diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-23 16:45:17 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-23 16:45:44 +0000 |
commit | 17d6a993fc17d533460c5f40f3908c708e057c18 (patch) | |
tree | 1a3bd93e0ecd74fa02f93a528fe2f87e5314c4b5 /src/s3select/include/s3select_functions.h | |
parent | Releasing progress-linux version 18.2.2-0progress7.99u1. (diff) | |
download | ceph-17d6a993fc17d533460c5f40f3908c708e057c18.tar.xz ceph-17d6a993fc17d533460c5f40f3908c708e057c18.zip |
Merging upstream version 18.2.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/s3select/include/s3select_functions.h')
-rw-r--r-- | src/s3select/include/s3select_functions.h | 110 |
1 files changed, 90 insertions, 20 deletions
diff --git a/src/s3select/include/s3select_functions.h b/src/s3select/include/s3select_functions.h index 8c507fca1..4d88d772e 100644 --- a/src/s3select/include/s3select_functions.h +++ b/src/s3select/include/s3select_functions.h @@ -350,6 +350,7 @@ private: s3select_functions* m_s3select_functions; variable m_result; bool m_is_aggregate_function; + value eval_result; void _resolve_name() { @@ -437,14 +438,28 @@ public: {//all rows prior to last row if(m_skip_non_aggregate_op == false || is_aggregate() == true) { - (*m_func_impl)(&arguments, &m_result); + try { + (*m_func_impl)(&arguments, &m_result); + } + catch(std::exception& e) + { + std::string error_msg = "[" + m_func_impl->m_function_name + " failed : " + std::string(e.what()) + "]"; + throw base_s3select_exception(error_msg.data(), base_s3select_exception::s3select_exp_en_t::FATAL); + } } else if(m_skip_non_aggregate_op == true) { for(auto& p : arguments) {//evaluating the arguments (not the function itself, which is a non-aggregate function) //i.e. in the following use case substring( , sum(),count() ) ; only sum() and count() are evaluated. - p->eval(); + try { + p->eval(); + } + catch(std::exception& e) + { + std::string error_msg = m_func_impl->m_function_name + " failed : " + std::string(e.what()); + throw base_s3select_exception(error_msg.data(), base_s3select_exception::s3select_exp_en_t::FATAL); + } } } } @@ -452,9 +467,27 @@ public: {//on the last row, the aggregate function is finalized, //and non-aggregate function is evaluated with the result of aggregate function. if(is_aggregate()) - (*m_func_impl).get_aggregate_result(&m_result); + { + try{ + (*m_func_impl).get_aggregate_result(&m_result); + } + catch(std::exception& e) + { + std::string error_msg = m_func_impl->m_function_name + " failed : " + std::string(e.what()); + throw base_s3select_exception(error_msg.data(), base_s3select_exception::s3select_exp_en_t::FATAL); + } + } else - (*m_func_impl)(&arguments, &m_result); + { + try{ + (*m_func_impl)(&arguments, &m_result); + } + catch(std::exception& e) + { + std::string error_msg = m_func_impl->m_function_name + " failed : " + std::string(e.what()); + throw base_s3select_exception(error_msg.data(), base_s3select_exception::s3select_exp_en_t::FATAL); + } + } } return m_result.get_value(); @@ -736,6 +769,10 @@ struct _fn_to_int : public base_function var_result = static_cast<int64_t>(v.dbl()); break; + case value::value_En_t::S3NULL: + var_result.setnull(); + break; + default: var_result = v.i64(); break; @@ -782,6 +819,10 @@ struct _fn_to_float : public base_function var_result = v.dbl(); break; + case value::value_En_t::S3NULL: + var_result.setnull(); + break; + default: var_result = v.i64(); break; @@ -2017,6 +2058,11 @@ struct _fn_to_bool : public base_function { i = func_arg.i64(); } + else if (func_arg.type == value::value_En_t::S3NULL) + { + result->set_null(); + return true; + } else { i = 0; @@ -2035,12 +2081,14 @@ struct _fn_to_bool : public base_function struct _fn_trim : public base_function { + //TODO base function trim std::string input_string; value v_remove; value v_input; _fn_trim() { + //default character to remove is blank v_remove = " "; } @@ -2053,13 +2101,16 @@ struct _fn_trim : public base_function { base_statement* str = *iter; v_input = str->eval(); if(v_input.type != value::value_En_t::STRING) { - throw base_s3select_exception("content is not string"); + throw base_s3select_exception("content type is not a string"); } input_string = v_input.str(); if (args_size == 2) { iter++; base_statement* next = *iter; v_remove = next->eval(); + if(v_remove.type != value::value_En_t::STRING) { + throw base_s3select_exception("remove type is not a string"); + } } boost::trim_right_if(input_string,boost::is_any_of(v_remove.str())); boost::trim_left_if(input_string,boost::is_any_of(v_remove.str())); @@ -2069,13 +2120,13 @@ struct _fn_trim : public base_function { }; struct _fn_leading : public base_function { - std::string input_string; value v_remove; value v_input; _fn_leading() { + //default character to remove is blank v_remove = " "; } @@ -2088,13 +2139,16 @@ struct _fn_leading : public base_function { base_statement* str = *iter; v_input = str->eval(); if(v_input.type != value::value_En_t::STRING) { - throw base_s3select_exception("content is not string"); + throw base_s3select_exception("content type is not a string"); } input_string = v_input.str(); if (args_size == 2) { iter++; base_statement* next = *iter; v_remove = next->eval(); + if(v_remove.type != value::value_En_t::STRING) { + throw base_s3select_exception("remove type is not a string"); + } } boost::trim_left_if(input_string,boost::is_any_of(v_remove.str())); result->set_value(input_string.c_str()); @@ -2110,6 +2164,7 @@ struct _fn_trailing : public base_function { _fn_trailing() { + //default character to remove is blank v_remove = " "; } @@ -2122,13 +2177,16 @@ struct _fn_trailing : public base_function { base_statement* str = *iter; v_input = str->eval(); if(v_input.type != value::value_En_t::STRING) { - throw base_s3select_exception("content is not string"); + throw base_s3select_exception("content type is not a string"); } input_string = v_input.str(); if (args_size == 2) { iter++; base_statement* next = *iter; v_remove = next->eval(); + if(v_remove.type != value::value_En_t::STRING) { + throw base_s3select_exception("remove type is not a string"); + } } boost::trim_right_if(input_string,boost::is_any_of(v_remove.str())); result->set_value(input_string.c_str()); @@ -2183,7 +2241,8 @@ struct _fn_decimal_operator : public base_function { iter++; base_statement* expr_scale = *iter; value expr_scale_val = expr_scale->eval(); - + + //parser does the type checking precision = expr_precision_val.i64(); scale = expr_scale_val.i64(); @@ -2195,20 +2254,20 @@ struct _fn_decimal_operator : public base_function { struct _fn_engine_version : public base_function { - const char* version_description =R"(PR #137 : -the change handle the use cases where the JSON input starts with an anonymous array/object this may cause wrong search result per the user request(SQL statement) - -handle the use-case where the user requests a json-key-path that may point to a non-discrete value. i.e. array or an object. -editorial changes. - -fix for CSV flow, in the case of a "broken row" (upon processing stream of data) - -null results upon aggregation functions on an empty group (no match for where clause). + const char* version_description =R"( +-- trim operator: case insensitive #140 +-- add exception handling to avoid crashes, and produce informative messages instead #141 +-- case-insensitive in the case of is null or is not null predicates. #141 +-- a fix for missing check-type, which cause a crash(trim operator) #142 +-- cast null operations returned false instead of null. #143 +-- adding another way to generate TPCDS data, this method is faster and efficient, it launches multiple instances of data-generators and uses less disk space #145 +-- the scripts use the dsdgen application resides on https://github.com/galsalomon66/tpc-ds-datagen-to-aws-s3 +the whole system resides in a container [ docker pull galsl/fedora_38:tpcds_v2 ] #146 +-- upon logical_operand(and/or) the parser-builder does not use case-insensitive compare function, resulting in wrong evaluation #147 )"; - _fn_engine_version() - { + {//it means it will return a single result line, in case of multi-rows input object aggregate = true; } @@ -2535,6 +2594,17 @@ bool base_statement::is_column_reference() const return false; } +std::string base_statement::get_key_from_projection() +{ + variable* v_name = dynamic_cast<variable*>(this); + + if(v_name) { + return v_name->get_name(); + } else { + throw base_s3select_exception("key not present"); + } +} + bool base_statement::is_nested_aggregate(bool &aggr_flow) const { if (is_aggregate()) |