Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
timestamp-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 <boost/date_time/posix_time/posix_time.hpp>
16 #include <boost/date_time/gregorian/gregorian.hpp>
17 #include <boost/date_time/time_zone_base.hpp>
18 #include <boost/date_time/local_time/local_time.hpp>
19 #include <boost/algorithm/string.hpp>
20 #include <gutil/strings/substitute.h>
21 
23 #include "exprs/expr.h"
24 #include "exprs/anyval-util.h"
25 
26 #include "runtime/tuple-row.h"
28 #include "util/path-builder.h"
30 #include "udf/udf.h"
31 #include "udf/udf-internal.h"
32 #include "runtime/runtime-state.h"
33 
34 #define TIMEZONE_DATABASE "be/files/date_time_zonespec.csv"
35 
36 #include "common/names.h"
37 
38 using boost::algorithm::iequals;
39 using boost::gregorian::days;
40 using boost::gregorian::months;
41 using boost::gregorian::weeks;
42 using boost::gregorian::years;
43 using boost::local_time::local_date_time;
44 using boost::local_time::time_zone_ptr;
45 using boost::posix_time::hours;
46 using boost::posix_time::microseconds;
47 using boost::posix_time::milliseconds;
48 using boost::posix_time::minutes;
49 using boost::posix_time::nanoseconds;
50 using boost::posix_time::ptime;
51 using boost::posix_time::seconds;
52 using namespace impala_udf;
53 using namespace strings;
54 
55 namespace impala {
56 
57 // Constant strings used for DayName function.
58 const char* TimestampFunctions::SUNDAY = "Sunday";
59 const char* TimestampFunctions::MONDAY = "Monday";
60 const char* TimestampFunctions::TUESDAY = "Tuesday";
61 const char* TimestampFunctions::WEDNESDAY = "Wednesday";
62 const char* TimestampFunctions::THURSDAY = "Thursday";
63 const char* TimestampFunctions::FRIDAY = "Friday";
64 const char* TimestampFunctions::SATURDAY = "Saturday";
65 
66 void TimestampFunctions::UnixAndFromUnixPrepare(FunctionContext* context,
68  if (scope != FunctionContext::THREAD_LOCAL) return;
69  DateTimeFormatContext* dt_ctx = NULL;
70  if (context->IsArgConstant(1)) {
71  StringVal fmt_val = *reinterpret_cast<StringVal*>(context->GetConstantArg(1));
72  const StringValue& fmt_ref = StringValue::FromStringVal(fmt_val);
73  if (fmt_val.is_null || fmt_ref.len == 0) {
74  TimestampFunctions::ReportBadFormat(context, fmt_val, true);
75  return;
76  }
77  dt_ctx = new DateTimeFormatContext(fmt_ref.ptr, fmt_ref.len);
78  bool parse_result = TimestampParser::ParseFormatTokens(dt_ctx);
79  if (!parse_result) {
80  delete dt_ctx;
81  TimestampFunctions::ReportBadFormat(context, fmt_val, true);
82  return;
83  }
84  } else {
85  // If our format string is constant, then we benefit from it only being parsed once in
86  // the code above. If it's not constant, then we can reuse a context by resetting it.
87  // This is much cheaper vs alloc/dealloc'ing a context for each evaluation.
88  dt_ctx = new DateTimeFormatContext();
89  }
90  context->SetFunctionState(scope, dt_ctx);
91 }
92 
93 void TimestampFunctions::UnixAndFromUnixClose(FunctionContext* context,
95  if (scope == FunctionContext::THREAD_LOCAL) {
96  DateTimeFormatContext* dt_ctx =
97  reinterpret_cast<DateTimeFormatContext*>(context->GetFunctionState(scope));
98  delete dt_ctx;
99  }
100 }
101 
102 template <class TIME>
103 StringVal TimestampFunctions::FromUnix(FunctionContext* context, const TIME& intp) {
104  if (intp.is_null) return StringVal::null();
105  TimestampValue t(intp.val);
106  return AnyValUtil::FromString(context, lexical_cast<string>(t));
107 }
108 
109 template <class TIME>
110 StringVal TimestampFunctions::FromUnix(FunctionContext* context, const TIME& intp,
111  const StringVal& fmt) {
112  if (fmt.is_null || fmt.len == 0) {
113  TimestampFunctions::ReportBadFormat(context, fmt, false);
114  return StringVal::null();
115  }
116  if (intp.is_null) return StringVal::null();
117 
118  TimestampValue t(intp.val);
119  void* state = context->GetFunctionState(FunctionContext::THREAD_LOCAL);
120  DateTimeFormatContext* dt_ctx = reinterpret_cast<DateTimeFormatContext*>(state);
121  if (!context->IsArgConstant(1)) {
122  dt_ctx->Reset(reinterpret_cast<const char*>(fmt.ptr), fmt.len);
123  if (!TimestampParser::ParseFormatTokens(dt_ctx)){
124  TimestampFunctions::ReportBadFormat(context, fmt, false);
125  return StringVal::null();
126  }
127  }
128 
129  int buff_len = dt_ctx->fmt_out_len + 1;
130  StringVal result(context, buff_len);
131  result.len = t.Format(*dt_ctx, buff_len, reinterpret_cast<char*>(result.ptr));
132  if (result.len <= 0) return StringVal::null();
133  return result;
134 }
135 
136 BigIntVal TimestampFunctions::Unix(FunctionContext* context, const StringVal& string_val,
137  const StringVal& fmt) {
138  if (fmt.is_null || fmt.len == 0) {
139  TimestampFunctions::ReportBadFormat(context, fmt, false);
140  return BigIntVal::null();
141  }
142  if (string_val.is_null || string_val.len == 0) return BigIntVal::null();
143 
144  void* state = context->GetFunctionState(FunctionContext::THREAD_LOCAL);
145  DateTimeFormatContext* dt_ctx = reinterpret_cast<DateTimeFormatContext*>(state);
146  if (!context->IsArgConstant(1)) {
147  dt_ctx->Reset(reinterpret_cast<const char*>(fmt.ptr), fmt.len);
148  if (!TimestampParser::ParseFormatTokens(dt_ctx)) {
149  ReportBadFormat(context, fmt, false);
150  return BigIntVal::null();
151  }
152  }
153 
155  reinterpret_cast<const char*>(string_val.ptr), string_val.len, *dt_ctx);
156  if (!tv.HasDate()) return BigIntVal::null();
157  return BigIntVal(tv.ToUnixTime());
158 }
159 
160 BigIntVal TimestampFunctions::Unix(FunctionContext* context, const TimestampVal& ts_val) {
161  if (ts_val.is_null) return BigIntVal::null();
162  const TimestampValue& tv = TimestampValue::FromTimestampVal(ts_val);
163  if (!tv.HasDate()) return BigIntVal::null();
164  return BigIntVal(tv.ToUnixTime());
165 }
166 
167 BigIntVal TimestampFunctions::Unix(FunctionContext* context) {
168  if (!context->impl()->state()->now()->HasDate()) return BigIntVal::null();
169  return BigIntVal(context->impl()->state()->now()->ToUnixTime());
170 }
171 
172 BigIntVal TimestampFunctions::UnixFromString(FunctionContext* context,
173  const StringVal& sv) {
174  if (sv.is_null) return BigIntVal::null();
175  TimestampValue tv(reinterpret_cast<const char *>(sv.ptr), sv.len);
176  if (!tv.HasDate()) return BigIntVal::null();
177  return BigIntVal(tv.ToUnixTime());
178 }
179 
180 void TimestampFunctions::ReportBadFormat(FunctionContext* context,
181  const StringVal& format, bool is_error) {
182  stringstream ss;
183  const StringValue& fmt = StringValue::FromStringVal(format);
184  if (format.is_null || format.len == 0) {
185  ss << "Bad date/time conversion format: format string is NULL or has 0 length";
186  } else {
187  ss << "Bad date/time conversion format: " << fmt.DebugString();
188  }
189  if (is_error) {
190  context->SetError(ss.str().c_str());
191  } else {
192  context->AddWarning(ss.str().c_str());
193  }
194 }
195 
196 StringVal TimestampFunctions::DayName(FunctionContext* context, const TimestampVal& ts) {
197  if (ts.is_null) return StringVal::null();
198  IntVal dow = DayOfWeek(context, ts);
199  switch(dow.val) {
200  case 1: return StringVal(SUNDAY);
201  case 2: return StringVal(MONDAY);
202  case 3: return StringVal(TUESDAY);
203  case 4: return StringVal(WEDNESDAY);
204  case 5: return StringVal(THURSDAY);
205  case 6: return StringVal(FRIDAY);
206  case 7: return StringVal(SATURDAY);
207  default: return StringVal::null();
208  }
209 }
210 
211 IntVal TimestampFunctions::Year(FunctionContext* context, const TimestampVal& ts_val) {
212  if (ts_val.is_null) return IntVal::null();
213  const TimestampValue& ts_value = TimestampValue::FromTimestampVal(ts_val);
214  if (!ts_value.HasDate()) return IntVal::null();
215  return IntVal(ts_value.date().year());
216 }
217 
218 
219 IntVal TimestampFunctions::Month(FunctionContext* context, const TimestampVal& ts_val) {
220  if (ts_val.is_null) return IntVal::null();
221  const TimestampValue& ts_value = TimestampValue::FromTimestampVal(ts_val);
222  if (!ts_value.HasDate()) return IntVal::null();
223  return IntVal(ts_value.date().month());
224 }
225 
226 
227 IntVal TimestampFunctions::DayOfWeek(FunctionContext* context,
228  const TimestampVal& ts_val) {
229  if (ts_val.is_null) return IntVal::null();
230  const TimestampValue& ts_value = TimestampValue::FromTimestampVal(ts_val);
231  if (!ts_value.HasDate()) return IntVal::null();
232  // Sql has the result in [1,7] where 1 = Sunday. Boost has 0 = Sunday.
233  return IntVal(ts_value.date().day_of_week() + 1);
234 }
235 
236 IntVal TimestampFunctions::DayOfMonth(FunctionContext* context,
237  const TimestampVal& ts_val) {
238  if (ts_val.is_null) return IntVal::null();
239  const TimestampValue& ts_value = TimestampValue::FromTimestampVal(ts_val);
240  if (!ts_value.HasDate()) return IntVal::null();
241  return IntVal(ts_value.date().day());
242 }
243 
244 IntVal TimestampFunctions::DayOfYear(FunctionContext* context,
245  const TimestampVal& ts_val) {
246  if (ts_val.is_null) return IntVal::null();
247  const TimestampValue& ts_value = TimestampValue::FromTimestampVal(ts_val);
248  if (!ts_value.HasDate()) return IntVal::null();
249  return IntVal(ts_value.date().day_of_year());
250 }
251 
252 IntVal TimestampFunctions::WeekOfYear(FunctionContext* context,
253  const TimestampVal& ts_val) {
254  if (ts_val.is_null) return IntVal::null();
255  const TimestampValue& ts_value = TimestampValue::FromTimestampVal(ts_val);
256  if (!ts_value.HasDate()) return IntVal::null();
257  return IntVal(ts_value.date().week_number());
258 }
259 
260 IntVal TimestampFunctions::Hour(FunctionContext* context, const TimestampVal& ts_val) {
261  if (ts_val.is_null) return IntVal::null();
262  const TimestampValue& ts_value = TimestampValue::FromTimestampVal(ts_val);
263  if (!ts_value.HasTime()) return IntVal::null();
264  return IntVal(ts_value.time().hours());
265 }
266 
267 IntVal TimestampFunctions::Minute(FunctionContext* context, const TimestampVal& ts_val) {
268  if (ts_val.is_null) return IntVal::null();
269  const TimestampValue& ts_value = TimestampValue::FromTimestampVal(ts_val);
270  if (!ts_value.HasTime()) return IntVal::null();
271  return IntVal(ts_value.time().minutes());
272 }
273 
274 IntVal TimestampFunctions::Second(FunctionContext* context, const TimestampVal& ts_val) {
275  if (ts_val.is_null) return IntVal::null();
276  const TimestampValue& ts_value = TimestampValue::FromTimestampVal(ts_val);
277  if (!ts_value.HasTime()) return IntVal::null();
278  return IntVal(ts_value.time().seconds());
279 }
280 
281 TimestampVal TimestampFunctions::Now(FunctionContext* context) {
282  const TimestampValue* now = context->impl()->state()->now();
283  if (!now->HasDateOrTime()) return TimestampVal::null();
284  TimestampVal return_val;
285  now->ToTimestampVal(&return_val);
286  return return_val;
287 }
288 
289 StringVal TimestampFunctions::ToDate(FunctionContext* context,
290  const TimestampVal& ts_val) {
291  if (ts_val.is_null) return StringVal::null();
292  const TimestampValue ts_value = TimestampValue::FromTimestampVal(ts_val);
293  string result = to_iso_extended_string(ts_value.date());
294  return AnyValUtil::FromString(context, result);
295 }
296 
297 template <bool ISADD, class VALTYPE, class UNIT>
298 TimestampVal TimestampFunctions::DateAddSub(FunctionContext* context,
299  const TimestampVal& ts_val, const VALTYPE& count) {
300  if (ts_val.is_null || count.is_null) return TimestampVal::null();
301  const TimestampValue& ts_value = TimestampValue::FromTimestampVal(ts_val);
302 
303  if (!ts_value.HasDate()) return TimestampVal::null();
304  UNIT unit(count.val);
305  TimestampValue value;
306  try {
307  // Adding/subtracting boost::gregorian::dates can throw (via constructing a new date)
308  value = TimestampValue(
309  (ISADD ? ts_value.date() + unit : ts_value.date() - unit), ts_value.time());
310  } catch (const std::exception& e) {
311  context->AddWarning(Substitute("Cannot $0 date interval $1: $2",
312  ISADD ? "add" : "subtract", count.val, e.what()).c_str());
313  return TimestampVal::null();
314  }
315  TimestampVal return_val;
316  value.ToTimestampVal(&return_val);
317  return return_val;
318 }
319 
320 template <bool ISADD, class VALTYPE, class UNIT>
321 TimestampVal TimestampFunctions::TimeAddSub(FunctionContext * context,
322  const TimestampVal& ts_val, const VALTYPE& count) {
323  if (ts_val.is_null || count.is_null) return TimestampVal::null();
324  const TimestampValue& ts_value = TimestampValue::FromTimestampVal(ts_val);
325  if (!ts_value.HasDate()) return TimestampVal::null();
326  UNIT unit(count.val);
327  ptime p(ts_value.date(), ts_value.time());
328  TimestampValue value(ISADD ? p + unit : p - unit);
329  TimestampVal return_val;
330  value.ToTimestampVal(&return_val);
331  return return_val;
332 }
333 
334 IntVal TimestampFunctions::DateDiff(FunctionContext* context,
335  const TimestampVal& ts_val1,
336  const TimestampVal& ts_val2) {
337  if (ts_val1.is_null || ts_val2.is_null) return IntVal::null();
338  const TimestampValue& ts_value1 = TimestampValue::FromTimestampVal(ts_val1);
339  const TimestampValue& ts_value2 = TimestampValue::FromTimestampVal(ts_val2);
340  if (!ts_value1.HasDate() || !ts_value2.HasDate()) {
341  return IntVal::null();
342  }
343  return IntVal((ts_value1.date() - ts_value2.date()).days());
344 }
345 
346 // This function uses inline asm functions, which we believe to be from the boost library.
347 // Inline asm is not currently supported by JIT, so this function should always be run in
348 // the interpreted mode. This is handled in ScalarFnCall::GetUdf().
349 TimestampVal TimestampFunctions::FromUtc(FunctionContext* context,
350  const TimestampVal& ts_val, const StringVal& tz_string_val) {
351  if (ts_val.is_null || tz_string_val.is_null) return TimestampVal::null();
352  const TimestampValue& ts_value = TimestampValue::FromTimestampVal(ts_val);
353  if (!ts_value.HasDateOrTime()) return TimestampVal::null();
354 
355  const StringValue& tz_string_value = StringValue::FromStringVal(tz_string_val);
356  time_zone_ptr timezone =
357  TimezoneDatabase::FindTimezone(tz_string_value.DebugString(), ts_value);
358  if (timezone == NULL) {
359  // This should return null. Hive just ignores it.
360  stringstream ss;
361  ss << "Unknown timezone '" << tz_string_value << "'" << endl;
362  context->AddWarning(ss.str().c_str());
363  return ts_val;
364  }
365 
366  ptime temp;
367  ts_value.ToPtime(&temp);
368  local_date_time lt(temp, timezone);
369  TimestampValue return_value = lt.local_time();
370  TimestampVal return_val;
371  return_value.ToTimestampVal(&return_val);
372  return return_val;
373 }
374 
375 // This function uses inline asm functions, which we believe to be from the boost library.
376 // Inline asm is not currently supported by JIT, so this function should always be run in
377 // the interpreted mode. This is handled in ScalarFnCall::GetUdf().
378 TimestampVal TimestampFunctions::ToUtc(FunctionContext* context,
379  const TimestampVal& ts_val, const StringVal& tz_string_val) {
380  if (ts_val.is_null || tz_string_val.is_null) return TimestampVal::null();
381  const TimestampValue& ts_value = TimestampValue::FromTimestampVal(ts_val);
382  if (!ts_value.HasDateOrTime()) return TimestampVal::null();
383 
384  const StringValue& tz_string_value = StringValue::FromStringVal(tz_string_val);
385  time_zone_ptr timezone =
386  TimezoneDatabase::FindTimezone(tz_string_value.DebugString(), ts_value);
387  // This should raise some sort of error or at least null. Hive Just ignores it.
388  if (timezone == NULL) {
389  stringstream ss;
390  ss << "Unknown timezone '" << tz_string_value << "'" << endl;
391  context->AddWarning(ss.str().c_str());
392  return ts_val;
393  }
394 
395  local_date_time lt(ts_value.date(), ts_value.time(),
396  timezone, local_date_time::NOT_DATE_TIME_ON_ERROR);
397  TimestampValue return_value(lt.utc_time());
398  TimestampVal return_val;
399  return_value.ToTimestampVal(&return_val);
400  return return_val;
401 }
402 
403 TimezoneDatabase::TimezoneDatabase() {
404  // Create a temporary file and write the timezone information. The boost
405  // interface only loads this format from a file. We don't want to raise
406  // an error here since this is done when the backend is created and this
407  // information might not actually get used by any queries.
408  char filestr[] = "/tmp/impala.tzdb.XXXXXXX";
409  FILE* file;
410  int fd;
411  if ((fd = mkstemp(filestr)) == -1) {
412  LOG(ERROR) << "Could not create temporary timezone file: " << filestr;
413  return;
414  }
415  if ((file = fopen(filestr, "w")) == NULL) {
416  unlink(filestr);
417  close(fd);
418  LOG(ERROR) << "Could not open temporary timezone file: " << filestr;
419  return;
420  }
421  if (fputs(TIMEZONE_DATABASE_STR, file) == EOF) {
422  unlink(filestr);
423  close(fd);
424  fclose(file);
425  LOG(ERROR) << "Could not load temporary timezone file: " << filestr;
426  return;
427  }
428  fclose(file);
429  tz_database_.load_from_file(string(filestr));
430  tz_region_list_ = tz_database_.region_list();
431  unlink(filestr);
432  close(fd);
433 }
434 
435 TimezoneDatabase::~TimezoneDatabase() { }
436 
437 time_zone_ptr TimezoneDatabase::FindTimezone(const string& tz, const TimestampValue& tv) {
438  // The backing database does not capture some subtleties, there are special cases
439  if ((tv.date().year() > 2011 || (tv.date().year() == 2011 && tv.date().month() >= 4)) &&
440  (iequals("Europe/Moscow", tz) || iequals("Moscow", tz) || iequals("MSK", tz))) {
441  // We transition in April 2011 from using the tz_database_ to a custom rule
442  // Russia stopped using daylight savings in 2011, the tz_database_ is
443  // set up assuming Russia uses daylight saving every year.
444  // Sun, Mar 27, 2:00AM Moscow clocks moved forward +1 hour (a total of GMT +4)
445  // Specifically,
446  // UTC Time 26 Mar 2011 22:59:59 +0000 ===> Sun Mar 27 01:59:59 MSK 2011
447  // UTC Time 26 Mar 2011 23:00:00 +0000 ===> Sun Mar 27 03:00:00 MSK 2011
448  // This means in 2011, The database rule will apply DST starting March 26 2011.
449  // This will be a correct +4 offset, and the database rule can apply until
450  // Oct 31 when tz_database_ will incorrectly attempt to turn clocks backwards 1 hour.
451  return TIMEZONE_MSK_2011_NODST;
452  }
453 
454  // See if they specified a zone id
455  if (tz.find_first_of('/') != string::npos) {
456  return tz_database_.time_zone_from_region(tz);
457  }
458  for (vector<string>::const_iterator iter = tz_region_list_.begin();
459  iter != tz_region_list_.end(); ++iter) {
460  time_zone_ptr tzp = tz_database_.time_zone_from_region(*iter);
461  DCHECK(tzp != NULL);
462  if (tzp->dst_zone_abbrev() == tz)
463  return tzp;
464  if (tzp->std_zone_abbrev() == tz)
465  return tzp;
466  if (tzp->dst_zone_name() == tz)
467  return tzp;
468  if (tzp->std_zone_name() == tz)
469  return tzp;
470  }
471  return time_zone_ptr();
472 }
473 
474 // Explicit template instantiation is required for proper linking. These functions
475 // are only indirectly called via a function pointer provided by the opcode registry
476 // which does not trigger implicit template instantiation.
477 // Must be kept in sync with common/function-registry/impala_functions.py.
478 template StringVal
479 TimestampFunctions::FromUnix<IntVal>(FunctionContext* context, const IntVal& intp, const
480  StringVal& fmt);
481 template StringVal
482 TimestampFunctions::FromUnix<BigIntVal>(FunctionContext* context, const BigIntVal& intp,
483  const StringVal& fmt);
484 template StringVal
485 TimestampFunctions::FromUnix<IntVal>(FunctionContext* context , const IntVal& intp);
486 template StringVal
487 TimestampFunctions::FromUnix<BigIntVal>(FunctionContext* context, const BigIntVal& intp);
488 
489 template TimestampVal
490 TimestampFunctions::DateAddSub<true, IntVal, years>(FunctionContext* context,
491  const TimestampVal& ts_val, const IntVal& count);
492 template TimestampVal
493 TimestampFunctions::DateAddSub<true, BigIntVal, years>(FunctionContext* context,
494  const TimestampVal& ts_val, const BigIntVal& count);
495 template TimestampVal
496 TimestampFunctions::DateAddSub<false, IntVal, years>(FunctionContext* context,
497  const TimestampVal& ts_val, const IntVal& count);
498 template TimestampVal
499 TimestampFunctions::DateAddSub<false, BigIntVal, years>(FunctionContext* context,
500  const TimestampVal& ts_val, const BigIntVal& count);
501 template TimestampVal
502 TimestampFunctions::DateAddSub<true, IntVal, months>(FunctionContext* context,
503  const TimestampVal& ts_val, const IntVal& count);
504 template TimestampVal
505 TimestampFunctions::DateAddSub<true, BigIntVal, months>(FunctionContext* context,
506  const TimestampVal& ts_val, const BigIntVal& count);
507 template TimestampVal
508 TimestampFunctions::DateAddSub<false, IntVal, months>(FunctionContext* context,
509  const TimestampVal& ts_val, const IntVal& count);
510 template TimestampVal
511 TimestampFunctions::DateAddSub<false, BigIntVal, months>(FunctionContext* context,
512  const TimestampVal& ts_val, const BigIntVal& count);
513 template TimestampVal
514 TimestampFunctions::DateAddSub<true, IntVal, weeks>(FunctionContext* context,
515  const TimestampVal& ts_val, const IntVal& count);
516 template TimestampVal
517 TimestampFunctions::DateAddSub<true, BigIntVal, weeks>(FunctionContext* context,
518  const TimestampVal& ts_val, const BigIntVal& count);
519 template TimestampVal
520 TimestampFunctions::DateAddSub<false, IntVal, weeks>(FunctionContext* context,
521  const TimestampVal& ts_val, const IntVal& count);
522 template TimestampVal
523 TimestampFunctions::DateAddSub<false, BigIntVal, weeks>(FunctionContext* context,
524  const TimestampVal& ts_val, const BigIntVal& count);
525 template TimestampVal
526 TimestampFunctions::DateAddSub<true, IntVal, days>(FunctionContext* context,
527  const TimestampVal& ts_val, const IntVal& count);
528 template TimestampVal
529 TimestampFunctions::DateAddSub<true, BigIntVal, days>(FunctionContext* context,
530  const TimestampVal& ts_val, const BigIntVal& count);
531 template TimestampVal
532 TimestampFunctions::DateAddSub<false, IntVal, days>(FunctionContext* context,
533  const TimestampVal& ts_val, const IntVal& count);
534 template TimestampVal
535 TimestampFunctions::DateAddSub<false, BigIntVal, days>(FunctionContext* context,
536  const TimestampVal& ts_val, const BigIntVal& count);
537 
538 template TimestampVal
539 TimestampFunctions::TimeAddSub<true, IntVal, hours>(FunctionContext* context,
540  const TimestampVal& ts_val, const IntVal& count);
541 template TimestampVal
542 TimestampFunctions::TimeAddSub<true, BigIntVal, hours>(FunctionContext* context,
543  const TimestampVal& ts_val, const BigIntVal& count);
544 template TimestampVal
545 TimestampFunctions::TimeAddSub<false, IntVal, hours>(FunctionContext* context,
546  const TimestampVal& ts_val, const IntVal& count);
547 template TimestampVal
548 TimestampFunctions::TimeAddSub<false, BigIntVal, hours>(FunctionContext* context,
549  const TimestampVal& ts_val, const BigIntVal& count);
550 template TimestampVal
551 TimestampFunctions::TimeAddSub<true, IntVal, minutes>(FunctionContext* context,
552  const TimestampVal& ts_val, const IntVal& count);
553 template TimestampVal
554 TimestampFunctions::TimeAddSub<true, BigIntVal, minutes>(FunctionContext* context,
555  const TimestampVal& ts_val, const BigIntVal& count);
556 template TimestampVal
557 TimestampFunctions::TimeAddSub<false, IntVal, minutes>(FunctionContext* context,
558  const TimestampVal& ts_val, const IntVal& count);
559 template TimestampVal
560 TimestampFunctions::TimeAddSub<false, BigIntVal, minutes>(FunctionContext* context,
561  const TimestampVal& ts_val, const BigIntVal& count);
562 template TimestampVal
563 TimestampFunctions::TimeAddSub<true, IntVal, seconds>(FunctionContext* context,
564  const TimestampVal& ts_val, const IntVal& count);
565 template TimestampVal
566 TimestampFunctions::TimeAddSub<true, BigIntVal, seconds>(FunctionContext* context,
567  const TimestampVal& ts_val, const BigIntVal& count);
568 template TimestampVal
569 TimestampFunctions::TimeAddSub<false, IntVal, seconds>(FunctionContext* context,
570  const TimestampVal& ts_val, const IntVal& count);
571 template TimestampVal
572 TimestampFunctions::TimeAddSub<false, BigIntVal, seconds>(FunctionContext* context,
573  const TimestampVal& ts_val, const BigIntVal& count);
574 template TimestampVal
575 TimestampFunctions::TimeAddSub<true, IntVal, milliseconds>(FunctionContext* context,
576  const TimestampVal& ts_val, const IntVal& count);
577 template TimestampVal
578 TimestampFunctions::TimeAddSub<true, BigIntVal, milliseconds>(FunctionContext* context,
579  const TimestampVal& ts_val, const BigIntVal& count);
580 template TimestampVal
581 TimestampFunctions::TimeAddSub<false, IntVal, milliseconds>(FunctionContext* context,
582  const TimestampVal& ts_val, const IntVal& count);
583 template TimestampVal
584 TimestampFunctions::TimeAddSub<false, BigIntVal, milliseconds>(FunctionContext* context,
585  const TimestampVal& ts_val, const BigIntVal& count);
586 template TimestampVal
587 TimestampFunctions::TimeAddSub<true, IntVal, microseconds>(FunctionContext* context,
588  const TimestampVal& ts_val, const IntVal& count);
589 template TimestampVal
590 TimestampFunctions::TimeAddSub<true, BigIntVal, microseconds>(FunctionContext* context,
591  const TimestampVal& ts_val, const BigIntVal& count);
592 template TimestampVal
593 TimestampFunctions::TimeAddSub<false, IntVal, microseconds>(FunctionContext* context,
594  const TimestampVal& ts_val, const IntVal& count);
595 template TimestampVal
596 TimestampFunctions::TimeAddSub<false, BigIntVal, microseconds>(FunctionContext* context,
597  const TimestampVal& ts_val, const BigIntVal& count);
598 template TimestampVal
599 TimestampFunctions::TimeAddSub<true, IntVal, nanoseconds>(FunctionContext* context,
600  const TimestampVal& ts_val, const IntVal& count);
601 template TimestampVal
602 TimestampFunctions::TimeAddSub<true, BigIntVal, nanoseconds>(FunctionContext* context,
603  const TimestampVal& ts_val, const BigIntVal& count);
604 template TimestampVal
605 TimestampFunctions::TimeAddSub<false, IntVal, nanoseconds>(FunctionContext* context,
606  const TimestampVal& ts_val, const IntVal& count);
607 template TimestampVal
608 TimestampFunctions::TimeAddSub<false, BigIntVal, nanoseconds>(FunctionContext* context,
609  const TimestampVal& ts_val, const BigIntVal& count);
610 }
int Format(const DateTimeFormatContext &dt_ctx, int len, char *buff)
static BigIntVal null()
Definition: udf.h:444
impala::FunctionContextImpl * impl()
TODO: Add mechanism for UDAs to update stats similar to runtime profile counters. ...
Definition: udf.h:202
static IntVal null()
Definition: udf.h:425
void Reset(const char *fmt, int fmt_len)
int32_t val
Definition: udf.h:421
bool HasDateOrTime() const
const boost::posix_time::time_duration & time() const
This object has a compatible storage format with boost::ptime.
Definition: udf.h:495
uint8_t * ptr
Definition: udf.h:523
void ToTimestampVal(impala_udf::TimestampVal *tv) const
bool AddWarning(const char *warning_msg)
Definition: udf.cc:345
bool is_null
Definition: udf.h:359
static TimestampVal null()
Definition: udf.h:505
void * GetFunctionState(FunctionStateScope scope) const
Definition: udf-ir.cc:38
bool IsArgConstant(int arg_idx) const
Definition: udf-ir.cc:20
void SetFunctionState(FunctionStateScope scope, void *ptr)
Definition: udf.cc:370
uint64_t count
RuntimeState * state()
Definition: udf-internal.h:95
static StringVal null()
Definition: udf.h:536
void ToPtime(boost::posix_time::ptime *ptp) const
const TimestampValue * now() const
void SetError(const char *error_msg)
Definition: udf.cc:332
const boost::gregorian::date & date() const
AnyVal * GetConstantArg(int arg_idx) const
Definition: udf-ir.cc:25
time_t ToUnixTime() const
std::string DebugString() const
Definition: string-value.cc:24