1 #ifndef __S3SELECT_FUNCTIONS__
2 #define __S3SELECT_FUNCTIONS__
5 #include "s3select_oper.h"
6 #include <boost/algorithm/string.hpp>
7 #include <boost/algorithm/string/trim.hpp>
8 #include <boost/regex.hpp>
11 using namespace std::string_literals
;
13 #define BOOST_BIND_ACTION_PARAM( push_name ,param ) boost::bind( &push_name::operator(), g_ ## push_name , _1 ,_2, param)
14 namespace s3selectEngine
17 constexpr double sec_scale(int n
)
24 void operator()(const char* a
, const char* b
, uint32_t* n
) const
30 static push_char g_push_char
;
34 void operator()(const char* a
, const char* b
, uint32_t* n
) const
36 *n
= (static_cast<char>(*a
) - 48) * 10 + (static_cast<char>(*(a
+1)) - 48) ;
40 static push_2dig g_push_2dig
;
44 void operator()(const char* a
, const char* b
, uint32_t* n
) const
46 *n
= (static_cast<char>(*a
) - 48) * 1000 + (static_cast<char>(*(a
+1)) - 48) * 100 + (static_cast<char>(*(a
+2)) - 48) * 10 + (static_cast<char>(*(a
+3)) - 48);
50 static push_4dig g_push_4dig
;
54 void operator()(const char* a
, const char* b
, uint32_t* n
) const
56 #if BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
57 const double scale
= sec_scale(9-1); //nano-sec
59 const double scale
= sec_scale(6-1); //micro-sec
62 *n
= ((static_cast<char>(*a
) - 48)) * scale
;
66 static push_1fdig g_push_1fdig
;
70 void operator()(const char* a
, const char* b
, uint32_t* n
) const
72 #if BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
73 const double scale
= sec_scale(9-2); //nano-sec
75 const double scale
= sec_scale(6-2); //micro-sec
78 *n
= ((static_cast<char>(*a
) - 48) * 10 + (static_cast<char>(*(a
+1)) - 48)) * scale
;
82 static push_2fdig g_push_2fdig
;
86 void operator()(const char* a
, const char* b
, uint32_t* n
) const
88 #if BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
89 const double scale
= sec_scale(9-3); //nano-sec
91 const double scale
= sec_scale(6-3); //micro-sec
94 *n
= ((static_cast<char>(*a
) - 48) * 100 + (static_cast<char>(*(a
+1)) - 48) * 10 + (static_cast<char>(*(a
+2)) - 48)) * scale
;
98 static push_3fdig g_push_3fdig
;
102 void operator()(const char* a
, const char* b
, uint32_t* n
) const
104 #if BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
105 const double scale
= sec_scale(9-4); //nano-sec
107 const double scale
= sec_scale(6-4); //micro-sec
110 *n
= ((static_cast<char>(*a
) - 48) * 1000 + (static_cast<char>(*(a
+1)) - 48) * 100 + (static_cast<char>(*(a
+2)) - 48) * 10 + (static_cast<char>(*(a
+3)) - 48)) * scale
;
114 static push_4fdig g_push_4fdig
;
118 void operator()(const char* a
, const char* b
, uint32_t* n
) const
120 #if BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
121 const double scale
= sec_scale(9-5); //nano-sec
123 const double scale
= sec_scale(6-5); //micro-sec
126 *n
= ((static_cast<char>(*a
) - 48) * 10000 + (static_cast<char>(*(a
+1)) - 48) * 1000 + (static_cast<char>(*(a
+2)) - 48) * 100 + (static_cast<char>(*(a
+3)) - 48) * 10 + (static_cast<char>(*(a
+4)) - 48)) * scale
;
130 static push_5fdig g_push_5fdig
;
134 void operator()(const char* a
, const char* b
, uint32_t* n
) const
136 #if BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
137 const double scale
= sec_scale(9-6); //nano-sec
139 const double scale
= sec_scale(6-6); //micro-sec
142 *n
= ((static_cast<char>(*a
) - 48) * 100000 + (static_cast<char>(*(a
+1)) - 48) * 10000 + (static_cast<char>(*(a
+2)) - 48) * 1000 + (static_cast<char>(*(a
+3)) - 48) * 100 + (static_cast<char>(*(a
+4)) - 48) * 10 + (static_cast<char>(*(a
+5)) - 48)) * scale
;
146 static push_6fdig g_push_6fdig
;
148 #if BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
151 void operator()(const char* a
, const char* b
, uint32_t* n
) const
153 const double scale
= sec_scale(9-7); //nano-sec
154 *n
= ((static_cast<char>(*a
) - 48) * 1000000 + (static_cast<char>(*(a
+1)) - 48) * 100000 + (static_cast<char>(*(a
+2)) - 48) * 10000 + (static_cast<char>(*(a
+3)) - 48) * 1000 + (static_cast<char>(*(a
+4)) - 48) * 100 + (static_cast<char>(*(a
+5)) - 48) * 10 + (static_cast<char>(*(a
+6)) - 48)) * scale
;
158 static push_7fdig g_push_7fdig
;
162 void operator()(const char* a
, const char* b
, uint32_t* n
) const
164 const double scale
= sec_scale(9-8); //nano-sec
165 *n
= ((static_cast<char>(*a
) - 48) * 10000000 + (static_cast<char>(*(a
+1)) - 48) * 1000000 + (static_cast<char>(*(a
+2)) - 48) * 100000 + (static_cast<char>(*(a
+3)) - 48) * 10000 + (static_cast<char>(*(a
+4)) - 48) * 1000 + (static_cast<char>(*(a
+5)) - 48) * 100 + (static_cast<char>(*(a
+6)) - 48) * 10 + (static_cast<char>(*(a
+7)) - 48)) * scale
;
169 static push_8fdig g_push_8fdig
;
173 void operator()(const char* a
, const char* b
, uint32_t* n
) const
175 const double scale
= sec_scale(9-9); //nano-sec
176 *n
= ((static_cast<char>(*a
) - 48) * 100000000 + (static_cast<char>(*(a
+1)) - 48) * 10000000 + (static_cast<char>(*(a
+2)) - 48) * 1000000 + (static_cast<char>(*(a
+3)) - 48) * 100000 + (static_cast<char>(*(a
+4)) - 48) * 10000 + (static_cast<char>(*(a
+5)) - 48) * 1000 + (static_cast<char>(*(a
+6)) - 48) * 100 + (static_cast<char>(*(a
+7)) - 48) * 10 + (static_cast<char>(*(a
+8)) - 48)) * scale
;
180 static push_9fdig g_push_9fdig
;
183 enum class s3select_func_En_t
{ADD
,
203 EXTRACT_TIMEZONE_HOUR
,
204 EXTRACT_TIMEZONE_MINUTE
,
240 class s3select_functions
245 using FunctionLibrary
= std::map
<std::string
, s3select_func_En_t
>;
246 s3select_allocator
* m_s3select_allocator
;
247 std::set
<base_statement
*>* m_ast_nodes_for_cleanup
;
249 const FunctionLibrary m_functions_library
=
251 {"add", s3select_func_En_t::ADD
},
252 {"sum", s3select_func_En_t::SUM
},
253 {"avg", s3select_func_En_t::AVG
},
254 {"count", s3select_func_En_t::COUNT
},
255 {"min", s3select_func_En_t::MIN
},
256 {"max", s3select_func_En_t::MAX
},
257 {"int", s3select_func_En_t::TO_INT
},
258 {"float", s3select_func_En_t::TO_FLOAT
},
259 {"substring", s3select_func_En_t::SUBSTR
},
260 {"to_timestamp", s3select_func_En_t::TO_TIMESTAMP
},
261 {"#to_string_constant#",s3select_func_En_t::TO_STRING_CONSTANT
},
262 {"#to_string_dynamic#",s3select_func_En_t::TO_STRING_DYNAMIC
},
263 {"to_bool", s3select_func_En_t::TO_BOOL
},
264 {"#extract_year#", s3select_func_En_t::EXTRACT_YEAR
},
265 {"#extract_month#", s3select_func_En_t::EXTRACT_MONTH
},
266 {"#extract_day#", s3select_func_En_t::EXTRACT_DAY
},
267 {"#extract_hour#", s3select_func_En_t::EXTRACT_HOUR
},
268 {"#extract_minute#", s3select_func_En_t::EXTRACT_MINUTE
},
269 {"#extract_second#", s3select_func_En_t::EXTRACT_SECOND
},
270 {"#extract_week#", s3select_func_En_t::EXTRACT_WEEK
},
271 {"#extract_timezone_hour#", s3select_func_En_t::EXTRACT_TIMEZONE_HOUR
},
272 {"#extract_timezone_minute#", s3select_func_En_t::EXTRACT_TIMEZONE_MINUTE
},
273 {"#dateadd_year#", s3select_func_En_t::DATE_ADD_YEAR
},
274 {"#dateadd_month#", s3select_func_En_t::DATE_ADD_MONTH
},
275 {"#dateadd_day#", s3select_func_En_t::DATE_ADD_DAY
},
276 {"#dateadd_hour#", s3select_func_En_t::DATE_ADD_HOUR
},
277 {"#dateadd_minute#", s3select_func_En_t::DATE_ADD_MINUTE
},
278 {"#dateadd_second#", s3select_func_En_t::DATE_ADD_SECOND
},
279 {"#datediff_year#", s3select_func_En_t::DATE_DIFF_YEAR
},
280 {"#datediff_month#", s3select_func_En_t::DATE_DIFF_MONTH
},
281 {"#datediff_day#", s3select_func_En_t::DATE_DIFF_DAY
},
282 {"#datediff_hour#", s3select_func_En_t::DATE_DIFF_HOUR
},
283 {"#datediff_minute#", s3select_func_En_t::DATE_DIFF_MINUTE
},
284 {"#datediff_second#", s3select_func_En_t::DATE_DIFF_SECOND
},
285 {"utcnow", s3select_func_En_t::UTCNOW
},
286 {"character_length", s3select_func_En_t::LENGTH
},
287 {"char_length", s3select_func_En_t::LENGTH
},
288 {"lower", s3select_func_En_t::LOWER
},
289 {"upper", s3select_func_En_t::UPPER
},
290 {"nullif", s3select_func_En_t::NULLIF
},
291 {"#between#", s3select_func_En_t::BETWEEN
},
292 {"#not_between#", s3select_func_En_t::NOT_BETWEEN
},
293 {"#is_null#", s3select_func_En_t::IS_NULL
},
294 {"#is_not_null#", s3select_func_En_t::IS_NOT_NULL
},
295 {"#in_predicate#", s3select_func_En_t::IN
},
296 {"#like_predicate#", s3select_func_En_t::LIKE
},
297 {"version", s3select_func_En_t::VERSION
},
298 {"#when-then#", s3select_func_En_t::WHEN_THEN
},
299 {"#when-value-then#", s3select_func_En_t::WHEN_VALUE_THEN
},
300 {"#case-when-else#", s3select_func_En_t::CASE_WHEN_ELSE
},
301 {"coalesce", s3select_func_En_t::COALESCE
},
302 {"string", s3select_func_En_t::STRING
},
303 {"#trim#", s3select_func_En_t::TRIM
},
304 {"#leading#", s3select_func_En_t::LEADING
},
305 {"#trailing#", s3select_func_En_t::TRAILING
}
310 base_function
* create(std::string_view fn_name
,const bs_stmt_vec_t
&);
312 s3select_functions():m_s3select_allocator(nullptr),m_ast_nodes_for_cleanup(nullptr)
317 void setAllocator(s3select_allocator
* alloc
)
319 m_s3select_allocator
= alloc
;
322 void set_AST_nodes_for_cleanup(std::set
<base_statement
*>* ast_for_cleanup
)
324 m_ast_nodes_for_cleanup
= ast_for_cleanup
;
327 s3select_allocator
* getAllocator()
329 return m_s3select_allocator
;
336 class __function
: public base_statement
340 bs_stmt_vec_t arguments
;
341 std::basic_string
<char,std::char_traits
<char>,ChunkAllocator
<char,256>> name
;
342 base_function
* m_func_impl
;
343 s3select_functions
* m_s3select_functions
;
345 bool m_is_aggregate_function
;
354 auto string_to_lower
= [](std::basic_string
<char,std::char_traits
<char>,ChunkAllocator
<char,256>> s
)
356 std::transform(s
.begin(),s
.end(),s
.begin(),[](unsigned char c
){ return std::tolower(c
); });
360 //the function name is converted into lowercase to enable case-insensitive
361 base_function
* f
= m_s3select_functions
->create(string_to_lower(name
),arguments
);
364 throw base_s3select_exception("function not found", base_s3select_exception::s3select_exp_en_t::FATAL
); //should abort query
367 m_is_aggregate_function
= m_func_impl
->is_aggregate();
373 base_function
* impl()
378 void traverse_and_apply(scratch_area
* sa
, projection_alias
* pa
,bool json_statement
) override
382 m_json_statement
= json_statement
;
383 for (base_statement
* ba
: arguments
)
385 ba
->traverse_and_apply(sa
, pa
, json_statement
);
389 void set_last_call() override
390 {//it cover the use-case where aggregation function is an argument in non-aggregate function.
392 for (auto& ba
: arguments
)
398 void set_skip_non_aggregate(bool skip_non_aggregate_op
) override
399 {//it cover the use-case where aggregation function is an argument in non-aggregate function.
400 m_skip_non_aggregate_op
= skip_non_aggregate_op
;
401 for (auto& ba
: arguments
)
403 ba
->set_skip_non_aggregate(m_skip_non_aggregate_op
);
407 bool is_aggregate() const override
409 return m_is_aggregate_function
;
412 bool semantic() override
417 __function(const char* fname
, s3select_functions
* s3f
) : name(fname
), m_func_impl(nullptr), m_s3select_functions(s3f
),m_is_aggregate_function(false)
420 value
& eval() override
422 return eval_internal();
425 value
& eval_internal() override
428 _resolve_name();//node is "resolved" (function is created) upon first call/first row.
430 if (is_last_call
== false)
431 {//all rows prior to last row
432 if(m_skip_non_aggregate_op
== false || is_aggregate() == true)
434 (*m_func_impl
)(&arguments
, &m_result
);
436 else if(m_skip_non_aggregate_op
== true)
438 for(auto& p
: arguments
)
439 {//evaluating the arguments (not the function itself, which is a non-aggregate function)
440 //i.e. in the following use case substring( , sum(),count() ) ; only sum() and count() are evaluated.
446 {//on the last row, the aggregate function is finalized,
447 //and non-aggregate function is evaluated with the result of aggregate function.
449 (*m_func_impl
).get_aggregate_result(&m_result
);
451 (*m_func_impl
)(&arguments
, &m_result
);
454 return m_result
.get_value();
457 void resolve_node() override
461 for (auto& arg
: arguments
)
467 std::string
print(int ident
) override
469 return std::string(0);
472 void push_argument(base_statement
* arg
)
474 arguments
.push_back(arg
);
478 bs_stmt_vec_t
& get_arguments()
483 virtual ~__function() = default;
487 s3-select function defintions
489 struct _fn_add
: public base_function
494 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
496 auto iter
= args
->begin();
497 base_statement
* x
= *iter
;
499 base_statement
* y
= *iter
;
501 var_result
= x
->eval() + y
->eval();
503 *result
= var_result
;
509 struct _fn_sum
: public base_function
519 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
521 auto iter
= args
->begin();
522 base_statement
* x
= *iter
;
526 sum
= sum
+ x
->eval();
528 catch (base_s3select_exception
& e
)
530 if (e
.severity() == base_s3select_exception::s3select_exp_en_t::FATAL
)
539 void get_aggregate_result(variable
* result
) override
545 struct _fn_count
: public base_function
555 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
558 {// in case argument exist, should count only non-null.
559 auto iter
= args
->begin();
560 base_statement
* x
= *iter
;
562 if(!x
->eval().is_null())
568 {//in case of non-arguments // count()
575 void get_aggregate_result(variable
* result
) override
577 result
->set_value(count
);
582 struct _fn_avg
: public base_function
588 _fn_avg() : sum(0) { aggregate
= true; }
590 bool operator()(bs_stmt_vec_t
* args
, variable
*result
) override
592 auto iter
= args
->begin();
593 base_statement
*x
= *iter
;
597 sum
= sum
+ x
->eval();
600 catch (base_s3select_exception
&e
)
602 throw base_s3select_exception(e
.what());
608 void get_aggregate_result(variable
*result
) override
610 if(count
== static_cast<value
>(0)) {
611 throw base_s3select_exception("count cannot be zero!");
613 *result
= sum
/count
;
618 struct _fn_min
: public base_function
623 _fn_min():min(__INT64_MAX__
)
628 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
630 auto iter
= args
->begin();
631 base_statement
* x
= *iter
;
641 void get_aggregate_result(variable
* result
) override
648 struct _fn_max
: public base_function
653 _fn_max():max(-__INT64_MAX__
)
658 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
660 auto iter
= args
->begin();
661 base_statement
* x
= *iter
;
671 void get_aggregate_result(variable
* result
) override
678 struct _fn_to_int
: public base_function
682 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
684 value v
= (*args
->begin())->eval();
688 case value::value_En_t::STRING
:
692 int64_t i
= strtol(v
.str(), &pend
, 10);
693 if (errno
== ERANGE
) {
694 throw base_s3select_exception("converted value would fall out of the range of the result type!");
696 if (pend
== v
.str()) {
698 throw base_s3select_exception("text cannot be converted to a number");
701 throw base_s3select_exception("extra characters after the number");
708 case value::value_En_t::FLOAT
:
709 var_result
= static_cast<int64_t>(v
.dbl());
713 var_result
= v
.i64();
717 *result
= var_result
;
723 struct _fn_to_float
: public base_function
727 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
729 value v
= (*args
->begin())->eval();
733 case value::value_En_t::STRING
:
736 double d
= strtod(v
.str(), &pend
);
737 if (errno
== ERANGE
) {
738 throw base_s3select_exception("converted value would fall out of the range of the result type!");
740 if (pend
== v
.str()) {
742 throw base_s3select_exception("text cannot be converted to a number");
745 throw base_s3select_exception("extra characters after the number");
752 case value::value_En_t::FLOAT
:
753 var_result
= v
.dbl();
757 var_result
= v
.i64();
761 *result
= var_result
;
767 struct _fn_to_timestamp
: public base_function
769 bsc::rule
<> date_separator
= bsc::ch_p("-");
770 bsc::rule
<> time_separator
= bsc::ch_p(":");
771 bsc::rule
<> nano_sec_separator
= bsc::ch_p(".");
772 bsc::rule
<> delimiter
= bsc::ch_p("T");
773 bsc::rule
<> zero_timezone
= bsc::ch_p("Z");
774 bsc::rule
<> timezone_sign
= bsc::ch_p("-") | bsc::ch_p("+");
776 uint32_t yr
= 1700, mo
= 1, dy
= 1;
777 bsc::rule
<> dig4
= bsc::lexeme_d
[bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
];
778 bsc::rule
<> dig2
= bsc::lexeme_d
[bsc::digit_p
>> bsc::digit_p
];
780 bsc::rule
<> d_yyyy_dig
= ((dig4
[BOOST_BIND_ACTION_PARAM(push_4dig
, &yr
)]) >> *(delimiter
));
781 bsc::rule
<> d_yyyymmdd_dig
= ((dig4
[BOOST_BIND_ACTION_PARAM(push_4dig
, &yr
)]) >> *(date_separator
)
782 >> (dig2
[BOOST_BIND_ACTION_PARAM(push_2dig
, &mo
)]) >> *(date_separator
)
783 >> (dig2
[BOOST_BIND_ACTION_PARAM(push_2dig
, &dy
)]) >> *(delimiter
));
785 uint32_t hr
= 0, mn
= 0, sc
= 0, frac_sec
= 0, tz_hr
= 0, tz_mn
= 0, sign
, tm_zone
= '0';
787 #if BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
788 bsc::rule
<> fdig9
= bsc::lexeme_d
[bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
];
789 bsc::rule
<> fdig8
= bsc::lexeme_d
[bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
];
790 bsc::rule
<> fdig7
= bsc::lexeme_d
[bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
];
793 bsc::rule
<> fdig6
= bsc::lexeme_d
[bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
];
794 bsc::rule
<> fdig5
= bsc::lexeme_d
[bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
];
795 bsc::rule
<> fdig4
= bsc::lexeme_d
[bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
];
796 bsc::rule
<> fdig3
= bsc::lexeme_d
[bsc::digit_p
>> bsc::digit_p
>> bsc::digit_p
];
797 bsc::rule
<> fdig2
= bsc::lexeme_d
[bsc::digit_p
>> bsc::digit_p
];
798 bsc::rule
<> fdig1
= bsc::lexeme_d
[bsc::digit_p
];
800 bsc::rule
<> d_timezone_dig
= ((timezone_sign
[BOOST_BIND_ACTION_PARAM(push_char
, &sign
)]) >> (dig2
[BOOST_BIND_ACTION_PARAM(push_2dig
, &tz_hr
)]) >> *(time_separator
)
801 >> (dig2
[BOOST_BIND_ACTION_PARAM(push_2dig
, &tz_mn
)])) | (zero_timezone
[BOOST_BIND_ACTION_PARAM(push_char
, &tm_zone
)]);
803 #if BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
804 bsc::rule
<> fraction_sec
= (fdig9
[BOOST_BIND_ACTION_PARAM(push_9fdig
, &frac_sec
)]) |
805 (fdig8
[BOOST_BIND_ACTION_PARAM(push_8fdig
, &frac_sec
)]) |
806 (fdig7
[BOOST_BIND_ACTION_PARAM(push_7fdig
, &frac_sec
)]) |
807 (fdig6
[BOOST_BIND_ACTION_PARAM(push_6fdig
, &frac_sec
)]) |
808 (fdig5
[BOOST_BIND_ACTION_PARAM(push_5fdig
, &frac_sec
)]) |
809 (fdig4
[BOOST_BIND_ACTION_PARAM(push_4fdig
, &frac_sec
)]) |
810 (fdig3
[BOOST_BIND_ACTION_PARAM(push_3fdig
, &frac_sec
)]) |
811 (fdig2
[BOOST_BIND_ACTION_PARAM(push_2fdig
, &frac_sec
)]) |
812 (fdig1
[BOOST_BIND_ACTION_PARAM(push_1fdig
, &frac_sec
)]);
814 bsc::rule
<> fraction_sec
= (fdig6
[BOOST_BIND_ACTION_PARAM(push_6fdig
, &frac_sec
)]) |
815 (fdig5
[BOOST_BIND_ACTION_PARAM(push_5fdig
, &frac_sec
)]) |
816 (fdig4
[BOOST_BIND_ACTION_PARAM(push_4fdig
, &frac_sec
)]) |
817 (fdig3
[BOOST_BIND_ACTION_PARAM(push_3fdig
, &frac_sec
)]) |
818 (fdig2
[BOOST_BIND_ACTION_PARAM(push_2fdig
, &frac_sec
)]) |
819 (fdig1
[BOOST_BIND_ACTION_PARAM(push_1fdig
, &frac_sec
)]);
822 bsc::rule
<> d_time_dig
= ((dig2
[BOOST_BIND_ACTION_PARAM(push_2dig
, &hr
)]) >> *(time_separator
)
823 >> (dig2
[BOOST_BIND_ACTION_PARAM(push_2dig
, &mn
)]) >> *(time_separator
)
824 >> (dig2
[BOOST_BIND_ACTION_PARAM(push_2dig
, &sc
)]) >> *(nano_sec_separator
)
825 >> (fraction_sec
) >> (d_timezone_dig
)) |
826 ((dig2
[BOOST_BIND_ACTION_PARAM(push_2dig
, &hr
)]) >> *(time_separator
)
827 >> (dig2
[BOOST_BIND_ACTION_PARAM(push_2dig
, &mn
)]) >> *(time_separator
)
828 >> (dig2
[BOOST_BIND_ACTION_PARAM(push_2dig
, &sc
)]) >> (d_timezone_dig
)) |
829 ((dig2
[BOOST_BIND_ACTION_PARAM(push_2dig
, &hr
)]) >> *(time_separator
)
830 >> (dig2
[BOOST_BIND_ACTION_PARAM(push_2dig
, &mn
)]) >> (d_timezone_dig
));
832 bsc::rule
<> d_date_time
= ((d_yyyymmdd_dig
) >> (d_time_dig
)) | (d_yyyymmdd_dig
) | (d_yyyy_dig
);
838 bool datetime_validation()
840 if (yr
>= 1400 && yr
<= 9999 && mo
>= 1 && mo
<= 12 && dy
>= 1 && hr
< 24 && mn
< 60 && sc
< 60 && tz_hour
<= 14 && tz_hour
>= -12 && tz_mn
< 60)
842 if ( (tz_hour
== -12 || tz_hour
== 14) && tz_mn
> 0)
871 if(!(yr
% 4) == 0 && dy
> 28)
875 else if(!(yr
% 100) == 0 && dy
<= 29)
879 else if(!(yr
% 400) == 0 && dy
> 28)
901 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
912 auto iter
= args
->begin();
913 int args_size
= args
->size();
917 throw base_s3select_exception("to_timestamp should have one parameter");
920 base_statement
* str
= *iter
;
924 if (v_str
.type
!= value::value_En_t::STRING
)
926 throw base_s3select_exception("to_timestamp first argument must be string"); //can skip current row
929 bsc::parse_info
<> info_dig
= bsc::parse(v_str
.str(), d_date_time
);
933 if ((char)sign
== '-')
939 if(datetime_validation()==false or !info_dig
.full
)
941 throw base_s3select_exception("input date-time is illegal");
944 boost::posix_time::ptime new_ptime
;
946 #if BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
947 new_ptime
= boost::posix_time::ptime(boost::gregorian::date(yr
, mo
, dy
),
948 boost::posix_time::hours(hr
) +
949 boost::posix_time::minutes(mn
) +
950 boost::posix_time::seconds(sc
) +
951 boost::posix_time::nanoseconds(frac_sec
));
953 new_ptime
= boost::posix_time::ptime(boost::gregorian::date(yr
, mo
, dy
),
954 boost::posix_time::hours(hr
) +
955 boost::posix_time::minutes(mn
) +
956 boost::posix_time::seconds(sc
) +
957 boost::posix_time::microseconds(frac_sec
));
960 tmstmp
= std::make_tuple(new_ptime
, boost::posix_time::time_duration(tz_hour
, tz_min
, 0), (char)tm_zone
== 'Z');
962 result
->set_value(&tmstmp
);
969 struct _fn_to_string_constant
: public base_timestamp_to_string
971 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
973 param_validation(args
);
977 prepare_to_string_vector(print_vector
, para
);
981 std::string result_
= execute_to_string(print_vector
, para
);
983 result
->set_value(result_
.c_str());
988 struct _fn_to_string_dynamic
: public base_timestamp_to_string
990 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
992 param_validation(args
);
994 print_vector
.clear();
997 prepare_to_string_vector(print_vector
, para
);
999 std::string result_
= execute_to_string(print_vector
, para
);
1001 result
->set_value(result_
.c_str());
1006 struct _fn_extract_year_from_timestamp
: public base_date_extract
1008 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1010 param_validation(args
);
1012 result
->set_value( (int64_t)new_ptime
.date().year());
1017 struct _fn_extract_month_from_timestamp
: public base_date_extract
1019 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1021 param_validation(args
);
1023 result
->set_value( (int64_t)new_ptime
.date().month());
1028 struct _fn_extract_day_from_timestamp
: public base_date_extract
1030 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1032 param_validation(args
);
1034 result
->set_value( (int64_t)new_ptime
.date().day());
1039 struct _fn_extract_hour_from_timestamp
: public base_date_extract
1041 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1043 param_validation(args
);
1045 result
->set_value( (int64_t)new_ptime
.time_of_day().hours());
1050 struct _fn_extract_minute_from_timestamp
: public base_date_extract
1052 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1054 param_validation(args
);
1056 result
->set_value( (int64_t)new_ptime
.time_of_day().minutes());
1061 struct _fn_extract_second_from_timestamp
: public base_date_extract
1063 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1065 param_validation(args
);
1067 result
->set_value( (int64_t)new_ptime
.time_of_day().seconds());
1072 struct _fn_extract_week_from_timestamp
: public base_date_extract
1074 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1076 param_validation(args
);
1078 result
->set_value( (int64_t)new_ptime
.date().week_number());
1083 struct _fn_extract_tz_hour_from_timestamp
: public base_date_extract
1085 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1087 param_validation(args
);
1089 result
->set_value((int64_t)td
.hours());
1094 struct _fn_extract_tz_minute_from_timestamp
: public base_date_extract
1096 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1098 param_validation(args
);
1100 result
->set_value((int64_t)td
.minutes());
1105 struct _fn_diff_year_timestamp
: public base_date_diff
1107 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1109 param_validation(args
);
1111 int year1
= ptime1
.date().year();
1112 int year2
= ptime2
.date().year();
1113 boost::posix_time::time_duration time1
= boost::posix_time::time_duration(
1114 ptime1
.time_of_day().hours(), ptime1
.time_of_day().minutes(),
1115 ptime1
.time_of_day().seconds());
1116 boost::posix_time::time_duration time2
= boost::posix_time::time_duration(
1117 ptime2
.time_of_day().hours(), ptime2
.time_of_day().minutes(),
1118 ptime2
.time_of_day().seconds());
1120 if (year2
> year1
&& ((ptime2
.date().day_of_year() < ptime1
.date().day_of_year()) ||
1121 (ptime2
.date().day_of_year() == ptime1
.date().day_of_year() && time2
< time1
)))
1125 else if (year2
< year1
&& ((ptime2
.date().day_of_year() > ptime1
.date().day_of_year()) ||
1126 (ptime2
.date().day_of_year() == ptime1
.date().day_of_year() && time2
> time1
)))
1131 int64_t yr
= year2
- year1
;
1132 result
->set_value( yr
);
1137 struct _fn_diff_month_timestamp
: public base_date_diff
1139 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1141 param_validation(args
);
1143 int year1
= ptime1
.date().year();
1144 int year2
= ptime2
.date().year();
1145 int mon1
= ptime1
.date().month();
1146 int mon2
= ptime2
.date().month();
1147 boost::posix_time::time_duration time1
= boost::posix_time::time_duration(
1148 ptime1
.time_of_day().hours(), ptime1
.time_of_day().minutes(),
1149 ptime1
.time_of_day().seconds());
1150 boost::posix_time::time_duration time2
= boost::posix_time::time_duration(
1151 ptime2
.time_of_day().hours(), ptime2
.time_of_day().minutes(),
1152 ptime2
.time_of_day().seconds());
1156 if (ptime2
.date().day() < ptime1
.date().day() || (ptime2
.date().day() == ptime1
.date().day() && time2
< time1
))
1161 if (ptime2
.date().month() < ptime1
.date().month())
1167 else if (year2
< year1
)
1169 if (ptime2
.date().day() > ptime1
.date().day() || (ptime2
.date().day() == ptime1
.date().day() && time2
> time1
))
1174 if (ptime2
.date().month() > ptime1
.date().month())
1181 int64_t mon_diff
= (year2
- year1
) * 12 + mon2
- mon1
;
1183 result
->set_value(mon_diff
);
1188 struct _fn_diff_day_timestamp
: public base_date_diff
1190 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1192 param_validation(args
);
1194 boost::posix_time::time_duration td_res
= ptime2
- ptime1
;
1195 int total_seconds
= (((td_res
.hours() * 60) + td_res
.minutes()) * 60) + td_res
.seconds();
1196 int64_t days
= total_seconds
/ (24 * 3600);
1198 result
->set_value(days
);
1203 struct _fn_diff_hour_timestamp
: public base_date_diff
1205 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1207 param_validation(args
);
1209 boost::posix_time::time_duration td_res
= ptime2
- ptime1
;
1210 result
->set_value((int64_t)td_res
.hours());
1215 struct _fn_diff_minute_timestamp
: public base_date_diff
1217 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1219 param_validation(args
);
1221 boost::posix_time::time_duration td_res
= ptime2
- ptime1
;
1222 result
->set_value((int64_t)((td_res
.hours() * 60) + td_res
.minutes()));
1227 struct _fn_diff_second_timestamp
: public base_date_diff
1229 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1231 param_validation(args
);
1233 boost::posix_time::time_duration td_res
= ptime2
- ptime1
;
1234 result
->set_value((int64_t)((((td_res
.hours() * 60) + td_res
.minutes()) * 60) + td_res
.seconds()));
1239 struct _fn_add_year_to_timestamp
: public base_date_add
1241 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1243 param_validation(args
);
1245 new_ptime
+= boost::gregorian::years( val_quantity
.i64() );
1246 new_tmstmp
= std::make_tuple(new_ptime
, td
, flag
);
1247 result
->set_value( &new_tmstmp
);
1252 struct _fn_add_month_to_timestamp
: public base_date_add
1254 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1256 param_validation(args
);
1258 int yr
, mn
, dy
, quant
;
1259 quant
= val_quantity
.i64();
1260 dy
= new_ptime
.date().day();
1262 int temp
= quant
% 12;
1263 mn
= new_ptime
.date().month() + temp
;
1265 yr
= new_ptime
.date().year() + temp
;
1290 if ((mn
== 4 || mn
== 6 || mn
== 9 || mn
== 11) && dy
> 30)
1294 else if (mn
== 2 && dy
> 28)
1296 if (!(yr
% 4) == 0 || ((yr
% 100) == 0 && !(yr
% 400) == 0))
1306 #if BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
1307 new_ptime
= boost::posix_time::ptime(boost::gregorian::date(yr
, mn
, dy
),
1308 boost::posix_time::hours(new_ptime
.time_of_day().hours()) +
1309 boost::posix_time::minutes(new_ptime
.time_of_day().minutes()) +
1310 boost::posix_time::seconds(new_ptime
.time_of_day().seconds()) +
1311 boost::posix_time::nanoseconds(new_ptime
.time_of_day().fractional_seconds()));
1313 new_ptime
= boost::posix_time::ptime(boost::gregorian::date(yr
, mn
, dy
),
1314 boost::posix_time::hours(new_ptime
.time_of_day().hours()) +
1315 boost::posix_time::minutes(new_ptime
.time_of_day().minutes()) +
1316 boost::posix_time::seconds(new_ptime
.time_of_day().seconds()) +
1317 boost::posix_time::microseconds(new_ptime
.time_of_day().fractional_seconds()));
1320 new_tmstmp
= std::make_tuple(new_ptime
, td
, flag
);
1321 result
->set_value( &new_tmstmp
);
1326 struct _fn_add_day_to_timestamp
: public base_date_add
1328 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1330 param_validation(args
);
1332 new_ptime
+= boost::gregorian::days( val_quantity
.i64() );
1333 new_tmstmp
= std::make_tuple(new_ptime
, td
, flag
);
1334 result
->set_value( &new_tmstmp
);
1339 struct _fn_add_hour_to_timestamp
: public base_date_add
1341 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1343 param_validation(args
);
1345 new_ptime
+= boost::posix_time::hours( val_quantity
.i64() );
1346 new_tmstmp
= std::make_tuple(new_ptime
, td
, flag
);
1347 result
->set_value( &new_tmstmp
);
1352 struct _fn_add_minute_to_timestamp
: public base_date_add
1354 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1356 param_validation(args
);
1358 new_ptime
+= boost::posix_time::minutes( val_quantity
.i64() );
1359 new_tmstmp
= std::make_tuple(new_ptime
, td
, flag
);
1360 result
->set_value( &new_tmstmp
);
1365 struct _fn_add_second_to_timestamp
: public base_date_add
1367 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1369 param_validation(args
);
1371 new_ptime
+= boost::posix_time::seconds( val_quantity
.i64() );
1372 new_tmstmp
= std::make_tuple(new_ptime
, td
, flag
);
1373 result
->set_value( &new_tmstmp
);
1378 struct _fn_utcnow
: public base_function
1380 timestamp_t now_timestamp
;
1382 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1384 int args_size
= args
->size();
1388 throw base_s3select_exception("utcnow does not expect any parameters");
1391 boost::posix_time::ptime now_ptime
= boost::posix_time::ptime( boost::posix_time::second_clock::universal_time());
1392 now_timestamp
= std::make_tuple(now_ptime
, boost::posix_time::time_duration(0, 0, 0), false);
1393 result
->set_value( &now_timestamp
);
1399 struct _fn_between
: public base_function
1404 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1406 int args_size
= args
->size();
1411 throw base_s3select_exception("between operates on 3 expressions");//TODO FATAL
1414 auto iter
= args
->begin();
1416 base_statement
* second_expr
= *iter
;
1418 base_statement
* first_expr
= *iter
;
1420 base_statement
* main_expr
= *iter
;
1422 value second_expr_val
= second_expr
->eval();
1423 value first_expr_val
= first_expr
->eval();
1424 value main_expr_val
= main_expr
->eval();
1426 if ((second_expr_val
.type
== first_expr_val
.type
&& first_expr_val
.type
== main_expr_val
.type
) || (second_expr_val
.is_number() && first_expr_val
.is_number() && main_expr_val
.is_number()))
1428 if((main_expr_val
>= first_expr_val
) && (main_expr_val
<= second_expr_val
)) {
1429 result
->set_value(true);
1431 result
->set_value(false);
1438 struct _fn_not_between
: public base_function
1442 _fn_between between_op
;
1444 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1446 between_op(args
,result
);
1448 if (result
->get_value().is_true() == 0) {
1449 result
->set_value(true);
1451 result
->set_value(false);
1457 static char s3select_ver
[10]="41.a";
1459 struct _fn_version
: public base_function
1461 value val
; //TODO use git to generate sha1
1462 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1464 val
= &s3select_ver
[0];
1470 struct _fn_isnull
: public base_function
1475 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1477 auto iter
= args
->begin();
1478 base_statement
* expr
= *iter
;
1479 value expr_val
= expr
->eval();
1480 if ( expr_val
.is_null()) {
1481 result
->set_value(true);
1483 result
->set_value(false);
1489 struct _fn_is_not_null
: public base_function
1492 _fn_isnull isnull_op
;
1494 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1497 isnull_op(args
,result
);
1499 if (result
->get_value().is_true() == 0)
1500 result
->set_value(true);
1502 result
->set_value(false);
1508 struct _fn_in
: public base_function
1513 bool operator()(bs_stmt_vec_t
*args
, variable
*result
) override
1515 int args_size
= static_cast<int>(args
->size()-1);
1516 base_statement
*main_expr
= (*args
)[args_size
];
1517 value main_expr_val
= main_expr
->eval();
1519 while (args_size
>=0)
1521 base_statement
*expr
= (*args
)[args_size
];
1522 value expr_val
= expr
->eval();
1524 if ((expr_val
.type
== main_expr_val
.type
) || (expr_val
.is_number() && main_expr_val
.is_number()))
1526 if (expr_val
== main_expr_val
)
1528 result
->set_value(true);
1533 result
->set_value(false);
1538 struct _fn_like
: public base_like
1540 explicit _fn_like(base_statement
* esc
, base_statement
* like_expr
)
1542 auto is_constant
= [&](base_statement
* bs
) {
1543 if (dynamic_cast<variable
*>(bs
) && dynamic_cast<variable
*>(bs
)->m_var_type
== variable::var_t::COLUMN_VALUE
) {
1550 if (is_constant(esc
) && is_constant(like_expr
)) {
1551 constant_state
= true;
1554 if(constant_state
== true)
1556 param_validation(esc
, like_expr
);
1557 std::vector
<char> like_as_regex
= transform(like_expr_val
.str(), *escape_expr_val
.str());
1558 compile(like_as_regex
);
1562 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1564 auto iter
= args
->begin();
1566 base_statement
* escape_expr
= *iter
;
1568 base_statement
* like_expr
= *iter
;
1570 base_statement
* main_expr
= *iter
;
1572 if (constant_state
== false)
1574 param_validation(escape_expr
, like_expr
);
1575 std::vector
<char> like_as_regex
= transform(like_expr_val
.str(), *escape_expr_val
.str());
1576 compile(like_as_regex
);
1579 value main_expr_val
= main_expr
->eval();
1580 if (main_expr_val
.type
!= value::value_En_t::STRING
)
1582 throw base_s3select_exception("main expression must be string");
1585 match(main_expr_val
, result
);
1590 struct _fn_substr
: public base_function
1593 char buff
[4096];// this buffer is persist for the query life time, it use for the results per row(only for the specific function call)
1594 //it prevent from intensive use of malloc/free (fragmentation).
1595 //should validate result length.
1596 //TODO may replace by std::string (dynamic) , or to replace with global allocator , in query scope.
1601 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1603 auto iter
= args
->begin();
1604 int args_size
= args
->size();
1609 throw base_s3select_exception("substr accept 2 arguments or 3");
1612 base_statement
* str
= *iter
;
1614 base_statement
* from
= *iter
;
1622 if (!v_to
.is_number())
1624 throw base_s3select_exception("substr third argument must be number"); //can skip row
1628 v_str
= str
->eval();
1630 if(v_str
.type
!= value::value_En_t::STRING
)
1632 throw base_s3select_exception("substr first argument must be string"); //can skip current row
1635 int str_length
= strlen(v_str
.str());
1637 v_from
= from
->eval();
1638 if(!v_from
.is_number())
1640 throw base_s3select_exception("substr second argument must be number"); //can skip current row
1646 if (v_from
.type
== value::value_En_t::FLOAT
)
1655 if (f
<= 0 && args_size
== 2)
1662 result
->set_value("");
1666 if (str_length
>(int)sizeof(buff
))
1668 throw base_s3select_exception("string too long for internal buffer"); //can skip row
1673 if (v_to
.type
== value::value_En_t::FLOAT
)
1698 if( (str_length
-(f
-1)-t
) <0)
1699 {//in case the requested length is too long, reduce it to exact length.
1700 t
= str_length
-(f
-1);
1703 strncpy(buff
, v_str
.str()+f
-1, t
);
1707 strcpy(buff
, v_str
.str()+f
-1);
1710 result
->set_value(buff
);
1716 struct _fn_charlength
: public base_function
{
1720 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1722 auto iter
= args
->begin();
1723 base_statement
* str
= *iter
;
1724 v_str
= str
->eval();
1725 if(v_str
.type
!= value::value_En_t::STRING
) {
1726 throw base_s3select_exception("content is not string!");
1728 int64_t str_length
= strlen(v_str
.str());
1729 result
->set_value(str_length
);
1735 struct _fn_lower
: public base_function
{
1740 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1742 auto iter
= args
->begin();
1743 base_statement
* str
= *iter
;
1744 v_str
= str
->eval();
1745 if(v_str
.type
!= value::value_En_t::STRING
) {
1746 throw base_s3select_exception("content is not string");
1749 boost::algorithm::to_lower(buff
);
1750 result
->set_value(buff
.c_str());
1756 struct _fn_upper
: public base_function
{
1761 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1763 auto iter
= args
->begin();
1764 base_statement
* str
= *iter
;
1765 v_str
= str
->eval();
1766 if(v_str
.type
!= value::value_En_t::STRING
) {
1767 throw base_s3select_exception("content is not string");
1770 boost::algorithm::to_upper(buff
);
1771 result
->set_value(buff
.c_str());
1777 struct _fn_nullif
: public base_function
{
1782 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1784 auto iter
= args
->begin();
1786 int args_size
= args
->size();
1789 throw base_s3select_exception("nullif accept only 2 arguments");
1791 base_statement
*first
= *iter
;
1794 base_statement
*second
= *iter
;
1796 if (x
.is_null() && y
.is_null())
1806 if (!(x
.is_number() && y
.is_number())) {
1807 if (x
.type
!= y
.type
) {
1821 struct _fn_when_then
: public base_function
{
1825 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1827 auto iter
= args
->begin();
1829 base_statement
* then_expr
= *iter
;
1832 base_statement
* when_expr
= *iter
;
1834 when_value
= when_expr
->eval();
1836 if (when_value
.is_true())//true
1838 *result
= then_expr
->eval();
1848 struct _fn_when_value_then
: public base_function
{
1854 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1856 auto iter
= args
->begin();
1858 base_statement
* then_expr
= *iter
;
1861 base_statement
* when_expr
= *iter
;
1864 base_statement
* case_expr
= *iter
;
1866 when_value
= when_expr
->eval();
1867 case_value
= case_expr
->eval();
1868 then_value
= then_expr
->eval();
1870 if (case_value
== when_value
)
1872 *result
= then_value
;
1881 struct _fn_case_when_else
: public base_function
{
1883 value when_then_value
;
1885 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1887 base_statement
* else_expr
= *(args
->begin());
1889 size_t args_size
= args
->size() -1;
1891 for(int ivec
=args_size
;ivec
>0;ivec
--)
1893 when_then_value
= (*args
)[ivec
]->eval();
1895 if(!when_then_value
.is_null())
1897 *result
= when_then_value
;
1903 *result
= else_expr
->eval();
1908 struct _fn_coalesce
: public base_function
1913 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1915 auto iter_begin
= args
->begin();
1916 int args_size
= args
->size();
1917 while (args_size
>= 1)
1919 base_statement
* expr
= *iter_begin
;
1920 value expr_val
= expr
->eval();
1922 if ( !(expr_val
.is_null())) {
1933 struct _fn_string
: public base_function
1938 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1940 auto iter
= args
->begin();
1942 base_statement
* expr
= *iter
;
1943 value expr_val
= expr
->eval();
1944 result
->set_value((expr_val
.to_string()));
1949 struct _fn_to_bool
: public base_function
1954 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1957 func_arg
= (*args
->begin())->eval();
1959 if (func_arg
.type
== value::value_En_t::FLOAT
)
1963 else if (func_arg
.type
== value::value_En_t::DECIMAL
|| func_arg
.type
== value::value_En_t::BOOL
)
1973 result
->set_value(false);
1977 result
->set_value(true);
1983 struct _fn_trim
: public base_function
{
1985 std::string input_string
;
1994 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
1996 auto iter
= args
->begin();
1997 int args_size
= args
->size();
1998 base_statement
* str
= *iter
;
1999 v_input
= str
->eval();
2000 if(v_input
.type
!= value::value_En_t::STRING
) {
2001 throw base_s3select_exception("content is not string");
2003 input_string
= v_input
.str();
2004 if (args_size
== 2) {
2006 base_statement
* next
= *iter
;
2007 v_remove
= next
->eval();
2009 boost::trim_right_if(input_string
,boost::is_any_of(v_remove
.str()));
2010 boost::trim_left_if(input_string
,boost::is_any_of(v_remove
.str()));
2011 result
->set_value(input_string
.c_str());
2016 struct _fn_leading
: public base_function
{
2018 std::string input_string
;
2027 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
2029 auto iter
= args
->begin();
2030 int args_size
= args
->size();
2031 base_statement
* str
= *iter
;
2032 v_input
= str
->eval();
2033 if(v_input
.type
!= value::value_En_t::STRING
) {
2034 throw base_s3select_exception("content is not string");
2036 input_string
= v_input
.str();
2037 if (args_size
== 2) {
2039 base_statement
* next
= *iter
;
2040 v_remove
= next
->eval();
2042 boost::trim_left_if(input_string
,boost::is_any_of(v_remove
.str()));
2043 result
->set_value(input_string
.c_str());
2048 struct _fn_trailing
: public base_function
{
2050 std::string input_string
;
2059 bool operator()(bs_stmt_vec_t
* args
, variable
* result
) override
2061 auto iter
= args
->begin();
2062 int args_size
= args
->size();
2063 base_statement
* str
= *iter
;
2064 v_input
= str
->eval();
2065 if(v_input
.type
!= value::value_En_t::STRING
) {
2066 throw base_s3select_exception("content is not string");
2068 input_string
= v_input
.str();
2069 if (args_size
== 2) {
2071 base_statement
* next
= *iter
;
2072 v_remove
= next
->eval();
2074 boost::trim_right_if(input_string
,boost::is_any_of(v_remove
.str()));
2075 result
->set_value(input_string
.c_str());
2080 base_function
* s3select_functions::create(std::string_view fn_name
,const bs_stmt_vec_t
&arguments
)
2082 const FunctionLibrary::const_iterator iter
= m_functions_library
.find(fn_name
.data());
2084 if (iter
== m_functions_library
.end())
2087 msg
= std::string
{fn_name
} + " " + " function not found";
2088 throw base_s3select_exception(msg
, base_s3select_exception::s3select_exp_en_t::FATAL
);
2091 switch (iter
->second
)
2093 case s3select_func_En_t::ADD
:
2094 return S3SELECT_NEW(this,_fn_add
);
2097 case s3select_func_En_t::SUM
:
2098 return S3SELECT_NEW(this,_fn_sum
);
2101 case s3select_func_En_t::COUNT
:
2102 return S3SELECT_NEW(this,_fn_count
);
2105 case s3select_func_En_t::MIN
:
2106 return S3SELECT_NEW(this,_fn_min
);
2109 case s3select_func_En_t::MAX
:
2110 return S3SELECT_NEW(this,_fn_max
);
2113 case s3select_func_En_t::TO_INT
:
2114 return S3SELECT_NEW(this,_fn_to_int
);
2117 case s3select_func_En_t::TO_FLOAT
:
2118 return S3SELECT_NEW(this,_fn_to_float
);
2121 case s3select_func_En_t::SUBSTR
:
2122 return S3SELECT_NEW(this,_fn_substr
);
2125 case s3select_func_En_t::TO_TIMESTAMP
:
2126 return S3SELECT_NEW(this,_fn_to_timestamp
);
2129 case s3select_func_En_t::TO_STRING_CONSTANT
:
2130 return S3SELECT_NEW(this,_fn_to_string_constant
);
2133 case s3select_func_En_t::TO_STRING_DYNAMIC
:
2134 return S3SELECT_NEW(this,_fn_to_string_dynamic
);
2137 case s3select_func_En_t::TO_BOOL
:
2138 return S3SELECT_NEW(this,_fn_to_bool
);
2141 case s3select_func_En_t::EXTRACT_YEAR
:
2142 return S3SELECT_NEW(this,_fn_extract_year_from_timestamp
);
2145 case s3select_func_En_t::EXTRACT_MONTH
:
2146 return S3SELECT_NEW(this,_fn_extract_month_from_timestamp
);
2149 case s3select_func_En_t::EXTRACT_DAY
:
2150 return S3SELECT_NEW(this,_fn_extract_day_from_timestamp
);
2153 case s3select_func_En_t::EXTRACT_HOUR
:
2154 return S3SELECT_NEW(this,_fn_extract_hour_from_timestamp
);
2157 case s3select_func_En_t::EXTRACT_MINUTE
:
2158 return S3SELECT_NEW(this,_fn_extract_minute_from_timestamp
);
2161 case s3select_func_En_t::EXTRACT_SECOND
:
2162 return S3SELECT_NEW(this,_fn_extract_second_from_timestamp
);
2165 case s3select_func_En_t::EXTRACT_WEEK
:
2166 return S3SELECT_NEW(this,_fn_extract_week_from_timestamp
);
2169 case s3select_func_En_t::EXTRACT_TIMEZONE_HOUR
:
2170 return S3SELECT_NEW(this,_fn_extract_tz_hour_from_timestamp
);
2173 case s3select_func_En_t::EXTRACT_TIMEZONE_MINUTE
:
2174 return S3SELECT_NEW(this,_fn_extract_tz_minute_from_timestamp
);
2177 case s3select_func_En_t::DATE_ADD_YEAR
:
2178 return S3SELECT_NEW(this,_fn_add_year_to_timestamp
);
2181 case s3select_func_En_t::DATE_ADD_MONTH
:
2182 return S3SELECT_NEW(this,_fn_add_month_to_timestamp
);
2185 case s3select_func_En_t::DATE_ADD_DAY
:
2186 return S3SELECT_NEW(this,_fn_add_day_to_timestamp
);
2189 case s3select_func_En_t::DATE_ADD_HOUR
:
2190 return S3SELECT_NEW(this,_fn_add_hour_to_timestamp
);
2193 case s3select_func_En_t::DATE_ADD_MINUTE
:
2194 return S3SELECT_NEW(this,_fn_add_minute_to_timestamp
);
2197 case s3select_func_En_t::DATE_ADD_SECOND
:
2198 return S3SELECT_NEW(this,_fn_add_second_to_timestamp
);
2201 case s3select_func_En_t::DATE_DIFF_YEAR
:
2202 return S3SELECT_NEW(this,_fn_diff_year_timestamp
);
2205 case s3select_func_En_t::DATE_DIFF_MONTH
:
2206 return S3SELECT_NEW(this,_fn_diff_month_timestamp
);
2209 case s3select_func_En_t::DATE_DIFF_DAY
:
2210 return S3SELECT_NEW(this,_fn_diff_day_timestamp
);
2213 case s3select_func_En_t::DATE_DIFF_HOUR
:
2214 return S3SELECT_NEW(this,_fn_diff_hour_timestamp
);
2217 case s3select_func_En_t::DATE_DIFF_MINUTE
:
2218 return S3SELECT_NEW(this,_fn_diff_minute_timestamp
);
2221 case s3select_func_En_t::DATE_DIFF_SECOND
:
2222 return S3SELECT_NEW(this,_fn_diff_second_timestamp
);
2225 case s3select_func_En_t::UTCNOW
:
2226 return S3SELECT_NEW(this,_fn_utcnow
);
2229 case s3select_func_En_t::AVG
:
2230 return S3SELECT_NEW(this,_fn_avg
);
2233 case s3select_func_En_t::LOWER
:
2234 return S3SELECT_NEW(this,_fn_lower
);
2237 case s3select_func_En_t::UPPER
:
2238 return S3SELECT_NEW(this,_fn_upper
);
2241 case s3select_func_En_t::LENGTH
:
2242 return S3SELECT_NEW(this,_fn_charlength
);
2245 case s3select_func_En_t::BETWEEN
:
2246 return S3SELECT_NEW(this,_fn_between
);
2249 case s3select_func_En_t::NOT_BETWEEN
:
2250 return S3SELECT_NEW(this,_fn_not_between
);
2253 case s3select_func_En_t::IS_NULL
:
2254 return S3SELECT_NEW(this,_fn_isnull
);
2257 case s3select_func_En_t::IS_NOT_NULL
:
2258 return S3SELECT_NEW(this,_fn_is_not_null
);
2261 case s3select_func_En_t::IN
:
2262 return S3SELECT_NEW(this,_fn_in
);
2265 case s3select_func_En_t::VERSION
:
2266 return S3SELECT_NEW(this,_fn_version
);
2269 case s3select_func_En_t::NULLIF
:
2270 return S3SELECT_NEW(this,_fn_nullif
);
2273 case s3select_func_En_t::LIKE
:
2274 return S3SELECT_NEW(this,_fn_like
,arguments
[0],arguments
[1]);
2277 case s3select_func_En_t::COALESCE
:
2278 return S3SELECT_NEW(this,_fn_coalesce
);
2281 case s3select_func_En_t::WHEN_THEN
:
2282 return S3SELECT_NEW(this,_fn_when_then
);
2285 case s3select_func_En_t::WHEN_VALUE_THEN
:
2286 return S3SELECT_NEW(this,_fn_when_value_then
);
2289 case s3select_func_En_t::CASE_WHEN_ELSE
:
2290 return S3SELECT_NEW(this,_fn_case_when_else
);
2293 case s3select_func_En_t::STRING
:
2294 return S3SELECT_NEW(this,_fn_string
);
2297 case s3select_func_En_t::TRIM
:
2298 return S3SELECT_NEW(this,_fn_trim
);
2301 case s3select_func_En_t::LEADING
:
2302 return S3SELECT_NEW(this,_fn_leading
);
2305 case s3select_func_En_t::TRAILING
:
2306 return S3SELECT_NEW(this,_fn_trailing
);
2310 throw base_s3select_exception("internal error while resolving function-name");
2315 bool base_statement::is_function() const
2317 if (dynamic_cast<__function
*>(const_cast<base_statement
*>(this)))
2327 const base_statement
* base_statement::get_aggregate() const
2329 //search for aggregation function in AST
2330 const base_statement
* res
= 0;
2337 if (left() && (res
=left()->get_aggregate())!=0)
2342 if (right() && (res
=right()->get_aggregate())!=0)
2349 for (auto i
: dynamic_cast<__function
*>(const_cast<base_statement
*>(this))->get_arguments())
2351 const base_statement
* b
=i
->get_aggregate();
2361 bool base_statement::is_column_reference() const
2367 return left()->is_column_reference();
2370 return right()->is_column_reference();
2374 for(auto a
: dynamic_cast<__function
*>(const_cast<base_statement
*>(this))->get_arguments())
2376 if(a
->is_column_reference())
2384 bool base_statement::is_nested_aggregate(bool &aggr_flow
) const
2389 for (auto& i
: dynamic_cast<__function
*>(const_cast<base_statement
*>(this))->get_arguments())
2391 if (i
->get_aggregate() != nullptr)
2398 if(left() && left()->is_nested_aggregate(aggr_flow
))
2401 if(right() && right()->is_nested_aggregate(aggr_flow
))
2406 for (auto& i
: dynamic_cast<__function
*>(const_cast<base_statement
*>(this))->get_arguments())
2408 if (i
->get_aggregate() != nullptr)
2410 return i
->is_nested_aggregate(aggr_flow
);
2418 bool base_statement::is_statement_contain_star_operation() const
2420 if(is_star_operation())
2424 return left()->is_statement_contain_star_operation();
2427 return right()->is_statement_contain_star_operation();
2431 for(auto a
: dynamic_cast<__function
*>(const_cast<base_statement
*>(this))->get_arguments())
2433 if(a
->is_star_operation())
2441 bool base_statement::mark_aggreagtion_subtree_to_execute()
2442 {//purpase:: set aggregation subtree as runnable.
2443 //the function search for aggregation function, and mark its subtree {skip = false}
2445 set_skip_non_aggregate(false);
2448 left()->mark_aggreagtion_subtree_to_execute();
2451 right()->mark_aggreagtion_subtree_to_execute();
2455 for (auto& i
: dynamic_cast<__function
*>(this)->get_arguments())
2457 i
->mark_aggreagtion_subtree_to_execute();
2464 void base_statement::push_for_cleanup(std::set
<base_statement
*>& ast_nodes_to_delete
)//semantic loop on each projection
2466 //placement new is releasing the main-buffer in which all AST nodes
2467 //allocating from it. meaning no calls to destructors.
2468 //the purpose of this routine is to traverse the AST in map all nodes for cleanup.
2469 //the cleanup method will trigger all destructors.
2471 ast_nodes_to_delete
.insert(this);
2474 left()->push_for_cleanup(ast_nodes_to_delete
);
2477 right()->push_for_cleanup(ast_nodes_to_delete
);
2481 for (auto& i
: dynamic_cast<__function
*>(this)->get_arguments())
2483 i
->push_for_cleanup(ast_nodes_to_delete
);
2489 void base_statement::extract_columns(parquet_file_parser::column_pos_t
&cols
,const uint16_t max_columns
)
2490 {// purpose: to extract all column-ids from query
2491 if(is_column()) //column reference or column position
2492 {variable
* v
= dynamic_cast<variable
*>(this);
2493 if(dynamic_cast<variable
*>(this)->m_var_type
== variable::var_t::VARIABLE_NAME
)
2496 if (v
->getScratchArea()->get_column_pos(v
->get_name().c_str())>=0)
2497 {//column belong to schema
2498 cols
.insert( v
->getScratchArea()->get_column_pos(v
->get_name().c_str() ));
2500 if(v
->getAlias()->search_alias(v
->get_name()))
2501 {//column is an alias --> extract columns belong to alias
2502 //TODO cyclic alias to resolve
2503 v
->getAlias()->search_alias(v
->get_name())->extract_columns(cols
,max_columns
);
2505 //column is not alias --> error
2506 std::stringstream ss
;
2507 ss
<< "column " + v
->get_name() + " is not part of schema nor an alias";
2508 throw base_s3select_exception(ss
.str(),base_s3select_exception::s3select_exp_en_t::FATAL
);
2511 }else if(v
->m_var_type
== variable::var_t::STAR_OPERATION
)
2513 for(uint16_t i
=0;i
<max_columns
;i
++)
2519 if (v
->get_column_pos()>=max_columns
)
2521 std::stringstream ss
;
2522 ss
<< "column " + std::to_string( v
->get_column_pos()+1 ) + " exceed max number of columns";
2523 throw base_s3select_exception(ss
.str(),base_s3select_exception::s3select_exp_en_t::FATAL
);
2525 cols
.insert(v
->get_column_pos());//push column positions
2527 }else if(is_function())
2529 __function
* f
= (dynamic_cast<__function
*>(this));
2530 bs_stmt_vec_t args
= f
->get_arguments();
2531 for (auto prm
: args
)
2532 {//traverse function args
2533 prm
->extract_columns(cols
,max_columns
);
2538 //keep traversing down the AST
2540 left()->extract_columns(cols
,max_columns
);
2543 right()->extract_columns(cols
,max_columns
);
2545 #endif //_ARROW_EXIST
2547 } //namespace s3selectEngine