pp function

This commit is contained in:
2021-08-16 13:55:51 +02:00
parent b03462da6a
commit a344f5b62f
6 changed files with 88 additions and 29 deletions

View File

@@ -2,6 +2,7 @@
#include "exception.h"
#include "ml_date.h"
#include <cmath>
#include <algorithm>
#include <fstream>
@@ -174,6 +175,7 @@ std::unique_ptr<Table> USql::execute_select(SelectFromTableNode &node) {
node.cols_names->emplace_back(SelectColNode{std::make_unique<DatabaseValueNode>(col.name), col.name});
}
}
// TODO further validations/optimizations like translate order by column names to indexes, validate those indexes, eval 1 + 1 etc
// create result table
@@ -199,8 +201,9 @@ std::unique_ptr<Table> USql::execute_select(SelectFromTableNode &node) {
for (auto idx = 0; idx < result->columns_count(); idx++) {
auto row_col_index = source_table_col_index[idx];
if (row_col_index == -1) { // TODO introduce constant here
auto evaluated_value = eval_value_node(table, *row, node.cols_names->operator[](idx).value.get());
if (row_col_index == FUNCTION_CALL) {
//auto evaluated_value = eval_value_node(table, *row, node.cols_names->operator[](idx).value.get());
auto evaluated_value = eval_function_value_node(table, *row, node.cols_names->operator[](idx).value.get());
ValueNode *col_value = evaluated_value.get();
new_row.setColumnValue(&result_tbl_col_defs[idx], col_value);
@@ -277,15 +280,7 @@ 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 == "to_string") {
ColDefNode col_def = ColDefNode{col_name, ColumnType::varchar_type, col_order, 32, true};
return std::make_tuple(-1, col_def);
} else if (func_node->function == "to_date") {
ColDefNode col_def = ColDefNode{col_name, ColumnType::integer_type, col_order, 1, true};
return std::make_tuple(-1, col_def);
}
throw Exception("Unsupported function");
return get_function_node_definition(col_name, col_order, func_node);
} else if (node->node_type == NodeType::arithmetical_operator) {
auto ari_node = static_cast<ArithmeticalOperatorNode *>(node);
@@ -322,8 +317,6 @@ std::tuple<int, ColDefNode> USql::get_node_definition(Table *table, Node * node,
throw Exception("Unsupported node type");
}
std::unique_ptr<Table> USql::execute_delete(DeleteFromTableNode &node) {
// find source table
Table *table = find_table(node.table_name);
@@ -492,6 +485,26 @@ std::unique_ptr<ValueNode> USql::eval_literal_value_node(Table *table, Row &row,
}
std::tuple<int, ColDefNode> USql::get_function_node_definition(const std::string &col_name, int col_order, const FunctionNode *func_node) {
if (func_node->function == "to_string") {
ColDefNode col_def = ColDefNode{col_name, ColumnType::varchar_type, col_order, 32, true};
return std::make_tuple(-1, col_def);
} else if (func_node->function == "to_date") {
ColDefNode col_def = ColDefNode{col_name, ColumnType::date_type, col_order, 1, true};
return std::make_tuple(-1, col_def);
} else if (func_node->function == "round") {
ColDefNode col_def = ColDefNode{col_name, ColumnType::float_type, col_order, 1, true};
return std::make_tuple(-1, col_def);
} else if (func_node->function == "pp") {
ColDefNode col_def = ColDefNode{col_name, ColumnType::varchar_type, col_order, 10, true};
return std::make_tuple(-1, col_def);
} else if (func_node->function == "upper" || func_node->function == "lower") {
throw Exception("eval size of string");
}
throw Exception("Unsupported function");
}
std::unique_ptr<ValueNode> USql::eval_function_value_node(Table *table, Row &row, Node *node) {
auto *fnc = static_cast<FunctionNode *>(node);
@@ -511,7 +524,6 @@ std::unique_ptr<ValueNode> USql::eval_function_value_node(Table *table, Row &row
std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c) -> unsigned char { return std::toupper(c); });
return std::make_unique<StringValueNode>(str);
}
if (fnc->function == "to_date") {
std::string date = evaluatedPars[0]->getStringValue();
std::string format = evaluatedPars[1]->getStringValue();
@@ -524,6 +536,48 @@ std::unique_ptr<ValueNode> USql::eval_function_value_node(Table *table, Row &row
std::string formatted_date = date_to_string(date, format);
return std::make_unique<StringValueNode>(formatted_date);
}
if (fnc->function == "pp") {
auto &parsed_value = evaluatedPars[0];
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 str;
str.resize(32);
double value = parsed_value->getDoubleValue();
if (format == "100%")
str = std::snprintf((char *)str.c_str(), 20, "%.2f%%", value);
else if (value >= 1000000000000)
str = std::snprintf((char *)str.c_str(), 20, "%7.2fT", value/1000000000000);
else if (value >= 1000000000)
str = std::snprintf((char *)str.c_str(), 20, "%7.2fB", value/1000000000);
else if (value >= 1000000)
str = std::snprintf((char *)str.c_str(), 20, "%7.2fM", value/1000000);
else if (value >= 100000)
str = std::snprintf((char *)str.c_str(), 20, "%7.2fM", value/100000); // 0.12M
else if (value <= -1000000000000)
str = std::snprintf((char *)str.c_str(), 20, "%7.2fT", value/1000000000000);
else if (value <= -1000000000)
str = std::snprintf((char *)str.c_str(), 20, "%7.2fB", value/1000000000);
else if (value <= -1000000)
str = std::snprintf((char *)str.c_str(), 20, "%7.2fM", value/1000000);
else if (value <= -100000)
str = std::snprintf((char *)str.c_str(), 20, "%7.2fM", value/100000); // 0.12M
else
str = parsed_value->getStringValue();
return std::make_unique<StringValueNode>(str);
}
return std::make_unique<StringValueNode>(parsed_value->getStringValue());
}
if (fnc->function == "round") {
double value = evaluatedPars[0]->getDoubleValue();
int places = evaluatedPars[1]->getIntegerValue();
// TODO, FIXME implement me
double rounded = std::ceil(value * pow(10, places)) / pow(10, places);
return std::make_unique<DoubleValueNode>(rounded);
}
throw Exception("invalid function");
}