File D:\maven-qcr-plugin-testsunitaires\qcr4java\h2-1.3.170-sources\target\site\qc\lecode\expression\ConditionInConstantSet.java.html

1 /*
2 * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
3 * Version 1.0, and under the Eclipse Public License, Version 1.0
4 * (http://h2database.com/html/license.html).
5 * Initial Developer: H2 Group
6 */
7 package org.h2.expression;
8
9 import java.util.ArrayList;
10 import java.util.HashSet;
11 import org.h2.engine.Session;
12 import org.h2.index.IndexCondition;
13 import org.h2.message.DbException;
14 import org.h2.table.ColumnResolver;
15 import org.h2.table.TableFilter;
16 import org.h2.util.StatementBuilder;
17 import org.h2.value.Value;
18 import org.h2.value.ValueBoolean;
19 import org.h2.value.ValueNull;
20
21 /**
22 * Used for optimised IN(...) queries where the contents of the IN list are all
23 * constant and of the same type.
24 * <p>
25 * Checking using a HashSet is has time complexity O(1), instead of O(n) for
26 * checking using an array.
27 */
28 public class ConditionInConstantSet extends Condition {
29
30 private Expression left;
31 private int queryLevel;
32 private final ArrayList<Expression> valueList;
33 private final HashSet<Value> valueSet;
34
35 /**
36 * Create a new IN(..) condition.
37 *
38 * @param session the session
39 * @param left the expression before IN
40 * @param valueList the value list (at least two elements)
41 */
42 public ConditionInConstantSet(Session session, Expression left, ArrayList<Expression> valueList) {
43 this.left = left;
44 this.valueList = valueList;
45 this.valueSet = new HashSet<Value>(valueList.size());
46 for (Expression expression : valueList) {
47 this.valueSet.add(expression.getValue(session));
48 }
49 }
50
51 public Value getValue(Session session) {
52 Value leftVal = left.getValue(session);
53 if (leftVal == ValueNull.INSTANCE) {
54 return leftVal;
55 }
56 boolean setHasNull = valueSet.contains(ValueNull.INSTANCE);
57 Value firstRightVal = valueSet.iterator().next();
58 leftVal = leftVal.convertTo(firstRightVal.getType());
59 boolean result = valueSet.contains(leftVal);
60
61 if (!result && setHasNull) {
62 return ValueNull.INSTANCE;
63 }
64 return ValueBoolean.get(result);
65 }
66
67 public void mapColumns(ColumnResolver resolver, int level) {
68 left.mapColumns(resolver, level);
69 this.queryLevel = Math.max(level, this.queryLevel);
70 }
71
72 public Expression optimize(Session session) {
73 left = left.optimize(session);
74 return this;
75 }
76
77 public void createIndexConditions(Session session, TableFilter filter) {
78 if (!(left instanceof ExpressionColumn)) {
79 return;
80 }
81 ExpressionColumn l = (ExpressionColumn) left;
82 if (filter != l.getTableFilter()) {
83 return;
84 }
85 if (session.getDatabase().getSettings().optimizeInList) {
86 filter.addIndexCondition(IndexCondition.getInList(l, valueList));
87 return;
88 }
89 }
90
91 public void setEvaluatable(TableFilter tableFilter, boolean b) {
92 left.setEvaluatable(tableFilter, b);
93 }
94
95 public String getSQL() {
96 StatementBuilder buff = new StatementBuilder("(");
97 buff.append(left.getSQL()).append(" IN(");
98 for (Expression e : valueList) {
99 buff.appendExceptFirst(", ");
100 buff.append(e.getSQL());
101 }
102 return buff.append("))").toString();
103 }
104
105 public void updateAggregate(Session session) {
106 // nothing to do
107 }
108
109 public boolean isEverything(ExpressionVisitor visitor) {
110 if (!left.isEverything(visitor)) {
111 return false;
112 }
113 switch (visitor.getType()) {
114 case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL:
115 case ExpressionVisitor.DETERMINISTIC:
116 case ExpressionVisitor.READONLY:
117 case ExpressionVisitor.INDEPENDENT:
118 case ExpressionVisitor.EVALUATABLE:
119 case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID:
120 case ExpressionVisitor.NOT_FROM_RESOLVER:
121 case ExpressionVisitor.GET_DEPENDENCIES:
122 case ExpressionVisitor.QUERY_COMPARABLE:
123 case ExpressionVisitor.GET_COLUMNS:
124 return true;
125 default:
126 throw DbException.throwInternalError("type=" + visitor.getType());
127 }
128 }
129
130 public int getCost() {
131 int cost = left.getCost();
132 return cost;
133 }
134
135 }
136