From 65abc2fd070065c14121f72585893ca9abd78ce0 Mon Sep 17 00:00:00 2001 From: VaclavT Date: Tue, 8 Mar 2022 17:48:14 +0100 Subject: [PATCH] usql update --- usql/parser.cpp | 8 ++++---- usql/parser.h | 7 +++++-- usql/usql.cpp | 3 +++ usql/usql.h | 1 + usql/usql_dml.cpp | 7 +++++++ usql/usql_function.cpp | 27 ++++++++++++++++++++++----- 6 files changed, 42 insertions(+), 11 deletions(-) diff --git a/usql/parser.cpp b/usql/parser.cpp index 32d55ef..b5682d7 100644 --- a/usql/parser.cpp +++ b/usql/parser.cpp @@ -7,12 +7,12 @@ namespace usql { std::string column_type_name(const ColumnType type) { if (type == ColumnType::integer_type) return "integer_type"; - if (type == ColumnType::float_type) return "float_type"; + if (type == ColumnType::float_type) return "float_type"; if (type == ColumnType::varchar_type) return "varchar_type"; - if (type == ColumnType::date_type) return "date_type"; - if (type == ColumnType::bool_type) return "bool_type"; + if (type == ColumnType::date_type) return "date_type"; + if (type == ColumnType::bool_type) return "bool_type"; - throw Exception("invalid column type: " + (int)type); + throw Exception("invalid column type: " + std::to_string((int)type)); }; diff --git a/usql/parser.h b/usql/parser.h index f100c32..b7efea5 100644 --- a/usql/parser.h +++ b/usql/parser.h @@ -132,6 +132,7 @@ struct FunctionNode : Node { pp, lower, upper, + coalesce, min, max, count @@ -144,6 +145,7 @@ struct FunctionNode : Node { if (str=="pp") return Type::pp; if (str=="lower") return Type::lower; if (str=="upper") return Type::upper; + if (str=="coalesce") return Type::coalesce; if (str=="min") return Type::min; if (str=="max") return Type::max; if (str=="count") return Type::count; @@ -158,15 +160,16 @@ struct FunctionNode : Node { if (type == Type::pp) return "pp"; if (type == Type::lower) return "lower"; if (type == Type::upper) return "upper"; + if (type == Type::coalesce) return "coalesce"; if (type == Type::min) return "min"; if (type == Type::max) return "max"; if (type == Type::count) return "count"; - throw Exception("invalid function: " + (int)type); + throw Exception("invalid function: " + std::to_string((int)type)); }; - Type function; + Type function; std::vector> params; FunctionNode(std::string func_name, std::vector> pars) : diff --git a/usql/usql.cpp b/usql/usql.cpp index 1c634a9..e827c4b 100644 --- a/usql/usql.cpp +++ b/usql/usql.cpp @@ -173,6 +173,9 @@ std::unique_ptr USql::eval_function_value_node(Table *table, Row &row evaluatedPars.push_back(eval_value_node(table, row, param.get(), nullptr, nullptr)); } + // coalesce function can have first parameter null, so must be calles before following "return null" + if (fnc->function == FunctionNode::Type::coalesce) return coalesce_function(evaluatedPars); + if (evaluatedPars.empty() || evaluatedPars[0]->isNull()) return std::make_unique(); diff --git a/usql/usql.h b/usql/usql.h index 17a9ee3..d8f9383 100644 --- a/usql/usql.h +++ b/usql/usql.h @@ -73,6 +73,7 @@ private: static std::unique_ptr lower_function(const std::vector> &evaluatedPars); static std::unique_ptr upper_function(const std::vector> &evaluatedPars); + static std::unique_ptr coalesce_function(const std::vector> &evaluatedPars); static std::unique_ptr to_date_function(const std::vector> &evaluatedPars); static std::unique_ptr to_string_function(const std::vector> &evaluatedPars); static std::unique_ptr date_add_function(const std::vector> &evaluatedPars); diff --git a/usql/usql_dml.cpp b/usql/usql_dml.cpp index cb79699..f259687 100644 --- a/usql/usql_dml.cpp +++ b/usql/usql_dml.cpp @@ -239,6 +239,13 @@ std::tuple USql::get_node_definition(Table *table, Node * node, // TODO get length, use get_db_column_definition ColDefNode col_def = ColDefNode{col_name, ColumnType::varchar_type, col_order, 256, true}; return std::make_tuple(FUNCTION_CALL, col_def); + } else if (func_node->function == FunctionNode::Type::coalesce) { + // TODO handle cases here + if (func_node->params.empty()) throw Exception("Coalesce without parameters"); + if (func_node->params[0]->node_type != NodeType::database_value) throw Exception("Coalesce first parameter must be database column"); + ColDefNode tbl_col_def = get_db_column_definition(table, func_node->params[0].get()); + ColDefNode col_def = ColDefNode{col_name, tbl_col_def.type, col_order, tbl_col_def.length, true}; + return std::make_tuple(FUNCTION_CALL, col_def); } else if (func_node->function == FunctionNode::Type::min || func_node->function == FunctionNode::Type::max) { auto col_type= ColumnType::float_type; size_t col_len = 1; diff --git a/usql/usql_function.cpp b/usql/usql_function.cpp index 1d7b3e6..11ec866 100644 --- a/usql/usql_function.cpp +++ b/usql/usql_function.cpp @@ -34,6 +34,13 @@ std::unique_ptr USql::date_add_function(const std::vector USql::lower_function(const std::vector> &evaluatedPars) { + std::string str = evaluatedPars[0]->getStringValue(); + std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c) -> unsigned char { return tolower(c); }); + + return std::make_unique(str); +} + std::unique_ptr USql::upper_function(const std::vector> &evaluatedPars) { std::string str = evaluatedPars[0]->getStringValue(); std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c) -> unsigned char { return toupper(c); }); @@ -41,11 +48,21 @@ std::unique_ptr USql::upper_function(const std::vector(str); } -std::unique_ptr USql::lower_function(const std::vector> &evaluatedPars) { - std::string str = evaluatedPars[0]->getStringValue(); - std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c) -> unsigned char { return tolower(c); }); - - return std::make_unique(str); +std::unique_ptr USql::coalesce_function(const std::vector> &evaluatedPars) { + for(const auto & par : evaluatedPars) { + if (!par->isNull()) { + // TODO implement rest and take it out as a function + if (par->node_type == NodeType::int_value) + return std::make_unique(par->getIntegerValue()); + if (par->node_type == NodeType::float_value) + return std::make_unique(par->getDoubleValue()); + if (par->node_type == NodeType::string_value) + return std::make_unique(par->getStringValue()); + if (par->node_type == NodeType::bool_value) + return std::make_unique(par->getBooleanValue()); + } + } + return std::make_unique(); } std::unique_ptr USql::pp_function(const std::vector> &evaluatedPars) {