1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.expreval.expr.var;
22
23 import org.apache.expreval.client.InternalErrorException;
24 import org.apache.expreval.client.NullColumnValueException;
25 import org.apache.expreval.client.ResultMissingColumnException;
26 import org.apache.expreval.expr.MultipleExpressionContext;
27 import org.apache.expreval.expr.TypeSupport;
28 import org.apache.expreval.expr.literal.BooleanLiteral;
29 import org.apache.expreval.expr.literal.DateLiteral;
30 import org.apache.expreval.expr.literal.DoubleLiteral;
31 import org.apache.expreval.expr.literal.FloatLiteral;
32 import org.apache.expreval.expr.literal.IntegerLiteral;
33 import org.apache.expreval.expr.literal.LongLiteral;
34 import org.apache.expreval.expr.literal.NullLiteral;
35 import org.apache.expreval.expr.literal.ObjectLiteral;
36 import org.apache.expreval.expr.literal.ShortLiteral;
37 import org.apache.expreval.expr.literal.StringLiteral;
38 import org.apache.expreval.expr.node.GenericValue;
39 import org.apache.hadoop.hbase.client.Result;
40 import org.apache.hadoop.hbase.filter.Filter;
41 import org.apache.hadoop.hbase.hbql.client.HBqlException;
42 import org.apache.hadoop.hbase.hbql.impl.AggregateValue;
43 import org.apache.hadoop.hbase.hbql.impl.HConnectionImpl;
44 import org.apache.hadoop.hbase.hbql.impl.InvalidServerFilterException;
45 import org.apache.hadoop.hbase.hbql.impl.InvalidTypeException;
46 import org.apache.hadoop.hbase.hbql.util.Lists;
47
48 import java.io.Serializable;
49 import java.util.Collection;
50 import java.util.Comparator;
51 import java.util.Date;
52 import java.util.List;
53
54 public class NamedParameter implements GenericValue {
55
56 private static long counter = Long.MIN_VALUE;
57
58 private MultipleExpressionContext context = null;
59 private GenericValue typedExpr = null;
60 private List<GenericValue> typedExprList = null;
61
62 private String paramName;
63 private long position;
64
65 public NamedParameter() {
66 }
67
68 public NamedParameter(final String paramName) {
69 if (paramName.equals("?"))
70 this.paramName = "unnamed";
71 else
72 this.paramName = paramName;
73
74 this.position = getNextPosition();
75 }
76
77 private static synchronized long getNextPosition() {
78 return counter++;
79 }
80
81 public String toString() {
82 return this.getParamName();
83 }
84
85 public String getParamName() {
86 return this.paramName;
87 }
88
89 public long getPosition() {
90 return this.position;
91 }
92
93 private boolean isScalarValueSet() {
94 return this.getTypedExpr() != null;
95 }
96
97 private GenericValue getTypedExpr() {
98 return this.typedExpr;
99 }
100
101 private List<GenericValue> getTypedExprList() {
102 return this.typedExprList;
103 }
104
105 public GenericValue getOptimizedValue() throws HBqlException {
106 return this;
107 }
108
109 public boolean isAConstant() {
110 return false;
111 }
112
113 public boolean hasAColumnReference() {
114 return false;
115 }
116
117 public boolean isAColumnReference() {
118 return false;
119 }
120
121 public boolean isDefaultKeyword() {
122 return false;
123 }
124
125 public boolean isAnAggregateValue() {
126 return false;
127 }
128
129 public void setExpressionContext(final MultipleExpressionContext context) {
130 this.context = context;
131 this.getExpressionContext().addNamedParameter(this);
132 }
133
134 private MultipleExpressionContext getExpressionContext() {
135 return this.context;
136 }
137
138 public void initAggregateValue(final AggregateValue aggregateValue) throws HBqlException {
139 throw new InternalErrorException("Not applicable");
140 }
141
142 public void applyResultToAggregateValue(final AggregateValue aggregateValue, final Result result) throws HBqlException {
143 throw new InternalErrorException("Not applicable");
144 }
145
146 public void reset() {
147 this.typedExpr = null;
148 this.typedExprList = null;
149 }
150
151 public Class<? extends GenericValue> validateTypes(final GenericValue parentExpr,
152 final boolean allowCollections) throws HBqlException {
153
154 if (this.getTypedExpr() == null && this.getTypedExprList() == null)
155 throw new InvalidTypeException("Parameter \"" + this.getParamName() + "\" not assigned a value");
156
157 if (this.isScalarValueSet()) {
158 return this.getTypedExpr().getClass();
159 }
160 else {
161
162 if (!allowCollections) {
163 final String context = parentExpr == null ? "" : " in the context " + parentExpr.asString();
164 throw new InvalidTypeException("Parameter " + this.getParamName()
165 + " is assigned a collection which is not allowed" + context);
166 }
167
168
169 if (this.getTypedExprList().size() == 0)
170 throw new InvalidTypeException("Parameter " + this.getParamName() + " is assigned a collection with no values");
171
172
173 final GenericValue firstval = this.getTypedExprList().get(0);
174 final Class<? extends GenericValue> clazzToMatch = TypeSupport.getGenericExprType(firstval);
175
176 for (final GenericValue val : this.getTypedExprList()) {
177
178 final Class<? extends GenericValue> clazz = TypeSupport.getGenericExprType(val);
179
180 if (clazz == null)
181 throw new InvalidTypeException("Parameter " + this.getParamName()
182 + " assigned a collection value with invalid type "
183 + firstval.getClass().getSimpleName());
184
185 if (!clazz.equals(clazzToMatch))
186 throw new InvalidTypeException("Parameter " + this.getParamName()
187 + " assigned a collection value with type "
188 + firstval.getClass().getSimpleName()
189 + " which is inconsistent with the type of the first element");
190 }
191
192 return clazzToMatch;
193 }
194 }
195
196 public Object getValue(final HConnectionImpl conn, final Object object) throws HBqlException,
197 ResultMissingColumnException,
198 NullColumnValueException {
199 if (this.isScalarValueSet()) {
200 final GenericValue genericValue = this.getTypedExpr();
201 return genericValue.getValue(conn, object);
202 }
203 else
204 return this.getTypedExprList();
205 }
206
207 public void setParameter(final Object val) throws HBqlException {
208
209
210 this.reset();
211
212 if (val != null && TypeSupport.isACollection(val)) {
213 this.typedExprList = Lists.newArrayList();
214 for (final Object elem : (Collection)val)
215 this.getTypedExprList().add(this.getValueExpr((Serializable)elem));
216 }
217 else {
218 this.typedExpr = this.getValueExpr((Serializable)val);
219 }
220 }
221
222 private GenericValue getValueExpr(final Serializable val) throws InvalidTypeException {
223
224 if (val == null)
225 return new NullLiteral();
226
227 if (val instanceof Boolean)
228 return new BooleanLiteral((Boolean)val);
229
230 if (val instanceof Character)
231 return new ShortLiteral((short)((Character)val).charValue());
232
233 if (val instanceof Short)
234 return new ShortLiteral((Short)val);
235
236 if (val instanceof Integer)
237 return new IntegerLiteral((Integer)val);
238
239 if (val instanceof Long)
240 return new LongLiteral((Long)val);
241
242 if (val instanceof Float)
243 return new FloatLiteral((Float)val);
244
245 if (val instanceof Double)
246 return new DoubleLiteral((Double)val);
247
248 if (val instanceof String)
249 return new StringLiteral((String)val);
250
251 if (val instanceof Date)
252 return new DateLiteral((Date)val);
253
254 if (val instanceof Object)
255 return new ObjectLiteral(val);
256
257 throw new InvalidTypeException("Parameter " + this.getParamName()
258 + " assigned an unsupported type " + val.getClass().getSimpleName());
259 }
260
261 public String asString() {
262 return this.getParamName();
263 }
264
265 public static Comparator<? super NamedParameter> getComparator() {
266 return new NamedParameterComparator();
267 }
268
269 public static class NamedParameterComparator implements Comparator<NamedParameter>, Serializable {
270 public int compare(final NamedParameter param1, final NamedParameter param2) {
271 if (param1.getPosition() < param2.getPosition())
272 return -1;
273 else if (param1.getPosition() > param2.getPosition())
274 return +1;
275 else
276 return 0;
277 }
278 }
279
280 public Filter getFilter() throws HBqlException {
281 throw new InvalidServerFilterException();
282 }
283 }