File D:\maven-qcr-plugin-testsunitaires\qcr4java\h2-1.3.170-sources\target\site\qc\lecode\expression\ExpressionColumn.java.html

1 /*
2 * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
3 * Version 1.0, and under the Eclipse Public License, Version 1.0
4 * (http://h2database.com/html/license.html).
5 * Initial Developer: H2 Group
6 */
7 package org.h2.expression;
8
9 import java.util.HashMap;
10 import org.h2.command.Parser;
11 import org.h2.command.dml.Select;
12 import org.h2.command.dml.SelectListColumnResolver;
13 import org.h2.constant.ErrorCode;
14 import org.h2.engine.Database;
15 import org.h2.engine.Session;
16 import org.h2.index.IndexCondition;
17 import org.h2.message.DbException;
18 import org.h2.schema.Constant;
19 import org.h2.schema.Schema;
20 import org.h2.table.Column;
21 import org.h2.table.ColumnResolver;
22 import org.h2.table.Table;
23 import org.h2.table.TableFilter;
24 import org.h2.value.Value;
25 import org.h2.value.ValueBoolean;
26
27 /**
28 * A expression that represents a column of a table or view.
29 */
30 public class ExpressionColumn extends Expression {
31
32 private final Database database;
33 private final String schemaName;
34 private final String tableAlias;
35 private final String columnName;
36 private ColumnResolver columnResolver;
37 private int queryLevel;
38 private Column column;
39 private boolean evaluatable;
40
41 public ExpressionColumn(Database database, Column column) {
42 this.database = database;
43 this.column = column;
44 this.schemaName = null;
45 this.tableAlias = null;
46 this.columnName = null;
47 }
48
49 public ExpressionColumn(Database database, String schemaName, String tableAlias, String columnName) {
50 this.database = database;
51 this.schemaName = schemaName;
52 this.tableAlias = tableAlias;
53 this.columnName = columnName;
54 }
55
56 public String getSQL() {
57 String sql;
58 boolean quote = database.getSettings().databaseToUpper;
59 if (column != null) {
60 sql = column.getSQL();
61 } else {
62 sql = quote ? Parser.quoteIdentifier(columnName) : columnName;
63 }
64 if (tableAlias != null) {
65 String a = quote ? Parser.quoteIdentifier(tableAlias) : tableAlias;
66 sql = a + "." + sql;
67 }
68 if (schemaName != null) {
69 String s = quote ? Parser.quoteIdentifier(schemaName) : schemaName;
70 sql = s + "." + sql;
71 }
72 return sql;
73 }
74
75 public TableFilter getTableFilter() {
76 return columnResolver == null ? null : columnResolver.getTableFilter();
77 }
78
79 public void mapColumns(ColumnResolver resolver, int level) {
80 if (tableAlias != null && !database.equalsIdentifiers(tableAlias, resolver.getTableAlias())) {
81 return;
82 }
83 if (schemaName != null && !database.equalsIdentifiers(schemaName, resolver.getSchemaName())) {
84 return;
85 }
86 for (Column col : resolver.getColumns()) {
87 String n = col.getName();
88 if (database.equalsIdentifiers(columnName, n)) {
89 mapColumn(resolver, col, level);
90 return;
91 }
92 }
93 if (database.equalsIdentifiers(Column.ROWID, columnName)) {
94 Column col = resolver.getRowIdColumn();
95 if (col != null) {
96 mapColumn(resolver, col, level);
97 return;
98 }
99 }
100 Column[] columns = resolver.getSystemColumns();
101 for (int i = 0; columns != null && i < columns.length; i++) {
102 Column col = columns[i];
103 if (database.equalsIdentifiers(columnName, col.getName())) {
104 mapColumn(resolver, col, level);
105 return;
106 }
107 }
108 }
109
110 private void mapColumn(ColumnResolver resolver, Column col, int level) {
111 if (this.columnResolver == null) {
112 queryLevel = level;
113 column = col;
114 this.columnResolver = resolver;
115 } else if (queryLevel == level && this.columnResolver != resolver) {
116 if (resolver instanceof SelectListColumnResolver) {
117 // ignore - already mapped, that's ok
118 } else {
119 throw DbException.get(ErrorCode.AMBIGUOUS_COLUMN_NAME_1, columnName);
120 }
121 }
122 }
123
124 public Expression optimize(Session session) {
125 if (columnResolver == null) {
126 Schema schema = session.getDatabase().findSchema(
127 tableAlias == null ? session.getCurrentSchemaName() : tableAlias);
128 if (schema != null) {
129 Constant constant = schema.findConstant(columnName);
130 if (constant != null) {
131 return constant.getValue();
132 }
133 }
134 String name = columnName;
135 if (tableAlias != null) {
136 name = tableAlias + "." + name;
137 if (schemaName != null) {
138 name = schemaName + "." + name;
139 }
140 }
141 throw DbException.get(ErrorCode.COLUMN_NOT_FOUND_1, name);
142 }
143 return columnResolver.optimize(this, column);
144 }
145
146 public void updateAggregate(Session session) {
147 Value now = columnResolver.getValue(column);
148 Select select = columnResolver.getSelect();
149 if (select == null) {
150 throw DbException.get(ErrorCode.MUST_GROUP_BY_COLUMN_1, getSQL());
151 }
152 HashMap<Expression, Object> values = select.getCurrentGroup();
153 if (values == null) {
154 // this is a different level (the enclosing query)
155 return;
156 }
157 Value v = (Value) values.get(this);
158 if (v == null) {
159 values.put(this, now);
160 } else {
161 if (!database.areEqual(now, v)) {
162 throw DbException.get(ErrorCode.MUST_GROUP_BY_COLUMN_1, getSQL());
163 }
164 }
165 }
166
167 public Value getValue(Session session) {
168 Select select = columnResolver.getSelect();
169 if (select != null) {
170 HashMap<Expression, Object> values = select.getCurrentGroup();
171 if (values != null) {
172 Value v = (Value) values.get(this);
173 if (v != null) {
174 return v;
175 }
176 }
177 }
178 Value value = columnResolver.getValue(column);
179 if (value == null) {
180 columnResolver.getValue(column);
181 throw DbException.get(ErrorCode.MUST_GROUP_BY_COLUMN_1, getSQL());
182 }
183 return value;
184 }
185
186 public int getType() {
187 return column.getType();
188 }
189
190 public void setEvaluatable(TableFilter tableFilter, boolean b) {
191 if (columnResolver != null && tableFilter == columnResolver.getTableFilter()) {
192 evaluatable = b;
193 }
194 }
195
196 public Column getColumn() {
197 return column;
198 }
199
200 public int getScale() {
201 return column.getScale();
202 }
203
204 public long getPrecision() {
205 return column.getPrecision();
206 }
207
208 public int getDisplaySize() {
209 return column.getDisplaySize();
210 }
211
212 public String getOriginalColumnName() {
213 return columnName;
214 }
215
216 public String getOriginalTableAliasName() {
217 return tableAlias;
218 }
219
220 public String getColumnName() {
221 return columnName != null ? columnName : column.getName();
222 }
223
224 public String getSchemaName() {
225 Table table = column.getTable();
226 return table == null ? null : table.getSchema().getName();
227 }
228
229 public String getTableName() {
230 Table table = column.getTable();
231 return table == null ? null : table.getName();
232 }
233
234 public String getAlias() {
235 return column == null ? null : column.getName();
236 }
237
238 public boolean isAutoIncrement() {
239 return column.getSequence() != null;
240 }
241
242 public int getNullable() {
243 return column.isNullable() ? Column.NULLABLE : Column.NOT_NULLABLE;
244 }
245
246 public boolean isEverything(ExpressionVisitor visitor) {
247 switch (visitor.getType()) {
248 case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL:
249 return false;
250 case ExpressionVisitor.READONLY:
251 case ExpressionVisitor.DETERMINISTIC:
252 case ExpressionVisitor.QUERY_COMPARABLE:
253 return true;
254 case ExpressionVisitor.INDEPENDENT:
255 return this.queryLevel < visitor.getQueryLevel();
256 case ExpressionVisitor.EVALUATABLE:
257 // if the current value is known (evaluatable set)
258 // or if this columns belongs to a 'higher level' query and is
259 // therefore just a parameter
260 if (database.getSettings().nestedJoins) {
261 if (visitor.getQueryLevel() < this.queryLevel) {
262 return true;
263 }
264 if (getTableFilter() == null) {
265 return false;
266 }
267 return getTableFilter().isEvaluatable();
268 }
269 return evaluatable || visitor.getQueryLevel() < this.queryLevel;
270 case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID:
271 visitor.addDataModificationId(column.getTable().getMaxDataModificationId());
272 return true;
273 case ExpressionVisitor.NOT_FROM_RESOLVER:
274 return columnResolver != visitor.getResolver();
275 case ExpressionVisitor.GET_DEPENDENCIES:
276 if (column != null) {
277 visitor.addDependency(column.getTable());
278 }
279 return true;
280 case ExpressionVisitor.GET_COLUMNS:
281 visitor.addColumn(column);
282 return true;
283 default:
284 throw DbException.throwInternalError("type=" + visitor.getType());
285 }
286 }
287
288 public int getCost() {
289 return 2;
290 }
291
292 public void createIndexConditions(Session session, TableFilter filter) {
293 TableFilter tf = getTableFilter();
294 if (filter == tf && column.getType() == Value.BOOLEAN) {
295 IndexCondition cond = IndexCondition.get(Comparison.EQUAL, this, ValueExpression
296 .get(ValueBoolean.get(true)));
297 filter.addIndexCondition(cond);
298 }
299 }
300
301 public Expression getNotIfPossible(Session session) {
302 return new Comparison(session, Comparison.EQUAL, this, ValueExpression.get(ValueBoolean.get(false)));
303 }
304
305 }
306