1 5 package org.h2.expression; 6 7 import java.sql.SQLException ; 8 import java.util.HashMap ; 9 10 import org.h2.command.Parser; 11 import org.h2.command.dml.Select; 12 import org.h2.engine.Database; 13 import org.h2.engine.Session; 14 import org.h2.message.Message; 15 import org.h2.schema.Constant; 16 import org.h2.schema.Schema; 17 import org.h2.table.Column; 18 import org.h2.table.ColumnResolver; 19 import org.h2.table.Table; 20 import org.h2.table.TableFilter; 21 import org.h2.value.Value; 22 23 26 public class ExpressionColumn extends Expression { 27 private Database database; 28 private String schemaName; 29 private String tableAlias; 30 private String columnName; 31 private ColumnResolver resolver; 32 private int queryLevel; 33 private Column column; 34 private boolean evaluatable; 35 private Select select; 36 37 public ExpressionColumn(Database database, Select select, Column column) { 38 this.database = database; 39 this.select = select; 40 this.column = column; 41 } 42 43 public ExpressionColumn(Database database, Select select, String schemaName, String tableAlias, String columnName) { 44 this.database = database; 45 this.select = select; 46 this.schemaName = schemaName; 47 this.tableAlias = tableAlias; 48 this.columnName = columnName; 49 } 50 51 public String getSQL() { 52 String sql; 53 if(column != null) { 54 sql = column.getSQL(); 55 } else { 56 sql = columnName; 57 } 58 if(tableAlias != null) { 59 sql = Parser.quoteIdentifier(tableAlias) + "." + sql; 60 } 61 if(schemaName != null) { 62 sql = Parser.quoteIdentifier(schemaName) + "." + sql; 63 } 64 return sql; 65 } 66 67 public TableFilter getTableFilter() { 68 return resolver == null ? null : resolver.getTableFilter(); 69 } 70 71 public void mapColumns(ColumnResolver resolver, int level) throws SQLException { 72 if (tableAlias != null && !tableAlias.equals(resolver.getTableAlias())) { 73 return; 74 } 75 if(schemaName != null && !schemaName.equals(resolver.getSchemaName())) { 76 return; 77 } 78 Column[] columns = resolver.getColumns(); 79 for (int i = 0; i < columns.length; i++) { 80 Column col = columns[i]; 81 if (columnName.equals(col.getName())) { 82 if(this.resolver == null) { 83 queryLevel = level; 84 column = col; 85 this.resolver = resolver; 86 break; 87 } else if(queryLevel==level && this.resolver != resolver) { 88 throw Message.getSQLException(Message.AMBIGUOUS_COLUMN_NAME_1, columnName); 89 } 90 } 91 } 92 } 93 94 public Expression optimize(Session session) throws SQLException { 95 if (resolver == null) { 96 Schema schema = session.getDatabase().findSchema(tableAlias == null ? session.getCurrentSchemaName() : tableAlias); 97 if(schema != null) { 98 Constant constant = schema.findConstant(columnName); 99 if(constant != null) { 100 return constant.getValue(); 101 } 102 } 103 String name = columnName; 104 if (tableAlias != null) { 105 name = tableAlias + "." + name; 106 if(schemaName != null) { 107 name = schemaName + "." + name; 108 } 109 } 110 throw Message.getSQLException(Message.COLUMN_NOT_FOUND_1, name); 111 } 112 return this; 113 } 114 115 public void updateAggregate(Session session) throws SQLException { 116 Value now = resolver.getValue(column); 117 if(select == null) { 118 throw Message.getSQLException(Message.MUST_GROUP_BY_COLUMN_1, getSQL()); 119 } 120 HashMap values = select.getCurrentGroup(); 121 Value v = (Value)values.get(this); 122 if(v==null) { 123 values.put(this, now); 124 } else { 125 if(!database.areEqual(now, v)) { 126 throw Message.getSQLException(Message.MUST_GROUP_BY_COLUMN_1, getSQL()); 127 } 128 } 129 } 130 131 public Value getValue(Session session) throws SQLException { 132 if(select != null) { 135 HashMap values = select.getCurrentGroup(); 136 if(values != null) { 137 Value v = (Value)values.get(this); 138 if(v!=null) { 139 return v; 140 } 141 } 142 } 143 Value value = resolver.getValue(column); 144 if(value== null) { 145 throw Message.getSQLException(Message.MUST_GROUP_BY_COLUMN_1, getSQL()); 146 } 147 return value; 148 } 149 150 public int getType() { 151 return column.getType(); 152 } 153 154 public void setEvaluatable(TableFilter tableFilter, boolean b) { 155 if (tableFilter == resolver.getTableFilter()) { 156 evaluatable = b; 157 } 158 } 159 160 public Column getColumn() { 161 return column; 162 } 163 164 public int getScale() { 165 return column.getScale(); 166 } 167 168 public long getPrecision() { 169 return column.getPrecision(); 170 } 171 172 public String getOriginalColumnName() { 173 return columnName; 174 } 175 176 public String getOriginalAliasName() { 177 return tableAlias; 178 } 179 180 public String getColumnName() { 181 return columnName!=null ? columnName : column.getName(); 182 } 183 184 public String getSchemaName() { 185 Table table = column.getTable(); 186 return table == null ? null : table.getSchema().getName(); 187 } 188 189 public String getTableName() { 190 Table table = column.getTable(); 191 return table == null ? null : table.getName(); 192 } 193 194 public String getAlias() { 195 return column.getName(); 196 } 197 198 public boolean isAutoIncrement() { 199 return column.getSequence() != null; 200 } 201 202 public int getNullable() { 203 return column.getNullable() ? Column.NULLABLE : Column.NOT_NULLABLE; 204 } 205 206 public boolean isEverything(ExpressionVisitor visitor) { 207 switch(visitor.type) { 208 case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL: 209 return false; 210 case ExpressionVisitor.READONLY: 211 case ExpressionVisitor.DETERMINISTIC: 212 return true; 213 case ExpressionVisitor.INDEPENDENT: 214 return this.queryLevel < visitor.queryLevel; 215 case ExpressionVisitor.EVALUATABLE: 216 return evaluatable || visitor.queryLevel < this.queryLevel; 219 case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID: 220 visitor.addDataModificationId(column.getTable().getMaxDataModificationId()); 221 return true; 222 default: 223 throw Message.getInternalError("type="+visitor.type); 224 } 225 } 226 227 public int getCost() { 228 return 2; 229 } 230 231 } 232 | Popular Tags |