EMMA Coverage Report (generated Sun Mar 01 22:06:14 CET 2015)
[all classes][org.h2.expression]

COVERAGE SUMMARY FOR SOURCE FILE [ConditionInConstantSet.java]

nameclass, %method, %block, %line, %
ConditionInConstantSet.java100% (2/2)79%  (11/14)88%  (211/240)86%  (50/58)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ConditionInConstantSet100% (1/1)75%  (9/12)87%  (195/224)86%  (49/57)
isDisjunctive (): boolean 0%   (0/1)0%   (0/2)0%   (0/1)
mapColumns (ColumnResolver, int): void 0%   (0/1)0%   (0/12)0%   (0/3)
updateAggregate (Session): void 0%   (0/1)0%   (0/1)0%   (0/1)
isEverything (ExpressionVisitor): boolean 100% (1/1)43%  (10/23)60%  (3/5)
createIndexConditions (Session, TableFilter): void 100% (1/1)96%  (26/27)89%  (8/9)
ConditionInConstantSet (Session, Expression, ArrayList): void 100% (1/1)100% (42/42)100% (9/9)
getAdditional (Session, Comparison): Expression 100% (1/1)100% (30/30)100% (7/7)
getCost (): int 100% (1/1)100% (6/6)100% (2/2)
getSQL (): String 100% (1/1)100% (38/38)100% (7/7)
getValue (Session): Value 100% (1/1)100% (29/29)100% (9/9)
optimize (Session): Expression 100% (1/1)100% (8/8)100% (2/2)
setEvaluatable (TableFilter, boolean): void 100% (1/1)100% (6/6)100% (2/2)
     
class ConditionInConstantSet$1100% (1/1)100% (2/2)100% (16/16)100% (2/2)
ConditionInConstantSet$1 (ConditionInConstantSet, Session): void 100% (1/1)100% (9/9)100% (1/1)
compare (Value, Value): int 100% (1/1)100% (7/7)100% (1/1)

1/*
2 * Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0,
3 * and the EPL 1.0 (http://h2database.com/html/license.html).
4 * Initial Developer: H2 Group
5 */
6package org.h2.expression;
7 
8import java.util.ArrayList;
9import java.util.Comparator;
10import java.util.TreeSet;
11import org.h2.engine.Session;
12import org.h2.index.IndexCondition;
13import org.h2.message.DbException;
14import org.h2.table.ColumnResolver;
15import org.h2.table.TableFilter;
16import org.h2.util.StatementBuilder;
17import org.h2.value.Value;
18import org.h2.value.ValueBoolean;
19import 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 */
28public class ConditionInConstantSet extends Condition {
29 
30    private Expression left;
31    private int queryLevel;
32    private final ArrayList<Expression> valueList;
33    private final TreeSet<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(final Session session, Expression left,
43            ArrayList<Expression> valueList) {
44        this.left = left;
45        this.valueList = valueList;
46        this.valueSet = new TreeSet<Value>(new Comparator<Value>() {
47            @Override
48            public int compare(Value o1, Value o2) {
49                return session.getDatabase().compare(o1, o2);
50            }
51        });
52        int type = left.getType();
53        for (Expression expression : valueList) {
54            valueSet.add(expression.getValue(session).convertTo(type));
55        }
56    }
57 
58    @Override
59    public Value getValue(Session session) {
60        Value x = left.getValue(session);
61        if (x == ValueNull.INSTANCE) {
62            return x;
63        }
64        boolean result = valueSet.contains(x);
65        if (!result) {
66            boolean setHasNull = valueSet.contains(ValueNull.INSTANCE);
67            if (setHasNull) {
68                return ValueNull.INSTANCE;
69            }
70        }
71        return ValueBoolean.get(result);
72    }
73 
74    @Override
75    public void mapColumns(ColumnResolver resolver, int level) {
76        left.mapColumns(resolver, level);
77        this.queryLevel = Math.max(level, this.queryLevel);
78    }
79 
80    @Override
81    public Expression optimize(Session session) {
82        left = left.optimize(session);
83        return this;
84    }
85 
86    @Override
87    public void createIndexConditions(Session session, TableFilter filter) {
88        if (!(left instanceof ExpressionColumn)) {
89            return;
90        }
91        ExpressionColumn l = (ExpressionColumn) left;
92        if (filter != l.getTableFilter()) {
93            return;
94        }
95        if (session.getDatabase().getSettings().optimizeInList) {
96            filter.addIndexCondition(IndexCondition.getInList(l, valueList));
97            return;
98        }
99    }
100 
101    @Override
102    public void setEvaluatable(TableFilter tableFilter, boolean b) {
103        left.setEvaluatable(tableFilter, b);
104    }
105 
106    @Override
107    public String getSQL() {
108        StatementBuilder buff = new StatementBuilder("(");
109        buff.append(left.getSQL()).append(" IN(");
110        for (Expression e : valueList) {
111            buff.appendExceptFirst(", ");
112            buff.append(e.getSQL());
113        }
114        return buff.append("))").toString();
115    }
116 
117    @Override
118    public void updateAggregate(Session session) {
119        // nothing to do
120    }
121 
122    @Override
123    public boolean isEverything(ExpressionVisitor visitor) {
124        if (!left.isEverything(visitor)) {
125            return false;
126        }
127        switch (visitor.getType()) {
128        case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL:
129        case ExpressionVisitor.DETERMINISTIC:
130        case ExpressionVisitor.READONLY:
131        case ExpressionVisitor.INDEPENDENT:
132        case ExpressionVisitor.EVALUATABLE:
133        case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID:
134        case ExpressionVisitor.NOT_FROM_RESOLVER:
135        case ExpressionVisitor.GET_DEPENDENCIES:
136        case ExpressionVisitor.QUERY_COMPARABLE:
137        case ExpressionVisitor.GET_COLUMNS:
138            return true;
139        default:
140            throw DbException.throwInternalError("type=" + visitor.getType());
141        }
142    }
143 
144    @Override
145    public int getCost() {
146        int cost = left.getCost();
147        return cost;
148    }
149 
150    @Override
151    public boolean isDisjunctive() {
152        return true;
153    }
154 
155    /**
156     * Add an additional element if possible. Example: given two conditions
157     * A IN(1, 2) OR A=3, the constant 3 is added: A IN(1, 2, 3).
158     *
159     * @param session the session
160     * @param other the second condition
161     * @return null if the condition was not added, or the new condition
162     */
163    Expression getAdditional(Session session, Comparison other) {
164        Expression add = other.getIfEquals(left);
165        if (add != null) {
166            if (add.isConstant()) {
167                valueList.add(add);
168                valueSet.add(add.getValue(session).convertTo(left.getType()));
169                return this;
170            }
171        }
172        return null;
173    }
174}

[all classes][org.h2.expression]
EMMA 2.0.5312 (C) Vladimir Roubtsov