Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
test-udfs.cc
Go to the documentation of this file.
1 // Copyright 2012 Cloudera Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <udf/udf.h>
16 
17 using namespace impala_udf;
18 
19 // These functions are intended to test the "glue" that runs UDFs. Thus, the UDFs
20 // themselves are kept very simple.
21 
22 BooleanVal Identity(FunctionContext* context, const BooleanVal& arg) { return arg; }
23 
24 TinyIntVal Identity(FunctionContext* context, const TinyIntVal& arg) { return arg; }
25 
26 SmallIntVal Identity(FunctionContext* context, const SmallIntVal& arg) { return arg; }
27 
28 IntVal Identity(FunctionContext* context, const IntVal& arg) { return arg; }
29 
30 BigIntVal Identity(FunctionContext* context, const BigIntVal& arg) { return arg; }
31 
32 FloatVal Identity(FunctionContext* context, const FloatVal& arg) { return arg; }
33 
34 DoubleVal Identity(FunctionContext* context, const DoubleVal& arg) { return arg; }
35 
36 StringVal Identity(FunctionContext* context, const StringVal& arg) { return arg; }
37 
38 TimestampVal Identity(FunctionContext* context, const TimestampVal& arg) { return arg; }
39 
40 DecimalVal Identity(FunctionContext* context, const DecimalVal& arg) { return arg; }
41 
43  FunctionContext* context, const StringVal& string, const BooleanVal& boolean,
44  const TinyIntVal& tiny_int, const SmallIntVal& small_int, const IntVal& int_val,
45  const BigIntVal& big_int, const FloatVal& float_val, const DoubleVal& double_val,
46  const DecimalVal& decimal) {
47  int result = string.len + boolean.val + tiny_int.val + small_int.val + int_val.val
48  + big_int.val + static_cast<int64_t>(float_val.val)
49  + static_cast<int64_t>(double_val.val) + decimal.val4;
50  return IntVal(result);
51 }
52 
54  const char* result = "string";
55  StringVal ret(context, strlen(result));
56  // TODO: llvm 3.3 seems to have a bug if we use memcpy here making
57  // the IR udf crash. This is fixed in 3.3.1. Fix this when we upgrade.
58  //memcpy(ret.ptr, result, strlen(result));
59  // IMPALA-775
60  for (int i = 0; i < strlen(result); ++i) ret.ptr[i] = result[i];
61  return ret;
62 }
63 
64 BooleanVal VarAnd(FunctionContext* context, int n, const BooleanVal* args) {
65  bool result = true;
66  for (int i = 0; i < n; ++i) {
67  if (args[i].is_null) return BooleanVal(false);
68  result &= args[i].val;
69  }
70  return BooleanVal(result);
71 }
72 
73 IntVal VarSum(FunctionContext* context, int n, const IntVal* args) {
74  int result = 0;
75  bool is_null = true;
76  for (int i = 0; i < n; ++i) {
77  if (args[i].is_null) continue;
78  result += args[i].val;
79  is_null = false;
80  }
81  if (is_null) return IntVal::null();
82  return IntVal(result);
83 }
84 
85 DoubleVal VarSum(FunctionContext* context, int n, const DoubleVal* args) {
86  double result = 0;
87  bool is_null = true;
88  for (int i = 0; i < n; ++i) {
89  if (args[i].is_null) continue;
90  result += args[i].val;
91  is_null = false;
92  }
93  if (is_null) return DoubleVal::null();
94  return DoubleVal(result);
95 }
96 
97 // TODO: have this return a StringVal (make sure not to use functions defined in other
98 // compilation units, or change how this is built).
99 IntVal VarSum(FunctionContext* context, int n, const StringVal* args) {
100  int total_len = 0;
101  for (int i = 0; i < n; ++i) {
102  if (args[i].is_null) continue;
103  total_len += args[i].len;
104  }
105  return IntVal(total_len);
106 }
107 
108 // Decimal4Value... => Decimal8Value
109 DecimalVal VarSum(FunctionContext* context, int n, const DecimalVal* args) {
110  int64_t result = 0;
111  bool is_null = true;
112  for (int i = 0; i < n; ++i) {
113  const FunctionContext::TypeDesc* desc = context->GetArgType(i);
114  if (desc->type != FunctionContext::TYPE_DECIMAL || desc->precision > 9) {
115  context->SetError("VarSum() only accepts Decimal4Value (precison <= 9)");
116  return DecimalVal::null();
117  }
118  if (args[i].is_null) continue;
119  result += args[i].val4;
120  is_null = false;
121  }
122  if (is_null) return DecimalVal::null();
123  return DecimalVal(result);
124 }
125 
127  const DoubleVal& d, int n, const IntVal* args) {
128  if (d.is_null) return DoubleVal::null();
129 
130  int result = 0;
131  bool is_null = true;
132  for (int i = 0; i < n; ++i) {
133  if (args[i].is_null) continue;
134  result += args[i].val;
135  is_null = false;
136  }
137  if (is_null) return DoubleVal::null();
138  return DoubleVal(result * d.val);
139 }
140 
142  context->SetError("test UDF error");
143  context->SetError("this shouldn't show up");
144  return BooleanVal(false);
145 }
146 
148  context->AddWarning("test UDF warning 1");
149  context->AddWarning("test UDF warning 2");
150  return BooleanVal(false);
151 }
152 
153 // Dummy functions to test ddl.
155 IntVal Fn(FunctionContext*, const IntVal&) { return IntVal::null(); }
156 IntVal Fn(FunctionContext*, const IntVal&, const StringVal&) { return IntVal::null(); }
157 IntVal Fn(FunctionContext*, const StringVal&, const IntVal&) { return IntVal::null(); }
159 IntVal Fn2(FunctionContext*, const IntVal&, const StringVal&) { return IntVal::null(); }
160 
162  return TimestampVal(2456575, 1); // 2013-10-09 00:00:00.000000001
163 }
164 
166  if (context->GetArgType(0)->type != FunctionContext::TYPE_STRING) {
167  return BooleanVal(false);
168  }
169  if (context->GetArgType(-1) != NULL) return BooleanVal(false);
170  if (context->GetArgType(1) != NULL) return BooleanVal(false);
171  return BooleanVal(true);
172 }
173 
174 // Count UDF: counts the number of input rows per thread-local FunctionContext
176  if (scope == FunctionContext::THREAD_LOCAL) {
177  uint64_t* state = reinterpret_cast<uint64_t*>(context->Allocate(sizeof(uint64_t)));
178  *state = 0;
179  context->SetFunctionState(scope, state);
180  }
181 }
182 
184  uint64_t* state = reinterpret_cast<uint64_t*>(
186  return BigIntVal(++(*state));
187 }
188 
190  if (scope == FunctionContext::THREAD_LOCAL) {
191  void* state = context->GetFunctionState(scope);
192  context->Free(reinterpret_cast<uint8_t*>(state));
193  context->SetFunctionState(scope, NULL);
194  }
195 }
196 
197 // ConstantArg UDF: returns the first argument if it's constant, otherwise returns NULL.
200  if (scope == FunctionContext::THREAD_LOCAL) {
201  IntVal* state = reinterpret_cast<IntVal*>(context->Allocate(sizeof(IntVal)));
202  if (context->IsArgConstant(0)) {
203  *state = *reinterpret_cast<IntVal*>(context->GetConstantArg(0));
204  } else {
205  *state = IntVal::null();
206  }
207  context->SetFunctionState(scope, state);
208  }
209 }
210 
211 IntVal ConstantArg(FunctionContext* context, const IntVal& const_val) {
212  IntVal* state = reinterpret_cast<IntVal*>(
214  return *state;
215 }
216 
219  if (scope == FunctionContext::THREAD_LOCAL) {
220  void* state = context->GetFunctionState(scope);
221  context->Free(reinterpret_cast<uint8_t*>(state));
222  context->SetFunctionState(scope, NULL);
223  }
224 }
225 
226 // ValidateOpen UDF: returns true if the UDF was opened, false otherwise. Can also be
227 // used to validate close since it will leak if it's not closed.
230  if (scope == FunctionContext::THREAD_LOCAL) {
231  uint8_t* state = context->Allocate(100);
232  context->SetFunctionState(scope, state);
233  }
234 }
235 
237  void* state = context->GetFunctionState(FunctionContext::THREAD_LOCAL);
238  return BooleanVal(state != NULL);
239 }
240 
243  if (scope == FunctionContext::THREAD_LOCAL) {
244  void* state = context->GetFunctionState(scope);
245  context->Free(reinterpret_cast<uint8_t*>(state));
246  context->SetFunctionState(scope, NULL);
247  }
248 }
249 
250 // MemTest UDF: "Allocates" the specified number of bytes per call.
252  if (scope == FunctionContext::THREAD_LOCAL) {
253  int64_t* total =
254  reinterpret_cast<int64_t*>(context->Allocate(sizeof(int64_t)));
255  *total = 0;
256  context->SetFunctionState(scope, total);
257  }
258 }
259 
260 BigIntVal MemTest(FunctionContext* context, const BigIntVal& bytes) {
261  int64_t* total = reinterpret_cast<int64_t*>(
263  context->TrackAllocation(bytes.val);
264  *total += bytes.val;
265  return bytes;
266 }
267 
269  if (scope == FunctionContext::THREAD_LOCAL) {
270  int64_t* total = reinterpret_cast<int64_t*>(
272  context->Free(*total);
273  context->Free(reinterpret_cast<uint8_t*>(total));
274  context->SetFunctionState(scope, NULL);
275  }
276 }
277 
279  context->TrackAllocation(bytes.val);
280  context->Free(bytes.val);
281  context->Free(bytes.val);
282  return bytes;
283 }
284 
286  return BigIntVal(5);
287 }
288 
289 // Functions to test interpreted path
290 IntVal FourArgs(FunctionContext* context, const IntVal& v1, const IntVal& v2,
291  const IntVal& v3, const IntVal& v4) {
292  return IntVal(v1.val + v2.val + v3.val + v4.val);
293 }
294 
295 IntVal FiveArgs(FunctionContext* context, const IntVal& v1, const IntVal& v2,
296  const IntVal& v3, const IntVal& v4, const IntVal& v5) {
297  return IntVal(v1.val + v2.val + v3.val + v4.val + v5.val);
298 }
299 
300 IntVal SixArgs(FunctionContext* context, const IntVal& v1, const IntVal& v2,
301  const IntVal& v3, const IntVal& v4, const IntVal& v5, const IntVal& v6) {
302  return IntVal(v1.val + v2.val + v3.val + v4.val + v5.val + v6.val);
303 }
304 
305 IntVal SevenArgs(FunctionContext* context, const IntVal& v1, const IntVal& v2,
306  const IntVal& v3, const IntVal& v4, const IntVal& v5, const IntVal& v6,
307  const IntVal& v7) {
308  return IntVal(v1.val + v2.val + v3.val + v4.val + v5.val + v6.val + v7.val);
309 }
310 
311 IntVal EightArgs(FunctionContext* context, const IntVal& v1, const IntVal& v2,
312  const IntVal& v3, const IntVal& v4, const IntVal& v5, const IntVal& v6,
313  const IntVal& v7, const IntVal& v8) {
314  return IntVal(v1.val + v2.val + v3.val + v4.val + v5.val + v6.val + v7.val + v8.val);
315 }
BigIntVal MemTest(FunctionContext *context, const BigIntVal &bytes)
Definition: test-udfs.cc:260
int precision
Only valid if type == TYPE_DECIMAL.
Definition: udf.h:75
BigIntVal Count(FunctionContext *context)
Definition: test-udfs.cc:183
BooleanVal TestWarnings(FunctionContext *context)
Definition: test-udfs.cc:147
static IntVal null()
Definition: udf.h:425
TimestampVal ConstantTimestamp(FunctionContext *context)
Definition: test-udfs.cc:161
void MemTestPrepare(FunctionContext *context, FunctionContext::FunctionStateScope scope)
Definition: test-udfs.cc:251
BooleanVal Identity(FunctionContext *context, const BooleanVal &arg)
Definition: test-udfs.cc:22
int32_t val
Definition: udf.h:421
IntVal Fn2(FunctionContext *, const IntVal &)
Definition: test-udfs.cc:158
BooleanVal ValidateArgType(FunctionContext *context, const StringVal &dummy)
Definition: test-udfs.cc:165
This object has a compatible storage format with boost::ptime.
Definition: udf.h:495
uint8_t * ptr
Definition: udf.h:523
IntVal ConstantArg(FunctionContext *context, const IntVal &const_val)
Definition: test-udfs.cc:211
bool AddWarning(const char *warning_msg)
Definition: udf.cc:345
IntVal VarSum(FunctionContext *context, int n, const IntVal *args)
Definition: test-udfs.cc:73
bool is_null
Definition: udf.h:359
IntVal FiveArgs(FunctionContext *context, const IntVal &v1, const IntVal &v2, const IntVal &v3, const IntVal &v4, const IntVal &v5)
Definition: test-udfs.cc:295
const TypeDesc * GetArgType(int arg_idx) const
Definition: udf.cc:425
void * GetFunctionState(FunctionStateScope scope) const
Definition: udf-ir.cc:38
void Free(uint8_t *buffer)
Frees a buffer returned from Allocate() or Reallocate()
Definition: udf.cc:291
DoubleVal VarSumMultiply(FunctionContext *context, const DoubleVal &d, int n, const IntVal *args)
Definition: test-udfs.cc:126
IntVal AllTypes(FunctionContext *context, const StringVal &string, const BooleanVal &boolean, const TinyIntVal &tiny_int, const SmallIntVal &small_int, const IntVal &int_val, const BigIntVal &big_int, const FloatVal &float_val, const DoubleVal &double_val, const DecimalVal &decimal)
Definition: test-udfs.cc:42
IntVal SevenArgs(FunctionContext *context, const IntVal &v1, const IntVal &v2, const IntVal &v3, const IntVal &v4, const IntVal &v5, const IntVal &v6, const IntVal &v7)
Definition: test-udfs.cc:305
bool IsArgConstant(int arg_idx) const
Definition: udf-ir.cc:20
void SetFunctionState(FunctionStateScope scope, void *ptr)
Definition: udf.cc:370
void ConstantArgPrepare(FunctionContext *context, FunctionContext::FunctionStateScope scope)
Definition: test-udfs.cc:198
BooleanVal TestError(FunctionContext *context)
Definition: test-udfs.cc:141
static DecimalVal null()
Definition: udf.h:580
void CountPrepare(FunctionContext *context, FunctionContext::FunctionStateScope scope)
Definition: test-udfs.cc:175
void CountClose(FunctionContext *context, FunctionContext::FunctionStateScope scope)
Definition: test-udfs.cc:189
BigIntVal UnmangledSymbol(FunctionContext *context)
Definition: test-udfs.cc:285
IntVal EightArgs(FunctionContext *context, const IntVal &v1, const IntVal &v2, const IntVal &v3, const IntVal &v4, const IntVal &v5, const IntVal &v6, const IntVal &v7, const IntVal &v8)
Definition: test-udfs.cc:311
void ValidateOpenClose(FunctionContext *context, FunctionContext::FunctionStateScope scope)
Definition: test-udfs.cc:241
uint8_t * Allocate(int byte_size)
Definition: udf.cc:262
IntVal FourArgs(FunctionContext *context, const IntVal &v1, const IntVal &v2, const IntVal &v3, const IntVal &v4)
Definition: test-udfs.cc:290
void TrackAllocation(int64_t byte_size)
Definition: udf.cc:312
BooleanVal VarAnd(FunctionContext *context, int n, const BooleanVal *args)
Definition: test-udfs.cc:64
StringVal NoArgs(FunctionContext *context)
Definition: test-udfs.cc:53
void MemTestClose(FunctionContext *context, FunctionContext::FunctionStateScope scope)
Definition: test-udfs.cc:268
static DoubleVal null()
Definition: udf.h:480
void ValidateOpenPrepare(FunctionContext *context, FunctionContext::FunctionStateScope scope)
Definition: test-udfs.cc:228
void SetError(const char *error_msg)
Definition: udf.cc:332
BigIntVal DoubleFreeTest(FunctionContext *context, BigIntVal bytes)
Definition: test-udfs.cc:278
AnyVal * GetConstantArg(int arg_idx) const
Definition: udf-ir.cc:25
IntVal Fn(FunctionContext *)
Definition: test-udfs.cc:154
void ConstantArgClose(FunctionContext *context, FunctionContext::FunctionStateScope scope)
Definition: test-udfs.cc:217
IntVal SixArgs(FunctionContext *context, const IntVal &v1, const IntVal &v2, const IntVal &v3, const IntVal &v4, const IntVal &v5, const IntVal &v6)
Definition: test-udfs.cc:300
BooleanVal ValidateOpen(FunctionContext *context, const IntVal &dummy)
Definition: test-udfs.cc:236