KickJava   Java API By Example, From Geeks To Geeks.

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


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.Session;
11 import org.h2.message.Message;
12 import org.h2.table.ColumnResolver;
13 import org.h2.table.TableFilter;
14 import org.h2.value.Value;
15 import org.h2.value.ValueBoolean;
16 import org.h2.value.ValueNull;
17
18 /**
19  * @author Thomas
20  */

21 public class ConditionAndOr extends Condition {
22     // TODO optimization: we could extend (ID=1 AND ID=B) to (ID=1 AND ID=B AND B=1)
23
public static final int AND = 0, OR = 1;
24     private int andOrType;
25     private Expression left, right;
26
27     public ConditionAndOr(int andOrType, Expression left, Expression right) {
28         this.andOrType = andOrType;
29         this.left = left;
30         this.right = right;
31         if(Constants.CHECK && (left == null || right == null)) {
32             throw Message.getInternalError();
33         }
34     }
35
36     public String JavaDoc getSQL() {
37         String JavaDoc sql;
38         switch(andOrType) {
39         case AND:
40             sql = left.getSQL() + " AND " + right.getSQL();
41             break;
42         case OR:
43             sql = left.getSQL() + " OR " + right.getSQL();
44             break;
45         default:
46             throw Message.getInternalError("andOrType="+andOrType);
47         }
48         return "("+sql+")";
49     }
50
51     public void createIndexConditions(TableFilter filter) throws SQLException JavaDoc {
52         if (andOrType == AND) {
53             left.createIndexConditions(filter);
54             right.createIndexConditions(filter);
55         }
56     }
57     
58     public Value getValue(Session session) throws SQLException JavaDoc {
59         Value l = left.getValue(session);
60         Value r;
61         switch (andOrType) {
62         case AND: {
63             if (Boolean.FALSE.equals(l.getBoolean())) {
64                 return l;
65             }
66             r = right.getValue(session);
67             if (Boolean.FALSE.equals(r.getBoolean())) {
68                 return r;
69             }
70             if(l == ValueNull.INSTANCE) {
71                 return l;
72             }
73             if(r == ValueNull.INSTANCE) {
74                 return r;
75             }
76             return ValueBoolean.get(true);
77         }
78         case OR: {
79             if (Boolean.TRUE.equals(l.getBoolean())) {
80                 return l;
81             }
82             r = right.getValue(session);
83             if (Boolean.TRUE.equals(r.getBoolean())) {
84                 return r;
85             }
86             if(l == ValueNull.INSTANCE) {
87                 return l;
88             }
89             if(r == ValueNull.INSTANCE) {
90                 return r;
91             }
92             return ValueBoolean.get(false);
93         }
94         default:
95             throw Message.getInternalError("type=" + andOrType);
96         }
97     }
98
99     public Expression optimize(Session session) throws SQLException JavaDoc {
100         // TODO NULL values: see http://www-cs-students.stanford.edu/~wlam/compsci/sqlnulls
101
// TODO test if all optimizations are switched off against all on (including performance)
102
// TODO document NULL exactly for every case
103
left = left.optimize(session);
104         right = right.optimize(session);
105         int lc = left.getCost(), rc = right.getCost();
106         if(rc < lc) {
107             Expression t = left;
108             left = right;
109             right = t;
110         }
111         Value l = left.isConstant() ? left.getValue(session) : null;
112         Value r = right.isConstant() ? right.getValue(session) : null;
113         if(l==null && r==null) {
114             return this;
115         }
116         if(l != null && r != null) {
117             return ValueExpression.get(getValue(session));
118         }
119         switch (andOrType) {
120         case AND:
121             if(l != null) {
122                 if(Boolean.FALSE.equals(l.getBoolean())) {
123                     return ValueExpression.get(l);
124                 } else if(Boolean.TRUE.equals(l.getBoolean())) {
125                     return right;
126                 }
127             } else if(r != null) {
128                 if(Boolean.FALSE.equals(r.getBoolean())) {
129                     return ValueExpression.get(r);
130                 } else if(Boolean.TRUE.equals(r.getBoolean())) {
131                     return left;
132                 }
133             }
134             break;
135         case OR:
136             if(l != null) {
137                 if(Boolean.TRUE.equals(l.getBoolean())) {
138                     return ValueExpression.get(l);
139                 } else if(Boolean.FALSE.equals(l.getBoolean())) {
140                     return right;
141                 }
142             } else if(r != null) {
143                 if(Boolean.TRUE.equals(r.getBoolean())) {
144                     return ValueExpression.get(r);
145                 } else if(Boolean.FALSE.equals(r.getBoolean())) {
146                     return left;
147                 }
148             }
149             break;
150         default:
151             throw Message.getInternalError("type=" + andOrType);
152         }
153         return this;
154     }
155     
156     public void addFilterConditions(TableFilter filter, boolean outerJoin) {
157         if (andOrType == AND) {
158             left.addFilterConditions(filter, outerJoin);
159             right.addFilterConditions(filter, outerJoin);
160         } else {
161             super.addFilterConditions(filter, outerJoin);
162         }
163     }
164
165     public void mapColumns(ColumnResolver resolver, int level) throws SQLException JavaDoc {
166         left.mapColumns(resolver, level);
167         right.mapColumns(resolver, level);
168     }
169
170     public void setEvaluatable(TableFilter tableFilter, boolean b) {
171         left.setEvaluatable(tableFilter, b);
172         right.setEvaluatable(tableFilter, b);
173     }
174
175     public void updateAggregate(Session session) throws SQLException JavaDoc {
176         left.updateAggregate(session);
177         right.updateAggregate(session);
178     }
179     
180     public boolean isEverything(ExpressionVisitor visitor) {
181         return left.isEverything(visitor) && right.isEverything(visitor);
182     }
183     
184     public int getCost() {
185         return left.getCost() + right.getCost();
186     }
187
188 }
189
Popular Tags