KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > h2 > command > dml > Query


1 /*
2  * Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
3  * Initial Developer: H2 Group
4  */

5 package org.h2.command.dml;
6
7 import java.sql.SQLException JavaDoc;
8 import java.util.HashSet JavaDoc;
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 JavaDoc;
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 JavaDoc {
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 JavaDoc {
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 JavaDoc {
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 JavaDoc {
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                 // special case: SELECT 1 AS A FROM DUAL ORDER BY A
107
// (oracle supports it, but only in order by, not in group by and not in having):
108
// SELECT 1 AS A FROM DUAL ORDER BY -A
109
boolean isAlias = false;
110                 idx = expressions.size();
111                 if(e instanceof ExpressionColumn) {
112                     ExpressionColumn ecol = (ExpressionColumn)e;
113                     String JavaDoc alias = ecol.getOriginalAliasName();
114                     String JavaDoc 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 JavaDoc;
175     public abstract ObjectArray getExpressions();
176     public abstract double getCost();
177     public abstract HashSet JavaDoc 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 JavaDoc;
182     public abstract void setEvaluatable(TableFilter tableFilter, boolean b);
183     public abstract void addGlobalCondition(Expression expr, int columnId, int comparisonType) throws SQLException JavaDoc;
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