Compare commits
3 Commits
c944bf67c9
...
1578c9889d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1578c9889d | ||
|
|
68504eb090 | ||
|
|
e9b210a456 |
4
debug.h
4
debug.h
@@ -17,7 +17,9 @@ std::vector<std::string> k_debug_sql_commands {
|
|||||||
"set 'USE_INDEXSCAN' = 'false'",
|
"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_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",
|
||||||
"set 'USE_INDEXSCAN' = 'true'",
|
"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_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 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 table a (i integer not null, s varchar(64))",
|
||||||
// "create index a_i on a(i)",
|
// "create index a_i on a(i)",
|
||||||
|
|||||||
12
parser.cpp
12
parser.cpp
@@ -5,6 +5,17 @@ namespace usql {
|
|||||||
|
|
||||||
// TOOD handle premature eof
|
// TOOD handle premature eof
|
||||||
|
|
||||||
|
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::varchar_type) return "varchar_type";
|
||||||
|
if (type == ColumnType::date_type) return "date_type";
|
||||||
|
if (type == ColumnType::bool_type) return "bool_type";
|
||||||
|
|
||||||
|
throw Exception("invalid column type: " + (int)type);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
Parser::Parser() {
|
Parser::Parser() {
|
||||||
m_lexer = Lexer{};
|
m_lexer = Lexer{};
|
||||||
}
|
}
|
||||||
@@ -529,4 +540,3 @@ namespace usql {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|||||||
120
parser.h
120
parser.h
@@ -21,6 +21,9 @@ enum class ColumnType {
|
|||||||
bool_type
|
bool_type
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::string column_type_name(const ColumnType type);
|
||||||
|
|
||||||
|
|
||||||
enum class NodeType {
|
enum class NodeType {
|
||||||
true_node,
|
true_node,
|
||||||
null_value,
|
null_value,
|
||||||
@@ -51,6 +54,7 @@ enum class NodeType {
|
|||||||
error
|
error
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Node {
|
struct Node {
|
||||||
NodeType node_type;
|
NodeType node_type;
|
||||||
|
|
||||||
@@ -58,7 +62,7 @@ struct Node {
|
|||||||
virtual ~Node() = default;
|
virtual ~Node() = default;
|
||||||
|
|
||||||
virtual void dump() const {
|
virtual void dump() const {
|
||||||
std::cout << "type: Node" << std::endl;
|
std::cout << "type: Node" << (int)node_type << std::endl;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -115,19 +119,76 @@ struct ColDefNode : Node {
|
|||||||
null(nullable) {}
|
null(nullable) {}
|
||||||
|
|
||||||
void dump() const override {
|
void dump() const override {
|
||||||
std::cout << "type: ColDefNode, name: " << name << ", type: " << (int)type << " TODO add more" << std::endl;
|
std::cout << "type: ColDefNode, name: " << name << ", type: " << column_type_name(type) << ", order: " << order << ", length: " << length << ", null: " << null << std::endl;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FunctionNode : Node {
|
struct FunctionNode : Node {
|
||||||
std::string function; // TODO use enum
|
|
||||||
|
enum class Type {
|
||||||
|
to_string,
|
||||||
|
to_date,
|
||||||
|
date_add,
|
||||||
|
pp,
|
||||||
|
lower,
|
||||||
|
upper,
|
||||||
|
min,
|
||||||
|
max,
|
||||||
|
count
|
||||||
|
};
|
||||||
|
|
||||||
|
static Type get_function(const std::string &str) {
|
||||||
|
if (str=="to_string") return Type::to_string;
|
||||||
|
if (str=="to_date") return Type::to_date;
|
||||||
|
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=="min") return Type::min;
|
||||||
|
if (str=="max") return Type::max;
|
||||||
|
if (str=="count") return Type::count;
|
||||||
|
|
||||||
|
throw Exception("invalid function: " + str);
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::string function_name(const Type type) {
|
||||||
|
if (type == Type::to_string) return "to_string";
|
||||||
|
if (type == Type::to_date) return "to_date";
|
||||||
|
if (type == Type::date_add) return "date_add";
|
||||||
|
if (type == Type::pp) return "pp";
|
||||||
|
if (type == Type::lower) return "lower";
|
||||||
|
if (type == Type::upper) return "upper";
|
||||||
|
if (type == Type::min) return "min";
|
||||||
|
if (type == Type::max) return "max";
|
||||||
|
if (type == Type::count) return "count";
|
||||||
|
|
||||||
|
throw Exception("invalid function: " + (int)type);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Type function;
|
||||||
std::vector<std::unique_ptr<Node>> params;
|
std::vector<std::unique_ptr<Node>> params;
|
||||||
|
|
||||||
FunctionNode(std::string func_name, std::vector<std::unique_ptr<Node>> pars) :
|
FunctionNode(std::string func_name, std::vector<std::unique_ptr<Node>> pars) :
|
||||||
Node(NodeType::function), function(std::move(func_name)), params(std::move(pars)) {}
|
Node(NodeType::function), function(get_function(func_name)), params(std::move(pars)) {}
|
||||||
|
|
||||||
|
bool is_agg_function() {
|
||||||
|
return (function == Type::count || function == Type::min || function == Type::max);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
friend std::ostream &operator<<(std::ostream &output, const Type &t ) {
|
||||||
|
output << function_name(t);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
void dump() const override {
|
void dump() const override {
|
||||||
std::cout << "type: FunctionNode, function: " << function << " TODO add more" << std::endl;
|
std::cout << "type: FunctionNode, function: " << function_name(function) << "(";
|
||||||
|
for(int i = 0; i < params.size(); i++){
|
||||||
|
if (i > 0) std::cout << ",";
|
||||||
|
params[i]->dump();
|
||||||
|
}
|
||||||
|
std::cout << ")" << std::endl;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -325,7 +386,12 @@ struct CreateTableNode : Node {
|
|||||||
Node(NodeType::create_table), table_name(std::move(name)), cols_defs(std::move(defs)) {}
|
Node(NodeType::create_table), table_name(std::move(name)), cols_defs(std::move(defs)) {}
|
||||||
|
|
||||||
void dump() const override {
|
void dump() const override {
|
||||||
std::cout << "type: CreateTableNode, table_name: " << table_name << "TODO complete me" << std::endl;
|
std::cout << "type: CreateTableNode, table_name: " << table_name << "(";
|
||||||
|
for(int i = 0; i < cols_defs.size(); i++) {
|
||||||
|
if (i > 0) std::cout << ",";
|
||||||
|
cols_defs[i].dump();
|
||||||
|
}
|
||||||
|
std::cout << ")" << std::endl;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -338,7 +404,17 @@ struct InsertIntoTableNode : Node {
|
|||||||
Node(NodeType::insert_into), table_name(std::move(name)), cols_names(std::move(names)), cols_values(std::move(values)) {}
|
Node(NodeType::insert_into), table_name(std::move(name)), cols_names(std::move(names)), cols_values(std::move(values)) {}
|
||||||
|
|
||||||
void dump() const override {
|
void dump() const override {
|
||||||
std::cout << "type: InsertIntoTableNode, table_name: " << table_name << "TODO complete me" << std::endl;
|
std::cout << "type: InsertIntoTableNode, table_name: " << table_name << "(";
|
||||||
|
for(int i = 0; i < cols_names.size(); i++) {
|
||||||
|
if (i > 0) std::cout << ",";
|
||||||
|
cols_names[i].dump();
|
||||||
|
}
|
||||||
|
std::cout << ") values (";
|
||||||
|
for(int i = 0; i < cols_values.size(); i++) {
|
||||||
|
if (i > 0) std::cout << ",";
|
||||||
|
cols_values[i]->dump();
|
||||||
|
}
|
||||||
|
std::cout << ")" << std::endl;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -354,8 +430,22 @@ struct SelectFromTableNode : Node {
|
|||||||
Node(NodeType::select_from), table_name(std::move(name)), cols_names(std::move(names)), where(std::move(where_clause)), order_by(std::move(orderby)), offset_limit(std::move(offlim)), distinct(distinct_) {}
|
Node(NodeType::select_from), table_name(std::move(name)), cols_names(std::move(names)), where(std::move(where_clause)), order_by(std::move(orderby)), offset_limit(std::move(offlim)), distinct(distinct_) {}
|
||||||
|
|
||||||
void dump() const override {
|
void dump() const override {
|
||||||
std::cout << "type: SelectFromTableNode, table_name: " << table_name << "TODO complete me" << std::endl;
|
std::cout << "type: SelectFromTableNode, table_name: " << table_name;
|
||||||
|
std::cout << "colums: ";
|
||||||
|
for(int i = 0; i < cols_names->size(); i++) {
|
||||||
|
if (i > 0) std::cout << ",";
|
||||||
|
cols_names->operator[](i).dump();
|
||||||
|
}
|
||||||
|
std::cout << "where: ";
|
||||||
where->dump();
|
where->dump();
|
||||||
|
std::cout << "offset,limit: ";
|
||||||
|
for(int i = 0; i < order_by.size(); i++) {
|
||||||
|
if (i > 0) std::cout << ",";
|
||||||
|
order_by[i].dump();
|
||||||
|
}
|
||||||
|
std::cout << "offset,limit: ";
|
||||||
|
offset_limit.dump();
|
||||||
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -384,8 +474,16 @@ struct UpdateTableNode : Node {
|
|||||||
where(std::move(where_clause)) {}
|
where(std::move(where_clause)) {}
|
||||||
|
|
||||||
void dump() const override {
|
void dump() const override {
|
||||||
std::cout << "type: UpdateTableNode, table_name: " << table_name << "TODO complete me" << std::endl;
|
std::cout << "type: UpdateTableNode, table_name: " << table_name << " set ";
|
||||||
|
for(int i = 0; i < cols_names.size(); i++) {
|
||||||
|
if (i > 0) std::cout << ",";
|
||||||
|
cols_names[i].dump();
|
||||||
|
std::cout << " = ";
|
||||||
|
values[i]->dump();
|
||||||
|
}
|
||||||
|
std::cout << " where: ";
|
||||||
where->dump();
|
where->dump();
|
||||||
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -431,8 +529,10 @@ struct DeleteFromTableNode : Node {
|
|||||||
Node(NodeType::delete_from), table_name(std::move(name)), where(std::move(where_clause)) {}
|
Node(NodeType::delete_from), table_name(std::move(name)), where(std::move(where_clause)) {}
|
||||||
|
|
||||||
void dump() const override {
|
void dump() const override {
|
||||||
std::cout << "type: DeleteFromTableNode, table_name: " << table_name << std::endl;
|
std::cout << "type: DeleteFromTableNode, table_name: " << table_name;
|
||||||
|
std::cout << "where: ";
|
||||||
where->dump();
|
where->dump();
|
||||||
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
2
row.h
2
row.h
@@ -182,7 +182,7 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] bool is_visible() const { return m_visible; };
|
[[nodiscard]] bool is_visible() const { return m_visible; };
|
||||||
void set_visible() { m_visible = true; };
|
void set_visible() { m_visible = true; };
|
||||||
void set_deleted() { m_visible = true; };
|
void set_deleted() { m_visible = false; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_visible;
|
bool m_visible;
|
||||||
|
|||||||
21
usql.cpp
21
usql.cpp
@@ -176,18 +176,17 @@ std::unique_ptr<ValueNode> USql::eval_function_value_node(Table *table, Row &row
|
|||||||
if (evaluatedPars.empty() || evaluatedPars[0]->isNull())
|
if (evaluatedPars.empty() || evaluatedPars[0]->isNull())
|
||||||
return std::make_unique<NullValueNode>();
|
return std::make_unique<NullValueNode>();
|
||||||
|
|
||||||
// TODO use some enum
|
if (fnc->function == FunctionNode::Type::lower) return lower_function(evaluatedPars);
|
||||||
if (fnc->function == "lower") return lower_function(evaluatedPars);
|
if (fnc->function == FunctionNode::Type::upper) return upper_function(evaluatedPars);
|
||||||
if (fnc->function == "upper") return upper_function(evaluatedPars);
|
if (fnc->function == FunctionNode::Type::to_date) return to_date_function(evaluatedPars);
|
||||||
if (fnc->function == "to_date") return to_date_function(evaluatedPars);
|
if (fnc->function == FunctionNode::Type::to_string) return to_string_function(evaluatedPars);
|
||||||
if (fnc->function == "to_string") return to_string_function(evaluatedPars);
|
if (fnc->function == FunctionNode::Type::date_add) return date_add_function(evaluatedPars);
|
||||||
if (fnc->function == "date_add") return date_add_function(evaluatedPars);
|
if (fnc->function == FunctionNode::Type::pp) return pp_function(evaluatedPars);
|
||||||
if (fnc->function == "pp") return pp_function(evaluatedPars);
|
if (fnc->function == FunctionNode::Type::count) return count_function(agg_func_value, evaluatedPars);
|
||||||
if (fnc->function == "count") return count_function(agg_func_value, evaluatedPars);
|
if (fnc->function == FunctionNode::Type::max) return max_function(evaluatedPars, col_def_node, agg_func_value);
|
||||||
if (fnc->function == "max") return max_function(evaluatedPars, col_def_node, agg_func_value);
|
if (fnc->function == FunctionNode::Type::min) return min_function(evaluatedPars, col_def_node, agg_func_value);
|
||||||
if (fnc->function == "min") return min_function(evaluatedPars, col_def_node, agg_func_value);
|
|
||||||
|
|
||||||
throw Exception("invalid function: " + fnc->function);
|
throw Exception("invalid function: " + FunctionNode::function_name(fnc->function));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
33
usql_dml.cpp
33
usql_dml.cpp
@@ -108,24 +108,21 @@ void USql::select_row(SelectFromTableNode &where_node,
|
|||||||
rslt_row->setColumnValue((ColDefNode *) &rslt_tbl_col_defs[idx], col_value);
|
rslt_row->setColumnValue((ColDefNode *) &rslt_tbl_col_defs[idx], col_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// for aggregate is validated more than needed
|
// for aggregate is validated more than needed
|
||||||
rslt_table->commit_row(*rslt_row);
|
rslt_table->commit_row(*rslt_row);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool USql::check_for_aggregate_only_functions(SelectFromTableNode &node, size_t result_cols_cnt) {
|
bool USql::check_for_aggregate_only_functions(SelectFromTableNode &node, size_t result_cols_cnt) {
|
||||||
size_t aggregate_funcs = 0;
|
size_t aggregate_funcs = 0;
|
||||||
|
|
||||||
for (size_t i = 0; i < node.cols_names->size(); i++) {
|
for (size_t i = 0; i < node.cols_names->size(); i++) {
|
||||||
SelectColNode * col_node = &node.cols_names->operator[](i);
|
SelectColNode * col_node = &node.cols_names->operator[](i);
|
||||||
if (col_node->value->node_type == NodeType::function) {
|
if (col_node->value->node_type == NodeType::function && ((FunctionNode *)col_node->value.get())->is_agg_function())
|
||||||
auto func_node = static_cast<FunctionNode *>(col_node->value.get());
|
|
||||||
if (func_node->function == "count" || func_node->function == "min" || func_node->function == "max")
|
|
||||||
aggregate_funcs++;
|
aggregate_funcs++;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// check whether aggregates are not present or all columns are aggregates
|
// check whether aggregates are not present or all columns are aggregates
|
||||||
if (aggregate_funcs > 0 && aggregate_funcs != result_cols_cnt) {
|
if (aggregate_funcs > 0 && aggregate_funcs != result_cols_cnt) {
|
||||||
throw Exception("aggregate functions with no aggregates");
|
throw Exception("aggregate functions mixed with no aggregate functions in select clause");
|
||||||
}
|
}
|
||||||
|
|
||||||
return aggregate_funcs > 0;
|
return aggregate_funcs > 0;
|
||||||
@@ -229,20 +226,20 @@ std::tuple<int, ColDefNode> USql::get_node_definition(Table *table, Node * node,
|
|||||||
} else if (node->node_type == NodeType::function) {
|
} else if (node->node_type == NodeType::function) {
|
||||||
auto func_node = static_cast<FunctionNode *>(node);
|
auto func_node = static_cast<FunctionNode *>(node);
|
||||||
|
|
||||||
if (func_node->function == "to_string") {
|
if (func_node->function == FunctionNode::Type::to_string) {
|
||||||
ColDefNode col_def = ColDefNode{col_name, ColumnType::varchar_type, col_order, 32, true};
|
ColDefNode col_def = ColDefNode{col_name, ColumnType::varchar_type, col_order, 32, true};
|
||||||
return std::make_tuple(-1, col_def);
|
return std::make_tuple(FUNCTION_CALL, col_def);
|
||||||
} else if (func_node->function == "to_date") {
|
} else if (func_node->function == FunctionNode::Type::to_date) {
|
||||||
ColDefNode col_def = ColDefNode{col_name, ColumnType::integer_type, col_order, 1, true};
|
ColDefNode col_def = ColDefNode{col_name, ColumnType::integer_type, col_order, 1, true};
|
||||||
return std::make_tuple(-1, col_def);
|
return std::make_tuple(FUNCTION_CALL, col_def);
|
||||||
} else if (func_node->function == "pp") {
|
} else if (func_node->function == FunctionNode::Type::pp) {
|
||||||
ColDefNode col_def = ColDefNode{col_name, ColumnType::varchar_type, col_order, 10, true};
|
ColDefNode col_def = ColDefNode{col_name, ColumnType::varchar_type, col_order, 10, true};
|
||||||
return std::make_tuple(-1, col_def);
|
return std::make_tuple(FUNCTION_CALL, col_def);
|
||||||
} else if (func_node->function == "lower" || func_node->function == "upper") {
|
} else if (func_node->function == FunctionNode::Type::lower || func_node->function == FunctionNode::Type::upper) {
|
||||||
// TODO get length, use get_db_column_definition
|
// TODO get length, use get_db_column_definition
|
||||||
ColDefNode col_def = ColDefNode{col_name, ColumnType::varchar_type, col_order, 256, true};
|
ColDefNode col_def = ColDefNode{col_name, ColumnType::varchar_type, col_order, 256, true};
|
||||||
return std::make_tuple(-1, col_def);
|
return std::make_tuple(FUNCTION_CALL, col_def);
|
||||||
} else if (func_node->function == "min" || func_node->function == "max") {
|
} 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;
|
size_t col_len = 1;
|
||||||
auto & v = func_node->params[0];
|
auto & v = func_node->params[0];
|
||||||
@@ -252,10 +249,10 @@ std::tuple<int, ColDefNode> USql::get_node_definition(Table *table, Node * node,
|
|||||||
col_len = src_col_def.length;
|
col_len = src_col_def.length;
|
||||||
}
|
}
|
||||||
ColDefNode col_def = ColDefNode{col_name, col_type, col_order, col_len, true};
|
ColDefNode col_def = ColDefNode{col_name, col_type, col_order, col_len, true};
|
||||||
return std::make_tuple(-1, col_def);
|
return std::make_tuple(FUNCTION_CALL, col_def);
|
||||||
} else if (func_node->function == "count") {
|
} else if (func_node->function == FunctionNode::Type::count) {
|
||||||
ColDefNode col_def = ColDefNode{col_name, ColumnType::integer_type, col_order, 1, true};
|
ColDefNode col_def = ColDefNode{col_name, ColumnType::integer_type, col_order, 1, true};
|
||||||
return std::make_tuple(-1, col_def);
|
return std::make_tuple(FUNCTION_CALL, col_def);
|
||||||
}
|
}
|
||||||
throw Exception("Unsupported function");
|
throw Exception("Unsupported function");
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ std::unique_ptr<ValueNode> USql::to_string_function(const std::vector<std::uniqu
|
|||||||
long date = evaluatedPars[0]->getDateValue();
|
long date = evaluatedPars[0]->getDateValue();
|
||||||
std::string format = evaluatedPars[1]->getStringValue();
|
std::string format = evaluatedPars[1]->getStringValue();
|
||||||
std::string formatted_date = date_to_string(date, format);
|
std::string formatted_date = date_to_string(date, format);
|
||||||
|
|
||||||
return std::make_unique<StringValueNode>(formatted_date);
|
return std::make_unique<StringValueNode>(formatted_date);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18,6 +19,7 @@ std::unique_ptr<ValueNode> USql::to_date_function(const std::vector<std::unique_
|
|||||||
std::string date = evaluatedPars[0]->getStringValue();
|
std::string date = evaluatedPars[0]->getStringValue();
|
||||||
std::string format = evaluatedPars[1]->getStringValue();
|
std::string format = evaluatedPars[1]->getStringValue();
|
||||||
long epoch_time = string_to_date(date, format);
|
long epoch_time = string_to_date(date, format);
|
||||||
|
|
||||||
return std::make_unique<IntValueNode>(epoch_time); // No DateValueNode for now
|
return std::make_unique<IntValueNode>(epoch_time); // No DateValueNode for now
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,6 +29,7 @@ std::unique_ptr<ValueNode> USql::date_add_function(const std::vector<std::unique
|
|||||||
std::string part = evaluatedPars[2]->getStringValue();
|
std::string part = evaluatedPars[2]->getStringValue();
|
||||||
|
|
||||||
long new_date = add_to_date(datetime, quantity, part);
|
long new_date = add_to_date(datetime, quantity, part);
|
||||||
|
|
||||||
return std::make_unique<IntValueNode>(new_date); // No DateValueNode for now
|
return std::make_unique<IntValueNode>(new_date); // No DateValueNode for now
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,51 +37,57 @@ std::unique_ptr<ValueNode> USql::date_add_function(const std::vector<std::unique
|
|||||||
std::unique_ptr<ValueNode> USql::upper_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars) {
|
std::unique_ptr<ValueNode> USql::upper_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars) {
|
||||||
std::string str = evaluatedPars[0]->getStringValue();
|
std::string str = evaluatedPars[0]->getStringValue();
|
||||||
std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c) -> unsigned char { return toupper(c); });
|
std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c) -> unsigned char { return toupper(c); });
|
||||||
|
|
||||||
return std::make_unique<StringValueNode>(str);
|
return std::make_unique<StringValueNode>(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ValueNode> USql::lower_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars) {
|
std::unique_ptr<ValueNode> USql::lower_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars) {
|
||||||
std::string str = evaluatedPars[0]->getStringValue();
|
std::string str = evaluatedPars[0]->getStringValue();
|
||||||
std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c) -> unsigned char { return tolower(c); });
|
std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c) -> unsigned char { return tolower(c); });
|
||||||
|
|
||||||
return std::make_unique<StringValueNode>(str);
|
return std::make_unique<StringValueNode>(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ValueNode> USql::pp_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars) {
|
std::unique_ptr<ValueNode> USql::pp_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars) {
|
||||||
|
constexpr auto k_num_format_rpad = 10;
|
||||||
|
constexpr auto k_num_format_maxlen = 20;
|
||||||
|
|
||||||
auto &parsed_value = evaluatedPars[0];
|
auto &parsed_value = evaluatedPars[0];
|
||||||
|
|
||||||
if (parsed_value->node_type == NodeType::int_value || parsed_value->node_type == NodeType::float_value) {
|
if (parsed_value->node_type == NodeType::int_value || parsed_value->node_type == NodeType::float_value) {
|
||||||
std::string format = evaluatedPars.size() > 1 ? evaluatedPars[1]->getStringValue() : "";
|
std::string format = evaluatedPars.size() > 1 ? evaluatedPars[1]->getStringValue() : "";
|
||||||
char buf[20] {0}; // TODO constant here
|
char buf[k_num_format_maxlen] {0};
|
||||||
double value = parsed_value->getDoubleValue();
|
double value = parsed_value->getDoubleValue();
|
||||||
|
|
||||||
if (format == "100%")
|
if (format == "100%")
|
||||||
std::snprintf(buf, 20, "%.2f%%", value);
|
std::snprintf(buf, k_num_format_maxlen, "%.2f%%", value);
|
||||||
else if (format == "%.2f")
|
else if (format == "%.2f")
|
||||||
std::snprintf(buf, 20, "%.2f", value);
|
std::snprintf(buf, k_num_format_maxlen, "%.2f", value);
|
||||||
else if (value >= 1000000000000)
|
else if (value >= 1000000000000)
|
||||||
std::snprintf(buf, 20, "%7.2fT", value/1000000000000);
|
std::snprintf(buf, k_num_format_maxlen, "%7.2fT", value/1000000000000);
|
||||||
else if (value >= 1000000000)
|
else if (value >= 1000000000)
|
||||||
std::sprintf(buf, "%7.2fB", value/1000000000);
|
std::snprintf(buf, k_num_format_maxlen, "%7.2fB", value/1000000000);
|
||||||
else if (value >= 1000000)
|
else if (value >= 1000000)
|
||||||
std::snprintf(buf, 20, "%7.2fM", value/1000000);
|
std::snprintf(buf, k_num_format_maxlen, "%7.2fM", value/1000000);
|
||||||
else if (value >= 100000)
|
else if (value >= 100000)
|
||||||
std::snprintf(buf, 20, "%7.2fM", value/100000); // 0.12M
|
std::snprintf(buf, k_num_format_maxlen, "%7.2fM", value/100000); // 0.12M
|
||||||
else if (value <= -1000000000000)
|
else if (value <= -1000000000000)
|
||||||
std::snprintf(buf, 20, "%7.2fT", value/1000000000000);
|
std::snprintf(buf, k_num_format_maxlen, "%7.2fT", value/1000000000000);
|
||||||
else if (value <= -1000000000)
|
else if (value <= -1000000000)
|
||||||
std::snprintf(buf, 20, "%7.2fB", value/1000000000);
|
std::snprintf(buf, k_num_format_maxlen, "%7.2fB", value/1000000000);
|
||||||
else if (value <= -1000000)
|
else if (value <= -1000000)
|
||||||
std::snprintf(buf, 20, "%7.2fM", value/1000000);
|
std::snprintf(buf, k_num_format_maxlen, "%7.2fM", value/1000000);
|
||||||
else if (value <= -100000)
|
else if (value <= -100000)
|
||||||
std::snprintf(buf, 20, "%7.2fM", value/100000); // 0.12M
|
std::snprintf(buf, k_num_format_maxlen, "%7.2fM", value/100000); // 0.12M
|
||||||
else if (value == 0)
|
else if (value == 0)
|
||||||
buf[0]='0';
|
buf[0]='0';
|
||||||
else
|
else
|
||||||
return std::make_unique<StringValueNode>(parsed_value->getStringValue().substr(0, 10));
|
return std::make_unique<StringValueNode>(parsed_value->getStringValue().substr(0, k_num_format_rpad));
|
||||||
// TODO introduce constant for 10
|
|
||||||
std::string s {buf};
|
std::string s {buf};
|
||||||
return std::make_unique<StringValueNode>(string_padd(s.erase(s.find_last_not_of(' ')+1), 10, ' ', false));
|
return std::make_unique<StringValueNode>(string_padd(s.erase(s.find_last_not_of(' ') + 1), k_num_format_rpad, ' ', false));
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::make_unique<StringValueNode>(parsed_value->getStringValue());
|
return std::make_unique<StringValueNode>(parsed_value->getStringValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user