View Javadoc

1   /*
2    * Copyright (c) 2010.  The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  
21  package org.apache.expreval.expr.function;
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.node.GenericValue;
27  import org.apache.expreval.expr.node.NumberValue;
28  import org.apache.hadoop.hbase.client.Result;
29  import org.apache.hadoop.hbase.hbql.client.HBqlException;
30  import org.apache.hadoop.hbase.hbql.impl.AggregateValue;
31  import org.apache.hadoop.hbase.hbql.impl.HConnectionImpl;
32  
33  import java.util.List;
34  
35  public class NumberFunction extends GenericFunction implements NumberValue {
36  
37      public NumberFunction(final FunctionType functionType, final List<GenericValue> exprs) {
38          super(functionType, exprs);
39      }
40  
41      public void initAggregateValue(final AggregateValue aggregateValue) throws HBqlException {
42  
43          switch (this.getFunctionType()) {
44  
45              case COUNT: {
46                  aggregateValue.setValue(0L);
47                  break;
48              }
49  
50              case MIN:
51              case MAX: {
52                  break;
53              }
54  
55              default:
56                  throw new InternalErrorException("Invalid aggregate function: " + this.getFunctionType());
57          }
58      }
59  
60      public void applyResultToAggregateValue(final AggregateValue aggVal, final Result result) throws HBqlException,
61                                                                                                       ResultMissingColumnException,
62                                                                                                       NullColumnValueException {
63  
64          switch (this.getFunctionType()) {
65  
66              case COUNT: {
67                  final long currval = (Long)aggVal.getCurrentValue();
68                  aggVal.setValue(currval + 1);
69                  break;
70              }
71  
72              case MIN: {
73                  final Number v1 = (Number)this.getExprArg(0).getValue(null, result);
74  
75                  if (v1 instanceof Short) {
76                      final short val = v1.shortValue();
77                      aggVal.setValue(aggVal.isValueSet() ? Math.min(val, (Short)aggVal.getValue()) : val);
78                  }
79                  else if (v1 instanceof Integer) {
80                      final int val = v1.intValue();
81                      aggVal.setValue(aggVal.isValueSet() ? Math.min(val, (Integer)aggVal.getValue()) : val);
82                  }
83                  else if (v1 instanceof Long) {
84                      final long val = v1.longValue();
85                      aggVal.setValue(aggVal.isValueSet() ? Math.min(val, (Long)aggVal.getValue()) : val);
86                  }
87                  else if (v1 instanceof Float) {
88                      final float val = v1.floatValue();
89                      aggVal.setValue(aggVal.isValueSet() ? Math.min(val, (Float)aggVal.getValue()) : val);
90                  }
91                  else if (v1 instanceof Double) {
92                      final double val = v1.doubleValue();
93                      aggVal.setValue(aggVal.isValueSet() ? Math.min(val, (Double)aggVal.getValue()) : val);
94                  }
95                  break;
96              }
97  
98              case MAX: {
99                  final Number v1 = (Number)this.getExprArg(0).getValue(null, result);
100 
101                 if (v1 instanceof Short) {
102                     final short val = v1.shortValue();
103                     aggVal.setValue(aggVal.isValueSet() ? Math.max(val, (Short)aggVal.getValue()) : val);
104                 }
105                 else if (v1 instanceof Integer) {
106                     final int val = v1.intValue();
107                     aggVal.setValue(aggVal.isValueSet() ? Math.max(val, (Integer)aggVal.getValue()) : val);
108                 }
109                 else if (v1 instanceof Long) {
110                     final long val = v1.longValue();
111                     aggVal.setValue(aggVal.isValueSet() ? Math.max(val, (Long)aggVal.getValue()) : val);
112                 }
113                 else if (v1 instanceof Float) {
114                     final float val = v1.floatValue();
115                     aggVal.setValue(aggVal.isValueSet() ? Math.max(val, (Float)aggVal.getValue()) : val);
116                 }
117                 else if (v1 instanceof Double) {
118                     final double val = v1.doubleValue();
119                     aggVal.setValue(aggVal.isValueSet() ? Math.max(val, (Double)aggVal.getValue()) : val);
120                 }
121                 break;
122             }
123 
124             default:
125                 throw new InternalErrorException("Invalid aggregate function: " + this.getFunctionType());
126         }
127     }
128 
129     public Number getValue(final HConnectionImpl conn, final Object object) throws HBqlException,
130                                                                                    ResultMissingColumnException,
131                                                                                    NullColumnValueException {
132 
133         switch (this.getFunctionType()) {
134 
135             case LENGTH: {
136                 final String val = (String)this.getExprArg(0).getValue(conn, object);
137                 return val.length();
138             }
139 
140             case INDEXOF: {
141                 final String v1 = (String)this.getExprArg(0).getValue(conn, object);
142                 final String v2 = (String)this.getExprArg(1).getValue(conn, object);
143                 return v1.indexOf(v2);
144             }
145 
146             case DATETOLONG: {
147                 return (Long)this.getExprArg(0).getValue(conn, object);
148             }
149 
150             case SHORT: {
151                 final String v1 = (String)this.getExprArg(0).getValue(conn, object);
152                 return Short.valueOf(v1);
153             }
154 
155             case INTEGER: {
156                 final String v1 = (String)this.getExprArg(0).getValue(conn, object);
157                 return Integer.valueOf(v1);
158             }
159 
160             case LONG: {
161                 final String v1 = (String)this.getExprArg(0).getValue(conn, object);
162                 return Long.valueOf(v1);
163             }
164 
165             case FLOAT: {
166                 final String v1 = (String)this.getExprArg(0).getValue(conn, object);
167                 return Float.valueOf(v1);
168             }
169 
170             case DOUBLE: {
171                 final String v1 = (String)this.getExprArg(0).getValue(conn, object);
172                 return Double.valueOf(v1);
173             }
174 
175             case ABS: {
176                 final Number v1 = (Number)this.getExprArg(0).getValue(conn, object);
177 
178                 if (v1 instanceof Short)
179                     return Math.abs(v1.shortValue());
180                 else if (v1 instanceof Integer)
181                     return Math.abs(v1.intValue());
182                 else if (v1 instanceof Long)
183                     return Math.abs(v1.longValue());
184                 else if (v1 instanceof Float)
185                     return Math.abs(v1.floatValue());
186                 else if (v1 instanceof Double)
187                     return Math.abs(v1.doubleValue());
188             }
189 
190             case LESSER: {
191                 final Number v1 = (Number)this.getExprArg(0).getValue(conn, object);
192                 final Number v2 = (Number)this.getExprArg(1).getValue(conn, object);
193 
194                 if (v1 instanceof Short)
195                     return Math.min(v1.shortValue(), v2.shortValue());
196                 else if (v1 instanceof Integer)
197                     return Math.min(v1.intValue(), v2.intValue());
198                 else if (v1 instanceof Long)
199                     return Math.min(v1.longValue(), v2.longValue());
200                 else if (v1 instanceof Float)
201                     return Math.min(v1.floatValue(), v2.floatValue());
202                 else if (v1 instanceof Double)
203                     return Math.min(v1.doubleValue(), v2.doubleValue());
204             }
205 
206             case GREATER: {
207                 final Number v1 = (Number)this.getExprArg(0).getValue(conn, object);
208                 final Number v2 = (Number)this.getExprArg(1).getValue(conn, object);
209 
210                 if (v1 instanceof Short)
211                     return Math.max(v1.shortValue(), v2.shortValue());
212                 else if (v1 instanceof Integer)
213                     return Math.max(v1.intValue(), v2.intValue());
214                 else if (v1 instanceof Long)
215                     return Math.max(v1.longValue(), v2.longValue());
216                 else if (v1 instanceof Float)
217                     return Math.max(v1.floatValue(), v2.floatValue());
218                 else if (v1 instanceof Double)
219                     return Math.max(v1.doubleValue(), v2.doubleValue());
220             }
221 
222             case RANDOMINTEGER: {
223                 return GenericFunction.randomVal.nextInt();
224             }
225 
226             case RANDOMLONG: {
227                 return GenericFunction.randomVal.nextLong();
228             }
229 
230             case RANDOMFLOAT: {
231                 return GenericFunction.randomVal.nextFloat();
232             }
233 
234             case RANDOMDOUBLE: {
235                 return GenericFunction.randomVal.nextDouble();
236             }
237 
238             default:
239                 throw new InternalErrorException("Invalid function: " + this.getFunctionType());
240         }
241     }
242 }