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 | */ |
6 | package org.h2.expression; |
7 | |
8 | import org.h2.engine.Session; |
9 | import org.h2.index.IndexCondition; |
10 | import org.h2.message.DbException; |
11 | import org.h2.table.ColumnResolver; |
12 | import org.h2.table.TableFilter; |
13 | import org.h2.value.Value; |
14 | import org.h2.value.ValueArray; |
15 | import org.h2.value.ValueBoolean; |
16 | import org.h2.value.ValueNull; |
17 | |
18 | /** |
19 | * An expression representing a constant value. |
20 | */ |
21 | public class ValueExpression extends Expression { |
22 | /** |
23 | * The expression represents ValueNull.INSTANCE. |
24 | */ |
25 | private static final Object NULL = new ValueExpression(ValueNull.INSTANCE); |
26 | |
27 | /** |
28 | * This special expression represents the default value. It is used for |
29 | * UPDATE statements of the form SET COLUMN = DEFAULT. The value is |
30 | * ValueNull.INSTANCE, but should never be accessed. |
31 | */ |
32 | private static final Object DEFAULT = new ValueExpression(ValueNull.INSTANCE); |
33 | |
34 | private final Value value; |
35 | |
36 | private ValueExpression(Value value) { |
37 | this.value = value; |
38 | } |
39 | |
40 | /** |
41 | * Get the NULL expression. |
42 | * |
43 | * @return the NULL expression |
44 | */ |
45 | public static ValueExpression getNull() { |
46 | return (ValueExpression) NULL; |
47 | } |
48 | |
49 | /** |
50 | * Get the DEFAULT expression. |
51 | * |
52 | * @return the DEFAULT expression |
53 | */ |
54 | public static ValueExpression getDefault() { |
55 | return (ValueExpression) DEFAULT; |
56 | } |
57 | |
58 | /** |
59 | * Create a new expression with the given value. |
60 | * |
61 | * @param value the value |
62 | * @return the expression |
63 | */ |
64 | public static ValueExpression get(Value value) { |
65 | if (value == ValueNull.INSTANCE) { |
66 | return getNull(); |
67 | } |
68 | return new ValueExpression(value); |
69 | } |
70 | |
71 | @Override |
72 | public Value getValue(Session session) { |
73 | return value; |
74 | } |
75 | |
76 | @Override |
77 | public int getType() { |
78 | return value.getType(); |
79 | } |
80 | |
81 | @Override |
82 | public void createIndexConditions(Session session, TableFilter filter) { |
83 | if (value.getType() == Value.BOOLEAN) { |
84 | boolean v = ((ValueBoolean) value).getBoolean().booleanValue(); |
85 | if (!v) { |
86 | filter.addIndexCondition(IndexCondition.get(Comparison.FALSE, null, this)); |
87 | } |
88 | } |
89 | } |
90 | |
91 | @Override |
92 | public Expression getNotIfPossible(Session session) { |
93 | return new Comparison(session, Comparison.EQUAL, this, |
94 | ValueExpression.get(ValueBoolean.get(false))); |
95 | } |
96 | |
97 | @Override |
98 | public void mapColumns(ColumnResolver resolver, int level) { |
99 | // nothing to do |
100 | } |
101 | |
102 | @Override |
103 | public Expression optimize(Session session) { |
104 | return this; |
105 | } |
106 | |
107 | @Override |
108 | public boolean isConstant() { |
109 | return true; |
110 | } |
111 | |
112 | @Override |
113 | public boolean isValueSet() { |
114 | return true; |
115 | } |
116 | |
117 | @Override |
118 | public void setEvaluatable(TableFilter tableFilter, boolean b) { |
119 | // nothing to do |
120 | } |
121 | |
122 | @Override |
123 | public int getScale() { |
124 | return value.getScale(); |
125 | } |
126 | |
127 | @Override |
128 | public long getPrecision() { |
129 | return value.getPrecision(); |
130 | } |
131 | |
132 | @Override |
133 | public int getDisplaySize() { |
134 | return value.getDisplaySize(); |
135 | } |
136 | |
137 | @Override |
138 | public String getSQL() { |
139 | if (this == DEFAULT) { |
140 | return "DEFAULT"; |
141 | } |
142 | return value.getSQL(); |
143 | } |
144 | |
145 | @Override |
146 | public void updateAggregate(Session session) { |
147 | // nothing to do |
148 | } |
149 | |
150 | @Override |
151 | public boolean isEverything(ExpressionVisitor visitor) { |
152 | switch (visitor.getType()) { |
153 | case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL: |
154 | case ExpressionVisitor.DETERMINISTIC: |
155 | case ExpressionVisitor.READONLY: |
156 | case ExpressionVisitor.INDEPENDENT: |
157 | case ExpressionVisitor.EVALUATABLE: |
158 | case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID: |
159 | case ExpressionVisitor.NOT_FROM_RESOLVER: |
160 | case ExpressionVisitor.GET_DEPENDENCIES: |
161 | case ExpressionVisitor.QUERY_COMPARABLE: |
162 | case ExpressionVisitor.GET_COLUMNS: |
163 | return true; |
164 | default: |
165 | throw DbException.throwInternalError("type=" + visitor.getType()); |
166 | } |
167 | } |
168 | |
169 | @Override |
170 | public int getCost() { |
171 | return 0; |
172 | } |
173 | |
174 | @Override |
175 | public Expression[] getExpressionColumns(Session session) { |
176 | if (getType() == Value.ARRAY) { |
177 | return getExpressionColumns(session, (ValueArray) getValue(session)); |
178 | } |
179 | return super.getExpressionColumns(session); |
180 | } |
181 | } |