KickJava   Java API By Example, From Geeks To Geeks.

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


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.command.dml.Query;
10 import org.h2.engine.Database;
11 import org.h2.engine.Session;
12 import org.h2.message.Message;
13 import org.h2.result.LocalResult;
14 import org.h2.table.ColumnResolver;
15 import org.h2.table.TableFilter;
16 import org.h2.value.Value;
17 import org.h2.value.ValueBoolean;
18 import org.h2.value.ValueNull;
19
20 /**
21  * @author Thomas
22  */

23 public class ConditionInSelect extends Condition {
24     private Database database;
25     private Expression left;
26     private Query query;
27     private boolean all;
28     private int compareType;
29     private int queryLevel;
30
31     public ConditionInSelect(Database database, Expression left, Query query, boolean all, int compareType) {
32         this.database = database;
33         this.left = left;
34         this.query = query;
35         this.all = all;
36         this.compareType = compareType;
37     }
38
39     public Value getValue(Session session) throws SQLException JavaDoc {
40         Value l = left.getValue(session);
41         if(l == ValueNull.INSTANCE) {
42             return l;
43         }
44         query.setSession(session);
45         LocalResult result = query.query(0);
46         try {
47             boolean valueAll = all;
48             while(result.next()) {
49                 boolean value;
50                 Value r = result.currentRow()[0];
51                 if(r == ValueNull.INSTANCE) {
52                     value = false;
53                 } else {
54                     value = Comparison.compareNotNull(database, l, r, compareType);
55                 }
56                 if(!value && all) {
57                     valueAll = false;
58                     break;
59                 } else if(value && !all) {
60                     valueAll = true;
61                     break;
62                 }
63             }
64             return ValueBoolean.get(valueAll);
65         } finally {
66             result.close();
67         }
68     }
69
70     public void mapColumns(ColumnResolver resolver, int queryLevel) throws SQLException JavaDoc {
71         left.mapColumns(resolver, queryLevel);
72         query.mapColumns(resolver, queryLevel+1);
73         this.queryLevel = Math.max(queryLevel, this.queryLevel);
74     }
75
76     public Expression optimize(Session session) throws SQLException JavaDoc {
77         left = left.optimize(session);
78         if(left == ValueExpression.NULL) {
79             return left;
80         }
81         if(query.getColumnCount() != 1) {
82             throw Message.getSQLException(Message.SUBQUERY_IS_NOT_SINGLE_COLUMN);
83         }
84         query.prepare();
85         // Can not optimize IN(SELECT...): the data may change
86
// However, could transform to an inner join
87
return this;
88     }
89
90     public void setEvaluatable(TableFilter tableFilter, boolean b) {
91         left.setEvaluatable(tableFilter, b);
92         query.setEvaluatable(tableFilter, b);
93     }
94
95     public String JavaDoc getSQL() {
96         StringBuffer JavaDoc buff = new StringBuffer JavaDoc("(");
97         buff.append(left.getSQL());
98         buff.append(" IN(");
99         buff.append(query.getPlan());
100         buff.append("))");
101         return buff.toString();
102     }
103
104     public void updateAggregate(Session session) {
105         // TODO exists: is it allowed that the subquery contains aggregates? probably not
106
// select id from test group by id having 1 in (select * from test2 where id=count(test.id))
107
}
108
109     public boolean isEverything(ExpressionVisitor visitor) {
110         return left.isEverything(visitor) && query.isEverything(visitor);
111     }
112     
113     public int getCost() {
114         return left.getCost() + 10 + (int)(10 * query.getCost());
115     }
116
117 }
118
Popular Tags