1 5 package org.h2.command.dml; 6 7 import java.sql.SQLException ; 8 import java.util.HashSet ; 9 10 import org.h2.command.Prepared; 11 import org.h2.engine.Session; 12 import org.h2.expression.Alias; 13 import org.h2.expression.Expression; 14 import org.h2.expression.ExpressionColumn; 15 import org.h2.expression.ExpressionVisitor; 16 import org.h2.expression.Parameter; 17 import org.h2.message.Message; 18 import org.h2.result.LocalResult; 19 import org.h2.result.SortOrder; 20 import org.h2.table.ColumnResolver; 21 import org.h2.table.TableFilter; 22 import org.h2.util.ObjectArray; 23 import org.h2.value.Value; 24 25 public abstract class Query extends Prepared { 26 27 protected Expression limit, offset; 28 protected int sampleSize; 29 30 private int lastLimit; 31 private long lastEvaluated; 32 private LocalResult lastResult; 33 private Value[] lastParameters; 34 35 abstract LocalResult queryWithoutCache(int limit) throws SQLException ; 36 37 public Query(Session session) { 38 super(session); 39 } 40 41 public boolean isQuery() { 42 return true; 43 } 44 45 public boolean isTransactional() { 46 return true; 47 } 48 49 public final boolean sameResultAsLast(Session session, Value[] params, Value[] lastParams, long lastEvaluated) throws SQLException { 50 for(int i=0; i<params.length; i++) { 51 if(!session.getDatabase().areEqual(lastParams[i], params[i])) { 52 return false; 53 } 54 } 55 if(!isEverything(ExpressionVisitor.DETERMINISTIC) || !isEverything(ExpressionVisitor.INDEPENDENT)) { 56 return false; 57 } 58 if(getMaxDataModificationId() > lastEvaluated) { 59 return false; 60 } 61 return true; 62 } 63 64 public final Value[] getParameterValues() throws SQLException { 65 ObjectArray list = getParameters(); 66 if(list == null) { 67 list = new ObjectArray(); 68 } 69 Value[] params = new Value[list.size()]; 70 for(int i=0; i<list.size(); i++) { 71 Value v = ((Parameter) list.get(i)).getParamValue(); 72 params[i] = v; 73 } 74 return params; 75 } 76 77 public final LocalResult query(int limit) throws SQLException { 78 if(!session.getDatabase().getOptimizeReuseResults()) { 79 return queryWithoutCache(limit); 80 } 81 Value[] params = getParameterValues(); 82 long now = session.getDatabase().getModificationDataId(); 83 if(lastResult != null && limit == lastLimit) { 84 if(sameResultAsLast(session, params, lastParameters, lastEvaluated)) { 85 lastResult = lastResult.createShallowCopy(session); 86 lastResult.reset(); 87 return lastResult; 88 } 89 } 90 lastParameters = params; 91 lastResult = queryWithoutCache(limit); 92 this.lastEvaluated = now; 93 lastLimit = limit; 94 return lastResult; 95 } 96 97 protected SortOrder initOrder(ObjectArray expressions, ObjectArray orderList, int visible, boolean mustBeInResult) throws SQLException { 98 int[] index = new int[orderList.size()]; 99 int[] sortType = new int[orderList.size()]; 100 int originalLength = expressions.size(); 101 for(int i=0; i<orderList.size(); i++) { 102 SelectOrderBy o = (SelectOrderBy) orderList.get(i); 103 int idx; 104 if(o.expression != null) { 105 Expression e = o.expression; 106 boolean isAlias = false; 110 idx = expressions.size(); 111 if(e instanceof ExpressionColumn) { 112 ExpressionColumn ecol = (ExpressionColumn)e; 113 String alias = ecol.getOriginalAliasName(); 114 String col = ecol.getOriginalColumnName(); 115 for(int j=0; j<visible; j++) { 116 boolean found = false; 117 Expression ec = (Expression) expressions.get(j); 118 if(ec instanceof ExpressionColumn) { 119 ExpressionColumn c = (ExpressionColumn) ec; 120 found = col.equals(c.getColumnName()); 121 if(alias != null && found) { 122 found = alias.equals(c.getOriginalAliasName()); 123 } 124 } else if(!(ec instanceof Alias)) { 125 continue; 126 } else if(col.equals(ec.getAlias())) { 127 found = true; 128 } else { 129 Expression ec2 = ec.getNonAliasExpression(); 130 if(ec2 instanceof ExpressionColumn) { 131 ExpressionColumn c2 = (ExpressionColumn) ec2; 132 found = col.equals(c2.getColumnName()); 133 } 134 } 135 if(found) { 136 idx = j; 137 isAlias = true; 138 break; 139 } 140 } 141 } 142 if(!isAlias) { 143 if(mustBeInResult) { 144 throw Message.getSQLException(Message.ORDER_BY_NOT_IN_RESULT, e.getSQL()); 145 } 146 expressions.add(e); 147 } 148 } else { 149 idx = o.column; 150 if(idx >= originalLength) { 151 throw Message.getSQLException(Message.ORDER_BY_NOT_IN_RESULT, "index " + idx); 152 } 153 } 154 index[i] = idx; 155 int type = o.descending ? SortOrder.DESCENDING : SortOrder.ASCENDING; 156 if(o.nullsFirst) { 157 type += SortOrder.NULLS_FIRST; 158 } else if(o.nullsLast) { 159 type += SortOrder.NULLS_LAST; 160 } 161 sortType[i] = type; 162 } 163 return new SortOrder(session.getDatabase(), index, sortType); 164 } 165 166 public void setOffset(Expression offset) { 167 this.offset = offset; 168 } 169 170 public void setLimit(Expression limit) { 171 this.limit = limit; 172 } 173 174 public abstract void init() throws SQLException ; 175 public abstract ObjectArray getExpressions(); 176 public abstract double getCost(); 177 public abstract HashSet getTables(); 178 public abstract void setOrder(ObjectArray order); 179 public abstract void setForUpdate(boolean forUpdate); 180 public abstract int getColumnCount(); 181 public abstract void mapColumns(ColumnResolver resolver, int level) throws SQLException ; 182 public abstract void setEvaluatable(TableFilter tableFilter, boolean b); 183 public abstract void addGlobalCondition(Expression expr, int columnId, int comparisonType) throws SQLException ; 184 public abstract void setDistinct(boolean b); 185 186 public void setSampleSize(int sampleSize) { 187 this.sampleSize = sampleSize; 188 } 189 190 public final long getMaxDataModificationId() { 191 ExpressionVisitor visitor = ExpressionVisitor.get(ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID); 192 isEverything(visitor); 193 return visitor.getMaxDataModificationId(); 194 } 195 196 public abstract boolean isEverything(ExpressionVisitor visitor); 197 198 public final boolean isEverything(int expressionVisitorType) { 199 ExpressionVisitor visitor = ExpressionVisitor.get(expressionVisitorType); 200 return isEverything(visitor); 201 } 202 203 } 204 | Popular Tags |