a bit of work on conversion functions

This commit is contained in:
vaclavt 2022-04-03 16:46:39 +02:00
parent aca52899fb
commit dadad69958
7 changed files with 81 additions and 25 deletions

View File

@ -4,8 +4,17 @@ compare in row.cpp shoud take into account m_visible
### TODO
- create local_install.sh
- change float type keyword to double and in code functions too
- add functions:
- coalesce
- now
- rtrim, ltrim, rpad, lpad
- round
- set xxx - without value to reset to default value
- coalesce, date functions now; string functions rtrim, ltrim, rpad, lpad; math function round
- add pipe | concatenation
- add support for 1_000_000 numbers
- expand_asterix_char should support multiple and everywhere *

27
debug.h
View File

@ -15,22 +15,22 @@ std::vector<std::string> k_debug_sql_commands {
// "create index sf1_symbol on sf1(symbol)",
// "load into sf1 '/srv/SHARADAR_SF1.csv'",
// "set 'USE_INDEXSCAN' = 'false'",
// "select dimension, to_string(calendar_date, '%d.%m.%Y'), pp(eps, \"%.2f\"), pp(shareswadil), pp(revenue), pp(netinc), pp(cashneq), pp(assets), pp(debt), pp(ncfdebt), pp(roe*100), pp(intangibles), calendar_date from sf1 where symbol = 'MU' and dimension = 'ARQ' order by dimension, calendar_date desc limit 5",
// "select dimension, to_char(calendar_date, '%d.%m.%Y'), pp(eps, \"%.2f\"), pp(shareswadil), pp(revenue), pp(netinc), pp(cashneq), pp(assets), pp(debt), pp(ncfdebt), pp(roe*100), pp(intangibles), calendar_date from sf1 where symbol = 'MU' and dimension = 'ARQ' order by dimension, calendar_date desc limit 5",
// "set 'USE_INDEXSCAN' = 'true'",
// "select dimension, to_string(calendar_date, '%d.%m.%Y'), pp(eps, \"%.2f\"), pp(shareswadil), pp(revenue), pp(netinc), pp(cashneq), pp(assets), pp(debt), pp(ncfdebt), pp(roe*100), pp(intangibles), calendar_date from sf1 where symbol = 'MU' and dimension = 'ARQ' order by dimension, calendar_date desc limit 5",
// "select dimension, to_char(calendar_date, '%d.%m.%Y'), pp(eps, \"%.2f\"), pp(shareswadil), pp(revenue), pp(netinc), pp(cashneq), pp(assets), pp(debt), pp(ncfdebt), pp(roe*100), pp(intangibles), calendar_date from sf1 where symbol = 'MU' and dimension = 'ARQ' order by dimension, calendar_date desc limit 5",
// "select max(calendar_date), calendar_date from sf1 where symbol = 'MU' and dimension = 'ARQ'",
// "select max(calendar_date), min(calendar_date) from sf1 where symbol = 'MU' and dimension = 'ARQ'"
"create table a (i integer not null, s varchar(64))",
"create index a_i on a(i)",
// "create table a (i integer not null, s varchar(64))",
// "create index a_i on a(i)",
// "insert into a (i, s) values(1, 'one')",
// "insert into a (i, s) values(2, 'two')",
// "insert into a (i, s) values(2, 'second two')",
// "insert into a (i, s) values(3, 'three')",
// "insert into a (i, s) values(4, 'four')",
"insert into a (i) values(5)",
"save a into '/tmp/a.csv'",
"set 'USE_INDEXSCAN' = 'true'",
// "insert into a (i) values(5)",
// "save a into '/tmp/a.csv'",
// "set 'USE_INDEXSCAN' = 'true'",
// "select * from a where 1 = i",
// "delete from a where i = 2 and s ='two'",
// "select * from a where i = 2",
@ -40,6 +40,17 @@ std::vector<std::string> k_debug_sql_commands {
// "select min(i), max(i), count(i) from a",
// "select i + 1000 from a",
// "select i, s from a where i = 5",
"select i, s, coalesce(s, i) from a where i = 5"
// "select i, s, coalesce(s, i) from a where i = 5",
// "create table a (i float, j float)",
// "insert into a (i, j) values(null, 123456789.12345)",
// "select pp(coalesce(i, j)) from a",
"create table d (datetime date)",
"insert into d (datetime) values(1648634993)",
"select to_char(datetime, '%Y%m%d') from d",
"select to_int(datetime) from d",
"select max(to_char(datetime, '%Y%m%d')) from d",
"select max(to_int(to_float(to_char(datetime, '%Y%m%d')))) from d"
};

View File

@ -126,8 +126,10 @@ struct ColDefNode : Node {
struct FunctionNode : Node {
enum class Type {
to_string,
to_char,
to_date,
to_int,
to_float,
date_add,
pp,
lower,
@ -139,13 +141,15 @@ struct FunctionNode : Node {
};
static Type get_function(const std::string &str) {
if (str=="to_string") return Type::to_string;
if (str=="to_char") return Type::to_char;
if (str=="to_date") return Type::to_date;
if (str=="to_int") return Type::to_int;
if (str=="to_float") return Type::to_float;
if (str=="date_add") return Type::date_add;
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=="coalesce") return Type::coalesce;
if (str=="min") return Type::min;
if (str=="max") return Type::max;
if (str=="count") return Type::count;
@ -154,8 +158,10 @@ struct FunctionNode : Node {
};
static std::string function_name(const Type type) {
if (type == Type::to_string) return "to_string";
if (type == Type::to_char) return "to_char";
if (type == Type::to_date) return "to_date";
if (type == Type::to_int) return "to_int";
if (type == Type::to_float) return "to_float";
if (type == Type::date_add) return "date_add";
if (type == Type::pp) return "pp";
if (type == Type::lower) return "lower";
@ -169,7 +175,7 @@ struct FunctionNode : Node {
};
Type function;
Type function;
std::vector<std::unique_ptr<Node>> params;
FunctionNode(std::string func_name, std::vector<std::unique_ptr<Node>> pars) :

View File

@ -182,7 +182,9 @@ std::unique_ptr<ValueNode> USql::eval_function_value_node(Table *table, Row &row
if (fnc->function == FunctionNode::Type::lower) return lower_function(evaluatedPars);
if (fnc->function == FunctionNode::Type::upper) return upper_function(evaluatedPars);
if (fnc->function == FunctionNode::Type::to_date) return to_date_function(evaluatedPars);
if (fnc->function == FunctionNode::Type::to_string) return to_string_function(evaluatedPars);
if (fnc->function == FunctionNode::Type::to_char) return to_char_function(evaluatedPars);
if (fnc->function == FunctionNode::Type::to_int) return to_int_function(evaluatedPars);
if (fnc->function == FunctionNode::Type::to_float) return to_float_function(evaluatedPars);
if (fnc->function == FunctionNode::Type::date_add) return date_add_function(evaluatedPars);
if (fnc->function == FunctionNode::Type::pp) return pp_function(evaluatedPars);
if (fnc->function == FunctionNode::Type::count) return count_function(agg_func_value, evaluatedPars);

4
usql.h
View File

@ -75,7 +75,9 @@ private:
static std::unique_ptr<ValueNode> upper_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars);
static std::unique_ptr<ValueNode> coalesce_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars);
static std::unique_ptr<ValueNode> to_date_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars);
static std::unique_ptr<ValueNode> to_string_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars);
static std::unique_ptr<ValueNode> to_char_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars);
static std::unique_ptr<ValueNode> to_int_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars);
static std::unique_ptr<ValueNode> to_float_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars);
static std::unique_ptr<ValueNode> date_add_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars);
static std::unique_ptr<ValueNode> pp_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars);

View File

@ -217,7 +217,7 @@ ColDefNode USql::get_db_column_definition(Table *table, Node *node) {
throw Exception("Undefined table node - get_db_column_definition");
}
std::tuple<int, ColDefNode> USql::get_node_definition(Table *table, Node * node, const std::string & col_name, int col_order ) {
std::tuple<int, ColDefNode> USql::get_node_definition(Table *table, Node * node, const std::string &col_name, int col_order ) {
if (node->node_type == NodeType::database_value) {
ColDefNode src_col_def = get_db_column_definition(table, node);
ColDefNode col_def = ColDefNode{col_name, src_col_def.type, col_order, src_col_def.length, src_col_def.null};
@ -226,9 +226,15 @@ std::tuple<int, ColDefNode> USql::get_node_definition(Table *table, Node * node,
} else if (node->node_type == NodeType::function) {
auto func_node = static_cast<FunctionNode *>(node);
if (func_node->function == FunctionNode::Type::to_string) {
if (func_node->function == FunctionNode::Type::to_char) {
ColDefNode col_def = ColDefNode{col_name, ColumnType::varchar_type, col_order, 32, true};
return std::make_tuple(FUNCTION_CALL, col_def);
} else if (func_node->function == FunctionNode::Type::to_int) {
ColDefNode col_def = ColDefNode{col_name, ColumnType::integer_type, col_order, 1, true};
return std::make_tuple(FUNCTION_CALL, col_def);
} else if (func_node->function == FunctionNode::Type::to_float) {
ColDefNode col_def = ColDefNode{col_name, ColumnType::float_type, col_order, 1, true};
return std::make_tuple(FUNCTION_CALL, col_def);
} else if (func_node->function == FunctionNode::Type::to_date) {
ColDefNode col_def = ColDefNode{col_name, ColumnType::integer_type, col_order, 1, true};
return std::make_tuple(FUNCTION_CALL, col_def);
@ -243,18 +249,26 @@ std::tuple<int, ColDefNode> USql::get_node_definition(Table *table, Node * node,
// 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;
auto col_type = ColumnType::float_type;
size_t col_len = 1;
auto & v = func_node->params[0];
auto &v = func_node->params[0];
if (v->node_type == NodeType::database_value) {
ColDefNode src_col_def = get_db_column_definition(table, v.get());
col_type = src_col_def.type;
col_len = src_col_def.length;
} else if (node->node_type == NodeType::function) {
std::tuple<int, ColDefNode> fun_type = get_node_definition(table, static_cast<Node*>(& *v), "", 0);
col_type = std::get<1>(fun_type).type;
col_len = std::get<1>(fun_type).length;
}
ColDefNode col_def = ColDefNode{col_name, col_type, col_order, col_len, true};
return std::make_tuple(FUNCTION_CALL, col_def);
} else if (func_node->function == FunctionNode::Type::count) {

View File

@ -7,12 +7,24 @@
namespace usql {
std::unique_ptr<ValueNode> USql::to_string_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars) {
long date = evaluatedPars[0]->getDateValue();
std::string format = evaluatedPars[1]->getStringValue();
std::string formatted_date = date_to_string(date, format);
std::unique_ptr<ValueNode> USql::to_char_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars) {
if (evaluatedPars[0]->node_type == NodeType::int_value && evaluatedPars.size()==2) { // TODO when propper date is introduced
long date = evaluatedPars[0]->getDateValue();
std::string format = evaluatedPars[1]->getStringValue();
std::string formatted_date = date_to_string(date, format);
return std::make_unique<StringValueNode>(formatted_date);
return std::make_unique<StringValueNode>(formatted_date);
} else {
return std::make_unique<StringValueNode>(evaluatedPars[0]->getStringValue());
}
}
std::unique_ptr<ValueNode> USql::to_int_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars) {
return std::make_unique<IntValueNode>(evaluatedPars[0]->getIntegerValue());
}
std::unique_ptr<ValueNode> USql::to_float_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars) {
return std::make_unique<DoubleValueNode>(evaluatedPars[0]->getDoubleValue());
}
std::unique_ptr<ValueNode> USql::to_date_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars) {