KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > h2 > expression > ConditionIn


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.expression;
6
7 import java.sql.SQLException JavaDoc;
8
9 import org.h2.engine.Constants;
10 import org.h2.engine.Database;
11 import org.h2.engine.Session;
12 import org.h2.index.IndexCondition;
13 import org.h2.table.ColumnResolver;
14 import org.h2.table.TableFilter;
15 import org.h2.util.ObjectArray;
16 import org.h2.value.CompareMode;
17 import org.h2.value.Value;
18 import org.h2.value.ValueBoolean;
19 import org.h2.value.ValueNull;
20
21 /**
22  * @author Thomas
23  */

24
25 public class ConditionIn extends Condition {
26     private Database database;
27     private Expression left;
28     private ObjectArray values;
29     private Value min, max;
30     private int queryLevel;
31
32     public ConditionIn(Database database, Expression left, ObjectArray values) {
33         this.database = database;
34         this.left = left;
35         this.values = values;
36     }
37
38     public Value getValue(Session session) throws SQLException JavaDoc {
39         Value l = left.getValue(session);
40         if(l == ValueNull.INSTANCE) {
41             return l;
42         }
43         boolean result = false;
44         boolean hasNull = false;
45         for(int i=0; i<values.size(); i++) {
46             Expression e = (Expression) values.get(i);
47             Value r = e.getValue(session);
48             if(r == ValueNull.INSTANCE) {
49                 hasNull = true;
50             } else {
51                 result = Comparison.compareNotNull(database, l, r, Comparison.EQUAL);
52                 if(result) {
53                     break;
54                 }
55             }
56         }
57         if(!result && hasNull) {
58             return ValueNull.INSTANCE;
59         }
60         return ValueBoolean.get(result);
61     }
62
63     public void mapColumns(ColumnResolver resolver, int queryLevel) throws SQLException JavaDoc {
64         left.mapColumns(resolver, queryLevel);
65         for(int i=0; i<values.size(); i++) {
66             Expression e = (Expression) values.get(i);
67             e.mapColumns(resolver, queryLevel);
68         }
69         this.queryLevel = Math.max(queryLevel, this.queryLevel);
70     }
71
72     public Expression optimize(Session session) throws SQLException JavaDoc {
73         left = left.optimize(session);
74         boolean constant = left.isConstant();
75         if(constant && left == ValueExpression.NULL) {
76             return left;
77         }
78         boolean allValuesConstant = true;
79         for(int i=0; i<values.size(); i++) {
80             Expression e = (Expression) values.get(i);
81             e = e.optimize(session);
82             if(allValuesConstant && !e.isConstant()) {
83                 allValuesConstant = false;
84             }
85             values.set(i, e);
86         }
87         if(constant && allValuesConstant) {
88             return ValueExpression.get(getValue(session));
89         }
90         // TODO optimization: could use index in some cases (sort, use min and max)
91
if(values.size()==1) {
92             Expression right = (Expression) values.get(0);
93             Expression expr = new Comparison(session, Comparison.EQUAL, left, right);
94             expr = expr.optimize(session);
95             return expr;
96         }
97         if(Constants.OPTIMIZE_IN) {
98             ExpressionVisitor independent = ExpressionVisitor.get(ExpressionVisitor.INDEPENDENT);
99             independent.queryLevel = queryLevel;
100             if(areAllValues(independent)) {
101                 if(left instanceof ExpressionColumn) {
102                     CompareMode mode = session.getDatabase().getCompareMode();
103                     for(int i=0; i<values.size(); i++) {
104                         Expression e = (Expression) values.get(i);
105                         Value v = e.getValue(session);
106                         values.set(i, ValueExpression.get(v));
107                         if(min == null || min.compareTo(v, mode) > 0) {
108                             min = v;
109                         }
110                         if(max == null || max.compareTo(v, mode) < 0) {
111                             max = v;
112                         }
113                     }
114                 }
115             }
116         }
117         return this;
118     }
119     
120     public void createIndexConditions(TableFilter filter) {
121         if(!Constants.OPTIMIZE_IN) {
122             return;
123         }
124         if(min == null && max == null) {
125             return;
126         }
127         if(!(left instanceof ExpressionColumn)) {
128             return;
129         }
130         ExpressionColumn l = (ExpressionColumn)left;
131         if(filter != l.getTableFilter()) {
132             return;
133         }
134         filter.addIndexCondition(new IndexCondition(Comparison.BIGGER_EQUAL, l, ValueExpression.get(min)));
135         filter.addIndexCondition(new IndexCondition(Comparison.SMALLER_EQUAL, l, ValueExpression.get(max)));
136     }
137
138     public void setEvaluatable(TableFilter tableFilter, boolean b) {
139         left.setEvaluatable(tableFilter, b);
140         for(int i=0; i<values.size(); i++) {
141             Expression e = (Expression) values.get(i);
142             e.setEvaluatable(tableFilter, b);
143         }
144     }
145
146     public String JavaDoc getSQL() {
147         StringBuffer JavaDoc buff = new StringBuffer JavaDoc("(");
148         buff.append(left.getSQL());
149         buff.append(" IN(");
150         for(int i=0; i<values.size(); i++) {
151             if(i>0) {
152                 buff.append(", ");
153             }
154             Expression e = (Expression) values.get(i);
155             buff.append(e.getSQL());
156         }
157         buff.append("))");
158         return buff.toString();
159     }
160
161     public void updateAggregate(Session session) throws SQLException JavaDoc {
162         left.updateAggregate(session);
163         for(int i=0; i<values.size(); i++) {
164             Expression e = (Expression) values.get(i);
165             e.updateAggregate(session);
166         }
167     }
168
169     public boolean isEverything(ExpressionVisitor visitor) {
170         if(!left.isEverything(visitor)) {
171             return false;
172         }
173         return areAllValues(visitor);
174     }
175     
176     private boolean areAllValues(ExpressionVisitor visitor) {
177         for(int i=0; i<values.size(); i++) {
178             Expression e = (Expression) values.get(i);
179             if(!e.isEverything(visitor)) {
180                 return false;
181             }
182         }
183         return true;
184     }
185     
186     public int getCost() {
187         int cost = left.getCost();
188         for(int i=0; i<values.size(); i++) {
189             Expression e = (Expression) values.get(i);
190             cost += e.getCost();
191         }
192         return cost;
193     }
194
195 }
196
Popular Tags