Skip to content

Commit 409b6d5

Browse files
authored
Implementation of to_string datetime function (#55)
* Implementation of to_string datetime function Converts given timestamp into given string format. And added test for the same. Signed-off-by: Girjesh Rajoria <grajoria@redhat.com> * Multirow test for datetime to_string function Added multirow test for to_string function which cover both cases i.e., where format is constant and dynamic expression. Signed-off-by: Girjesh Rajoria <grajoria@redhat.com>
1 parent 1d2a67c commit 409b6d5

File tree

4 files changed

+591
-2
lines changed

4 files changed

+591
-2
lines changed

include/s3select.h

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,18 @@ struct push_date_part : public base_ast_builder
370370
};
371371
static push_date_part g_push_date_part;
372372

373+
struct push_time_to_string_constant : public base_ast_builder
374+
{
375+
void builder(s3select* self, const char* a, const char* b) const;
376+
};
377+
static push_time_to_string_constant g_push_time_to_string_constant;
378+
379+
struct push_time_to_string_dynamic : public base_ast_builder
380+
{
381+
void builder(s3select* self, const char* a, const char* b) const;
382+
};
383+
static push_time_to_string_dynamic g_push_time_to_string_dynamic;
384+
373385
struct s3select : public bsc::grammar<s3select>
374386
{
375387
private:
@@ -622,7 +634,7 @@ struct s3select : public bsc::grammar<s3select>
622634
function = ((variable >> '(' )[BOOST_BIND_ACTION(push_function_name)] >> !list_of_function_arguments >> ')')[BOOST_BIND_ACTION(push_function_expr)];
623635

624636
arithmetic_argument = (float_number)[BOOST_BIND_ACTION(push_float_number)] | (number)[BOOST_BIND_ACTION(push_number)] | (column_pos)[BOOST_BIND_ACTION(push_column_pos)] |
625-
(string)[BOOST_BIND_ACTION(push_string)] | (datediff) | (dateadd) | (extract) |
637+
(string)[BOOST_BIND_ACTION(push_string)] | (datediff) | (dateadd) | (extract) | (time_to_string_constant) | (time_to_string_dynamic) |
626638
(cast) | (substr) | (trim) |
627639
(function) | (variable)[BOOST_BIND_ACTION(push_variable)]; //function is pushed by right-term
628640

@@ -658,6 +670,10 @@ struct s3select : public bsc::grammar<s3select>
658670

659671
date_part_extract = ((date_part) | bsc::str_p("week"));
660672

673+
time_to_string_constant = (bsc::str_p("to_string") >> '(' >> arithmetic_expression >> ',' >> (string)[BOOST_BIND_ACTION(push_string)] >> ')') [BOOST_BIND_ACTION(push_time_to_string_constant)];
674+
675+
time_to_string_dynamic = (bsc::str_p("to_string") >> '(' >> arithmetic_expression >> ',' >> arithmetic_expression >> ')') [BOOST_BIND_ACTION(push_time_to_string_dynamic)];
676+
661677
number = bsc::int_p;
662678

663679
float_number = bsc::real_p;
@@ -683,7 +699,7 @@ struct s3select : public bsc::grammar<s3select>
683699
bsc::rule<ScannerT> cast, data_type, variable, select_expr, s3_object, where_clause, number, float_number, string;
684700
bsc::rule<ScannerT> cmp_operand, arith_cmp, condition_expression, arithmetic_predicate, logical_predicate, factor;
685701
bsc::rule<ScannerT> trim, trim_whitespace_both, trim_one_side_whitespace, trim_anychar_anyside, trim_type, trim_remove_type, substr, substr_from, substr_from_for;
686-
bsc::rule<ScannerT> datediff, dateadd, extract, date_part, date_part_extract;
702+
bsc::rule<ScannerT> datediff, dateadd, extract, date_part, date_part_extract, time_to_string_constant, time_to_string_dynamic;
687703
bsc::rule<ScannerT> special_predicates, between_predicate, in_predicate, like_predicate, is_null, is_not_null;
688704
bsc::rule<ScannerT> muldiv_operator, addsubop_operator, function, arithmetic_expression, addsub_operand, list_of_function_arguments, arithmetic_argument, mulldiv_operand;
689705
bsc::rule<ScannerT> fs_type, object_path;
@@ -1568,6 +1584,43 @@ void push_date_part::builder(s3select* self, const char* a, const char* b) const
15681584
self->getAction()->datePartQ.push_back(token);
15691585
}
15701586

1587+
void push_time_to_string_constant::builder(s3select* self, const char* a, const char* b) const
1588+
{
1589+
std::string token(a, b);
1590+
1591+
__function* func = S3SELECT_NEW(self, __function, "#to_string_constant#", self->getS3F());
1592+
1593+
base_statement* expr = self->getAction()->exprQ.back();
1594+
self->getAction()->exprQ.pop_back();
1595+
1596+
base_statement* frmt = self->getAction()->exprQ.back();
1597+
self->getAction()->exprQ.pop_back();
1598+
1599+
func->push_argument(frmt);
1600+
func->push_argument(expr);
1601+
1602+
self->getAction()->exprQ.push_back(func);
1603+
1604+
}
1605+
1606+
void push_time_to_string_dynamic::builder(s3select* self, const char* a, const char* b) const
1607+
{
1608+
std::string token(a, b);
1609+
1610+
__function* func = S3SELECT_NEW(self, __function, "#to_string_dynamic#", self->getS3F());
1611+
1612+
base_statement* expr = self->getAction()->exprQ.back();
1613+
self->getAction()->exprQ.pop_back();
1614+
1615+
base_statement* frmt = self->getAction()->exprQ.back();
1616+
self->getAction()->exprQ.pop_back();
1617+
1618+
func->push_argument(frmt);
1619+
func->push_argument(expr);
1620+
1621+
self->getAction()->exprQ.push_back(func);
1622+
}
1623+
15711624
/////// handling different object types
15721625
class base_s3object
15731626
{

include/s3select_functions.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <boost/algorithm/string.hpp>
77
#include <boost/algorithm/string/trim.hpp>
88
#include <regex>
9+
#include <boost/regex.hpp>
910

1011
using namespace std::string_literals;
1112

@@ -82,6 +83,8 @@ enum class s3select_func_En_t {ADD,
8283
TO_INT,
8384
TO_FLOAT,
8485
TO_TIMESTAMP,
86+
TO_STRING_CONSTANT,
87+
TO_STRING_DYNAMIC,
8588
TO_BOOL,
8689
SUBSTR,
8790
EXTRACT_YEAR,
@@ -146,6 +149,8 @@ class s3select_functions
146149
{"float", s3select_func_En_t::TO_FLOAT},
147150
{"substring", s3select_func_En_t::SUBSTR},
148151
{"to_timestamp", s3select_func_En_t::TO_TIMESTAMP},
152+
{"#to_string_constant#",s3select_func_En_t::TO_STRING_CONSTANT},
153+
{"#to_string_dynamic#",s3select_func_En_t::TO_STRING_DYNAMIC},
149154
{"to_bool", s3select_func_En_t::TO_BOOL},
150155
{"#extract_year#", s3select_func_En_t::EXTRACT_YEAR},
151156
{"#extract_month#", s3select_func_En_t::EXTRACT_MONTH},
@@ -820,6 +825,43 @@ struct _fn_to_timestamp : public base_function
820825

821826
};
822827

828+
struct _fn_to_string_constant : public base_timestamp_to_string
829+
{
830+
bool operator()(bs_stmt_vec_t* args, variable* result) override
831+
{
832+
param_validation(args);
833+
834+
if (!initialized)
835+
{
836+
prepare_to_string_vector(print_vector, para);
837+
initialized = true;
838+
}
839+
840+
std::string result_ = execute_to_string(print_vector, para);
841+
842+
result->set_value(result_.c_str());
843+
return true;
844+
}
845+
};
846+
847+
struct _fn_to_string_dynamic : public base_timestamp_to_string
848+
{
849+
bool operator()(bs_stmt_vec_t* args, variable* result) override
850+
{
851+
param_validation(args);
852+
853+
print_vector.clear();
854+
para.clear();
855+
856+
prepare_to_string_vector(print_vector, para);
857+
858+
std::string result_ = execute_to_string(print_vector, para);
859+
860+
result->set_value(result_.c_str());
861+
return true;
862+
}
863+
};
864+
823865
struct _fn_extract_year_from_timestamp : public base_date_extract
824866
{
825867
bool operator()(bs_stmt_vec_t* args, variable* result) override
@@ -1801,6 +1843,14 @@ base_function* s3select_functions::create(std::string_view fn_name,const bs_stmt
18011843
return S3SELECT_NEW(this,_fn_to_timestamp);
18021844
break;
18031845

1846+
case s3select_func_En_t::TO_STRING_CONSTANT:
1847+
return S3SELECT_NEW(this,_fn_to_string_constant);
1848+
break;
1849+
1850+
case s3select_func_En_t::TO_STRING_DYNAMIC:
1851+
return S3SELECT_NEW(this,_fn_to_string_dynamic);
1852+
break;
1853+
18041854
case s3select_func_En_t::TO_BOOL:
18051855
return S3SELECT_NEW(this,_fn_to_bool);
18061856
break;

0 commit comments

Comments
 (0)