Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
math-functions.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 "exprs/math-functions.h"
16 
17 #include <iomanip>
18 #include <sstream>
19 #include <math.h>
20 
21 #include "exprs/anyval-util.h"
22 #include "exprs/expr.h"
23 #include "exprs/operators.h"
24 #include "util/string-parser.h"
25 
26 #include "common/names.h"
27 
28 using boost::algorithm::is_any_of;
29 using boost::algorithm::join;
30 using boost::algorithm::split;
31 using boost::algorithm::to_lower;
32 using std::uppercase;
33 
34 namespace impala {
35 
36 const char* MathFunctions::ALPHANUMERIC_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
37 
39  return DoubleVal(M_PI);
40 }
41 
43  return DoubleVal(M_E);
44 }
45 
46 // Generates a UDF that always calls FN() on the input val and returns it.
47 #define ONE_ARG_MATH_FN(NAME, RET_TYPE, INPUT_TYPE, FN) \
48  RET_TYPE MathFunctions::NAME(FunctionContext* ctx, const INPUT_TYPE& v) { \
49  if (v.is_null) return RET_TYPE::null(); \
50  return RET_TYPE(FN(v.val)); \
51  }
52 
53 ONE_ARG_MATH_FN(Abs, BigIntVal, BigIntVal, llabs);
55 ONE_ARG_MATH_FN(Abs, FloatVal, FloatVal, fabs);
60 ONE_ARG_MATH_FN(Asin, DoubleVal, DoubleVal, asin);
62 ONE_ARG_MATH_FN(Acos, DoubleVal, DoubleVal, acos);
64 ONE_ARG_MATH_FN(Atan, DoubleVal, DoubleVal, atan);
65 ONE_ARG_MATH_FN(Sqrt, DoubleVal, DoubleVal, sqrt);
66 ONE_ARG_MATH_FN(Ceil, BigIntVal, DoubleVal, ceil);
67 ONE_ARG_MATH_FN(Floor, BigIntVal, DoubleVal, floor);
69 ONE_ARG_MATH_FN(Log10, DoubleVal, DoubleVal, log10);
71 
73  if (v.is_null) return FloatVal::null();
74  return FloatVal((v.val > 0) ? 1.0f : ((v.val < 0) ? -1.0f : 0.0f));
75 }
76 
78  if (v.is_null) return v;
79  return DoubleVal(v.val * M_PI / 180.0);
80 }
81 
83  if (v.is_null) return v;
84  return DoubleVal(v.val * 180.0 / M_PI);
85 }
86 
88  if (v.is_null) return BigIntVal::null();
89  return BigIntVal(static_cast<int64_t>(v.val + ((v.val < 0) ? -0.5 : 0.5)));
90 }
91 
93  const IntVal& scale) {
94  if (v.is_null || scale.is_null) return DoubleVal::null();
95  return DoubleVal(floor(v.val * pow(10.0, scale.val) + 0.5) / pow(10.0, scale.val));
96 }
97 
99  if (v.is_null) return DoubleVal::null();
100  return DoubleVal(log(v.val) / log(2.0));
101 }
102 
104  const DoubleVal& v) {
105  if (base.is_null || v.is_null) return DoubleVal::null();
106  return DoubleVal(log(v.val) / log(base.val));
107 }
108 
110  const DoubleVal& exp) {
111  if (base.is_null || exp.is_null) return DoubleVal::null();
112  return DoubleVal(pow(base.val, exp.val));
113 }
114 
117  if (scope == FunctionContext::THREAD_LOCAL) {
118  uint32_t* seed = reinterpret_cast<uint32_t*>(ctx->Allocate(sizeof(uint32_t)));
119  ctx->SetFunctionState(scope, seed);
120  if (ctx->GetNumArgs() == 1) {
121  // This is a call to RandSeed, initialize the seed
122  // TODO: should we support non-constant seed?
123  if (!ctx->IsArgConstant(0)) {
124  ctx->SetError("Seed argument to rand() must be constant");
125  return;
126  }
127  DCHECK_EQ(ctx->GetArgType(0)->type, FunctionContext::TYPE_BIGINT);
128  BigIntVal* seed_arg = static_cast<BigIntVal*>(ctx->GetConstantArg(0));
129  if (seed_arg->is_null) {
130  seed = NULL;
131  } else {
132  *seed = seed_arg->val;
133  }
134  } else {
135  // This is a call to Rand, initialize seed to 0
136  // TODO: can we change this behavior? This is stupid.
137  *seed = 0;
138  }
139  }
140 }
141 
143  uint32_t* seed =
144  reinterpret_cast<uint32_t*>(ctx->GetFunctionState(FunctionContext::THREAD_LOCAL));
145  DCHECK(seed != NULL);
146  *seed = rand_r(seed);
147  // Normalize to [0,1].
148  return DoubleVal(static_cast<double>(*seed) / RAND_MAX);
149 }
150 
152  if (seed.is_null) return DoubleVal::null();
153  return Rand(ctx);
154 }
155 
157  if (v.is_null) return StringVal::null();
158  // Cast to an unsigned integer because it is compiler dependent
159  // whether the sign bit will be shifted like a regular bit.
160  // (logical vs. arithmetic shift for signed numbers)
161  uint64_t n = static_cast<uint64_t>(v.val);
162  const size_t max_bits = sizeof(uint64_t) * 8;
163  char result[max_bits];
164  uint32_t index = max_bits;
165  do {
166  result[--index] = '0' + (n & 1);
167  } while (n >>= 1);
168  return AnyValUtil::FromBuffer(ctx, result + index, max_bits - index);
169 }
170 
172  if (v.is_null) return StringVal::null();
173  // TODO: this is probably unreasonably slow
174  stringstream ss;
175  ss << hex << uppercase << v.val;
176  return AnyValUtil::FromString(ctx, ss.str());
177 }
178 
180  if (s.is_null) return StringVal::null();
181  stringstream ss;
182  ss << hex << uppercase << setfill('0');
183  for (int i = 0; i < s.len; ++i) {
184  // setw is not sticky. stringstream only converts integral values,
185  // so a cast to int is required, but only convert the least significant byte to hex.
186  ss << setw(2) << (static_cast<int32_t>(s.ptr[i]) & 0xFF);
187  }
188  return AnyValUtil::FromString(ctx, ss.str());
189 }
190 
192  if (s.is_null) return StringVal::null();
193  // For uneven number of chars return empty string like Hive does.
194  if (s.len % 2 != 0) return StringVal();
195 
196  int result_len = s.len / 2;
197  char result[result_len];
198  int res_index = 0;
199  int s_index = 0;
200  while (s_index < s.len) {
201  char c = 0;
202  for (int j = 0; j < 2; ++j, ++s_index) {
203  switch(s.ptr[s_index]) {
204  case '0':
205  case '1':
206  case '2':
207  case '3':
208  case '4':
209  case '5':
210  case '6':
211  case '7':
212  case '8':
213  case '9':
214  c += (s.ptr[s_index] - '0') * ((j == 0) ? 16 : 1);
215  break;
216  case 'A':
217  case 'B':
218  case 'C':
219  case 'D':
220  case 'E':
221  case 'F':
222  // Map to decimal values [10, 15]
223  c += (s.ptr[s_index] - 'A' + 10) * ((j == 0) ? 16 : 1);
224  break;
225  case 'a':
226  case 'b':
227  case 'c':
228  case 'd':
229  case 'e':
230  case 'f':
231  // Map to decimal [10, 15]
232  c += (s.ptr[s_index] - 'a' + 10) * ((j == 0) ? 16 : 1);
233  break;
234  default:
235  // Character not in hex alphabet, return empty string.
236  return StringVal();
237  }
238  }
239  result[res_index] = c;
240  ++res_index;
241  }
242  return AnyValUtil::FromBuffer(ctx, result, result_len);
243 }
244 
246  const TinyIntVal& src_base, const TinyIntVal& dest_base) {
247  if (num.is_null || src_base.is_null || dest_base.is_null) return StringVal::null();
248  // As in MySQL and Hive, min base is 2 and max base is 36.
249  // (36 is max base representable by alphanumeric chars)
250  // If a negative target base is given, num should be interpreted in 2's complement.
251  if (abs(src_base.val) < MIN_BASE || abs(src_base.val) > MAX_BASE
252  || abs(dest_base.val) < MIN_BASE || abs(dest_base.val) > MAX_BASE) {
253  // Return NULL like Hive does.
254  return StringVal::null();
255  }
256 
257  // Invalid input.
258  if (src_base.val < 0 && num.val >= 0) return StringVal::null();
259  int64_t decimal_num = num.val;
260  if (src_base.val != 10) {
261  // Convert src_num representing a number in src_base but encoded in decimal
262  // into its actual decimal number.
263  if (!DecimalInBaseToDecimal(num.val, src_base.val, &decimal_num)) {
264  // Handle overflow, setting decimal_num appropriately.
265  HandleParseResult(dest_base.val, &decimal_num, StringParser::PARSE_OVERFLOW);
266  }
267  }
268  return DecimalToBase(ctx, decimal_num, dest_base.val);
269 }
270 
272  const TinyIntVal& src_base, const TinyIntVal& dest_base) {
273  if (num_str.is_null || src_base.is_null || dest_base.is_null) return StringVal::null();
274  // As in MySQL and Hive, min base is 2 and max base is 36.
275  // (36 is max base representable by alphanumeric chars)
276  // If a negative target base is given, num should be interpreted in 2's complement.
277  if (abs(src_base.val) < MIN_BASE || abs(src_base.val) > MAX_BASE
278  || abs(dest_base.val) < MIN_BASE || abs(dest_base.val) > MAX_BASE) {
279  // Return NULL like Hive does.
280  return StringVal::null();
281  }
282  // Convert digits in num_str in src_base to decimal.
283  StringParser::ParseResult parse_res;
284  int64_t decimal_num = StringParser::StringToInt<int64_t>(
285  reinterpret_cast<char*>(num_str.ptr), num_str.len, src_base.val, &parse_res);
286  if (src_base.val < 0 && decimal_num >= 0) {
287  // Invalid input.
288  return StringVal::null();
289  }
290  if (!HandleParseResult(dest_base.val, &decimal_num, parse_res)) {
291  // Return 0 for invalid input strings like Hive does.
292  return StringVal(reinterpret_cast<uint8_t*>(const_cast<char*>("0")), 1);
293  }
294  return DecimalToBase(ctx, decimal_num, dest_base.val);
295 }
296 
298  int8_t dest_base) {
299  // Max number of digits of any base (base 2 gives max digits), plus sign.
300  const size_t max_digits = sizeof(uint64_t) * 8 + 1;
301  char buf[max_digits];
302  int32_t result_len = 0;
303  int32_t buf_index = max_digits - 1;
304  uint64_t temp_num;
305  if (dest_base < 0) {
306  // Dest base is negative, treat src_num as signed.
307  temp_num = abs(src_num);
308  } else {
309  // Dest base is positive. We must interpret src_num in 2's complement.
310  // Convert to an unsigned int to properly deal with 2's complement conversion.
311  temp_num = static_cast<uint64_t>(src_num);
312  }
313  int abs_base = abs(dest_base);
314  do {
315  buf[buf_index] = ALPHANUMERIC_CHARS[temp_num % abs_base];
316  temp_num /= abs_base;
317  --buf_index;
318  ++result_len;
319  } while (temp_num > 0);
320  // Add optional sign.
321  if (src_num < 0 && dest_base < 0) {
322  buf[buf_index] = '-';
323  ++result_len;
324  }
325  return AnyValUtil::FromBuffer(ctx, buf + max_digits - result_len, result_len);
326 }
327 
328 bool MathFunctions::DecimalInBaseToDecimal(int64_t src_num, int8_t src_base,
329  int64_t* result) {
330  uint64_t temp_num = abs(src_num);
331  int32_t place = 1;
332  *result = 0;
333  do {
334  int32_t digit = temp_num % 10;
335  // Reset result if digit is not representable in src_base.
336  if (digit >= src_base) {
337  *result = 0;
338  place = 1;
339  } else {
340  *result += digit * place;
341  place *= src_base;
342  // Overflow.
343  if (UNLIKELY(*result < digit)) {
344  return false;
345  }
346  }
347  temp_num /= 10;
348  } while (temp_num > 0);
349  *result = (src_num < 0) ? -(*result) : *result;
350  return true;
351 }
352 
353 bool MathFunctions::HandleParseResult(int8_t dest_base, int64_t* num,
354  StringParser::ParseResult parse_res) {
355  // On overflow set special value depending on dest_base.
356  // This is consistent with Hive and MySQL's behavior.
357  if (parse_res == StringParser::PARSE_OVERFLOW) {
358  if (dest_base < 0) {
359  *num = -1;
360  } else {
361  *num = numeric_limits<uint64_t>::max();
362  }
363  } else if (parse_res == StringParser::PARSE_FAILURE) {
364  // Some other error condition.
365  return false;
366  }
367  return true;
368 }
369 
371  const BigIntVal& b) {
372  if (a.is_null || b.is_null) return BigIntVal::null();
373  return BigIntVal(((a.val % b.val) + b.val) % b.val);
374 }
375 
377  const DoubleVal& b) {
378  if (a.is_null || b.is_null) return DoubleVal::null();
379  return DoubleVal(fmod(fmod(a.val, b.val) + b.val, b.val));
380 }
381 
383  const FloatVal& b) {
384  if (a.is_null || b.is_null || b.val == 0) return FloatVal::null();
385  return FloatVal(fmodf(a.val, b.val));
386 }
387 
389  const DoubleVal& b) {
390  if (a.is_null || b.is_null || b.val == 0) return DoubleVal::null();
391  return DoubleVal(fmod(a.val, b.val));
392 }
393 
394 template <typename T> T MathFunctions::Positive(FunctionContext* ctx, const T& val) {
395  return val;
396 }
397 
398 template <typename T> T MathFunctions::Negative(FunctionContext* ctx, const T& val) {
399  if (val.is_null) return val;
400  return T(-val.val);
401 }
402 
403 template <>
405  if (val.is_null) return val;
407  switch (type.GetByteSize()) {
408  case 4:
409  return DecimalVal(-val.val4);
410  case 8:
411  return DecimalVal(-val.val8);
412  case 16:
413  return DecimalVal(-val.val16);
414  default:
415  DCHECK(false);
416  return DecimalVal::null();
417  }
418 }
419 
421  const DoubleVal& y) {
422  if (x.is_null || y.is_null || static_cast<int64_t>(y.val) == 0) {
423  return BigIntVal::null();
424  }
425  return BigIntVal(static_cast<int64_t>(x.val) / static_cast<int64_t>(y.val));
426 }
427 
429  const BigIntVal& y) {
431 }
432 
433 template <typename VAL_TYPE, bool ISLEAST> VAL_TYPE MathFunctions::LeastGreatest(
434  FunctionContext* ctx, int num_args, const VAL_TYPE* args) {
435  DCHECK_GT(num_args, 0);
436  if (args[0].is_null) return VAL_TYPE::null();
437  int result_idx = 0;
438  for (int i = 1; i < num_args; ++i) {
439  if (args[i].is_null) return VAL_TYPE::null();
440  if (ISLEAST) {
441  if (args[i].val < args[result_idx].val) result_idx = i;
442  } else {
443  if (args[i].val > args[result_idx].val) result_idx = i;
444  }
445  }
446  return VAL_TYPE(args[result_idx].val);
447 }
448 
449 template <bool ISLEAST> StringVal MathFunctions::LeastGreatest(
450  FunctionContext* ctx, int num_args, const StringVal* args) {
451  DCHECK_GT(num_args, 0);
452  if (args[0].is_null) return StringVal::null();
453  StringValue result_val = StringValue::FromStringVal(args[0]);
454  for (int i = 1; i < num_args; ++i) {
455  if (args[i].is_null) return StringVal::null();
457  if (ISLEAST) {
458  if (val < result_val) result_val = val;
459  } else {
460  if (val > result_val) result_val = val;
461  }
462  }
463  StringVal result;
464  result_val.ToStringVal(&result);
465  return result;
466 }
467 
469  FunctionContext* ctx, int num_args, const TimestampVal* args) {
470  DCHECK_GT(num_args, 0);
471  if (args[0].is_null) return TimestampVal::null();
472  TimestampValue result_val = TimestampValue::FromTimestampVal(args[0]);
473  for (int i = 1; i < num_args; ++i) {
474  if (args[i].is_null) return TimestampVal::null();
476  if (ISLEAST) {
477  if (val < result_val) result_val = val;
478  } else {
479  if (val > result_val) result_val = val;
480  }
481  }
482  TimestampVal result;
483  result_val.ToTimestampVal(&result);
484  return result;
485 }
486 
487 template <bool ISLEAST> DecimalVal MathFunctions::LeastGreatest(
488  FunctionContext* ctx, int num_args, const DecimalVal* args) {
489  DCHECK_GT(num_args, 0);
490  if (args[0].is_null) return DecimalVal::null();
492  DecimalVal result_val = args[0];
493  for (int i = 1; i < num_args; ++i) {
494  if (args[i].is_null) return DecimalVal::null();
495  switch (type.GetByteSize()) {
496  case 4:
497  if (ISLEAST) {
498  if (args[i].val4 < result_val.val4) result_val = args[i];
499  } else {
500  if (args[i].val4 > result_val.val4) result_val = args[i];
501  }
502  break;
503  case 8:
504  if (ISLEAST) {
505  if (args[i].val8 < result_val.val8) result_val = args[i];
506  } else {
507  if (args[i].val8 > result_val.val8) result_val = args[i];
508  }
509  break;
510  case 16:
511  if (ISLEAST) {
512  if (args[i].val16 < result_val.val16) result_val = args[i];
513  } else {
514  if (args[i].val16 > result_val.val16) result_val = args[i];
515  }
516  break;
517  default:
518  DCHECK(false);
519  }
520  }
521  return result_val;
522 }
523 
524 template TinyIntVal MathFunctions::Positive<TinyIntVal>(
525  FunctionContext* ctx, const TinyIntVal& val);
526 template SmallIntVal MathFunctions::Positive<SmallIntVal>(
527  FunctionContext* ctx, const SmallIntVal& val);
528 template IntVal MathFunctions::Positive<IntVal>(
529  FunctionContext* ctx, const IntVal& val);
530 template BigIntVal MathFunctions::Positive<BigIntVal>(
531  FunctionContext* ctx, const BigIntVal& val);
532 template FloatVal MathFunctions::Positive<FloatVal>(
533  FunctionContext* ctx, const FloatVal& val);
534 template DoubleVal MathFunctions::Positive<DoubleVal>(
535  FunctionContext* ctx, const DoubleVal& val);
536 template DecimalVal MathFunctions::Positive<DecimalVal>(
537  FunctionContext* ctx, const DecimalVal& val);
538 
539 template TinyIntVal MathFunctions::Negative<TinyIntVal>(
540  FunctionContext* ctx, const TinyIntVal& val);
541 template SmallIntVal MathFunctions::Negative<SmallIntVal>(
542  FunctionContext* ctx, const SmallIntVal& val);
543 template IntVal MathFunctions::Negative<IntVal>(
544  FunctionContext* ctx, const IntVal& val);
545 template BigIntVal MathFunctions::Negative<BigIntVal>(
546  FunctionContext* ctx, const BigIntVal& val);
547 template FloatVal MathFunctions::Negative<FloatVal>(
548  FunctionContext* ctx, const FloatVal& val);
549 template DoubleVal MathFunctions::Negative<DoubleVal>(
550  FunctionContext* ctx, const DoubleVal& val);
551 
552 template TinyIntVal MathFunctions::LeastGreatest<TinyIntVal, true>(
553  FunctionContext* ctx, int num_args, const TinyIntVal* args);
554 template SmallIntVal MathFunctions::LeastGreatest<SmallIntVal, true>(
555  FunctionContext* ctx, int num_args, const SmallIntVal* args);
556 template IntVal MathFunctions::LeastGreatest<IntVal, true>(
557  FunctionContext* ctx, int num_args, const IntVal* args);
558 template BigIntVal MathFunctions::LeastGreatest<BigIntVal, true>(
559  FunctionContext* ctx, int num_args, const BigIntVal* args);
560 template FloatVal MathFunctions::LeastGreatest<FloatVal, true>(
561  FunctionContext* ctx, int num_args, const FloatVal* args);
562 template DoubleVal MathFunctions::LeastGreatest<DoubleVal, true>(
563  FunctionContext* ctx, int num_args, const DoubleVal* args);
564 
565 template TinyIntVal MathFunctions::LeastGreatest<TinyIntVal, false>(
566  FunctionContext* ctx, int num_args, const TinyIntVal* args);
567 template SmallIntVal MathFunctions::LeastGreatest<SmallIntVal, false>(
568  FunctionContext* ctx, int num_args, const SmallIntVal* args);
569 template IntVal MathFunctions::LeastGreatest<IntVal, false>(
570  FunctionContext* ctx, int num_args, const IntVal* args);
571 template BigIntVal MathFunctions::LeastGreatest<BigIntVal, false>(
572  FunctionContext* ctx, int num_args, const BigIntVal* args);
573 template FloatVal MathFunctions::LeastGreatest<FloatVal, false>(
574  FunctionContext* ctx, int num_args, const FloatVal* args);
575 template DoubleVal MathFunctions::LeastGreatest<DoubleVal, false>(
576  FunctionContext* ctx, int num_args, const DoubleVal* args);
577 
578 template StringVal MathFunctions::LeastGreatest<true>(
579  FunctionContext* ctx, int num_args, const StringVal* args);
580 template StringVal MathFunctions::LeastGreatest<false>(
581  FunctionContext* ctx, int num_args, const StringVal* args);
582 
583 template TimestampVal MathFunctions::LeastGreatest<true>(
584  FunctionContext* ctx, int num_args, const TimestampVal* args);
585 template TimestampVal MathFunctions::LeastGreatest<false>(
586  FunctionContext* ctx, int num_args, const TimestampVal* args);
587 
588 template DecimalVal MathFunctions::LeastGreatest<true>(
589  FunctionContext* ctx, int num_args, const DecimalVal* args);
590 template DecimalVal MathFunctions::LeastGreatest<false>(
591  FunctionContext* ctx, int num_args, const DecimalVal* args);
592 
593 }
static BigIntVal Int_divide_BigIntVal_BigIntVal(FunctionContext *, const BigIntVal &, const BigIntVal &)
static DoubleVal RandSeed(FunctionContext *, const BigIntVal &seed)
static const int32_t MIN_BASE
static void RandPrepare(FunctionContext *, FunctionContext::FunctionStateScope)
Used for both Rand() and RandSeed()
const TypeDesc & GetReturnType() const
Definition: udf-ir.cc:34
static StringVal FromBuffer(FunctionContext *ctx, const char *ptr, int len)
Definition: anyval-util.h:195
int128_t abs(const int128_t &x)
static ColumnType TypeDescToColumnType(const FunctionContext::TypeDesc &type)
Definition: anyval-util.cc:101
__int128_t val16
Definition: udf.h:572
static StringVal HexInt(FunctionContext *, const BigIntVal &)
int32_t val
Definition: udf.h:421
static DoubleVal FmodDouble(FunctionContext *, const DoubleVal &, const DoubleVal &)
static StringVal ConvInt(FunctionContext *, const BigIntVal &n, const TinyIntVal &src_base, const TinyIntVal &dst_base)
static FloatVal FmodFloat(FunctionContext *, const FloatVal &, const FloatVal &)
static DoubleVal Log2(FunctionContext *, const DoubleVal &)
static const int32_t MAX_BASE
This object has a compatible storage format with boost::ptime.
Definition: udf.h:495
static bool HandleParseResult(int8_t dest_base, int64_t *num, StringParser::ParseResult parse_res)
uint8_t * ptr
Definition: udf.h:523
static StringVal HexString(FunctionContext *, const StringVal &)
void ToTimestampVal(impala_udf::TimestampVal *tv) const
static DoubleVal Pi(FunctionContext *)
bool is_null
Definition: udf.h:359
static FloatVal Sign(FunctionContext *, const DoubleVal &)
static DoubleVal Degrees(FunctionContext *, const DoubleVal &)
static DoubleVal RoundUpTo(FunctionContext *, const DoubleVal &, const IntVal &)
const TypeDesc * GetArgType(int arg_idx) const
Definition: udf.cc:425
static BigIntVal QuotientBigInt(FunctionContext *, const BigIntVal &, const BigIntVal &)
ONE_ARG_MATH_FN(Abs, BigIntVal, BigIntVal, llabs)
static StringVal ConvString(FunctionContext *, const StringVal &s, const TinyIntVal &src_base, const TinyIntVal &dst_base)
void * GetFunctionState(FunctionStateScope scope) const
Definition: udf-ir.cc:38
int GetByteSize() const
Returns the byte size of this type. Returns 0 for variable length types.
Definition: types.h:178
static StringVal FromString(FunctionContext *ctx, const std::string &s)
Definition: anyval-util.h:183
static BigIntVal Round(FunctionContext *, const DoubleVal &)
bool IsArgConstant(int arg_idx) const
Definition: udf-ir.cc:20
void SetFunctionState(FunctionStateScope scope, void *ptr)
Definition: udf.cc:370
static VAL_TYPE LeastGreatest(FunctionContext *, int num_args, const VAL_TYPE *args)
static DoubleVal Rand(FunctionContext *)
static BigIntVal QuotientDouble(FunctionContext *, const DoubleVal &, const DoubleVal &)
static const char * ALPHANUMERIC_CHARS
int GetNumArgs() const
Definition: udf-ir.cc:30
static TimestampValue FromTimestampVal(const impala_udf::TimestampVal &udf_value)
static StringVal Bin(FunctionContext *, const BigIntVal &)
uint8_t * Allocate(int byte_size)
Definition: udf.cc:262
#define UNLIKELY(expr)
Definition: compiler-util.h:33
static DoubleVal Pow(FunctionContext *, const DoubleVal &base, const DoubleVal &val)
static T Negative(FunctionContext *, const T &)
static StringValue FromStringVal(const impala_udf::StringVal &sv)
Definition: string-value.h:103
static DoubleVal E(FunctionContext *)
static bool DecimalInBaseToDecimal(int64_t src_num, int8_t src_base, int64_t *result)
static DoubleVal PmodDouble(FunctionContext *, const DoubleVal &, const DoubleVal &)
void SetError(const char *error_msg)
Definition: udf.cc:332
void ToStringVal(impala_udf::StringVal *sv) const
Definition: string-value.h:99
static DoubleVal Log(FunctionContext *, const DoubleVal &base, const DoubleVal &val)
AnyVal * GetConstantArg(int arg_idx) const
Definition: udf-ir.cc:25
static StringVal DecimalToBase(FunctionContext *, int64_t src_num, int8_t dest_base)
Converts src_num in decimal to dest_base.
static BigIntVal PmodBigInt(FunctionContext *, const BigIntVal &, const BigIntVal &)
static StringVal Unhex(FunctionContext *, const StringVal &)
static DoubleVal Radians(FunctionContext *, const DoubleVal &)
static T Positive(FunctionContext *, const T &)