decide correct column type

This commit is contained in:
VaclavT 2021-08-14 17:30:40 +02:00
parent efb4ee1648
commit 5201f32023
2 changed files with 74 additions and 20 deletions

View File

@ -170,7 +170,7 @@ std::unique_ptr<Table> USql::execute_select(SelectFromTableNode &node) {
if (node.cols_names->size()==1 && node.cols_names->operator[](0).name == "*") {
node.cols_names->clear();
node.cols_names->reserve(table->columns_count());
for(auto col : table->m_col_defs) {
for(const auto& col : table->m_col_defs) {
node.cols_names->emplace_back(SelectColNode{std::make_unique<DatabaseValueNode>(col.name), col.name});
}
}
@ -181,7 +181,7 @@ std::unique_ptr<Table> USql::execute_select(SelectFromTableNode &node) {
std::vector<int> source_table_col_index{};
for (int i = 0; i < node.cols_names->size(); i++) {
auto [src_tbl_col_index, rst_tbl_col_def] = get_column_definition(table, &node.cols_names->operator[](i), i);
auto [src_tbl_col_index, rst_tbl_col_def] = get_column_definition(table, &node.cols_names->operator[](i), i);
source_table_col_index.push_back(src_tbl_col_index);
result_tbl_col_defs.push_back(rst_tbl_col_def);
@ -264,29 +264,84 @@ void USql::execute_offset_limit(OffsetLimitNode &node, Table *result) {
}
std::tuple<int, ColDefNode> USql::get_column_definition(Table *table, SelectColNode *select_col_node, int col_order ) {
std::string new_col_name = select_col_node->name;
return get_node_definition(table, select_col_node->value.get(), select_col_node->name, col_order );
if (select_col_node->value->node_type == NodeType::database_value) {
ColDefNode src_cdef = table->get_column_def(new_col_name);
ColDefNode cdef = ColDefNode{new_col_name, src_cdef.type, col_order, src_cdef.length, src_cdef.null};
// if (select_col_node->value->node_type == NodeType::database_value) {
// ColDefNode src_cdef = table->get_column_def(new_col_name);
// ColDefNode cdef = ColDefNode{new_col_name, src_cdef.type, col_order, src_cdef.length, src_cdef.null};
// return std::make_tuple(src_cdef.order, cdef);
//
// } else if (select_col_node->value->node_type == NodeType::function) {
// auto node = static_cast<FunctionNode *>(select_col_node->value.get());
//
// if (node->function == "to_string") {
// ColDefNode cdef = ColDefNode{new_col_name, ColumnType::varchar_type, col_order, 32, true};
// return std::make_tuple(-1, cdef);
// } else if (node->function == "to_date") {
// ColDefNode cdef = ColDefNode{new_col_name, ColumnType::integer_type, col_order, 1, true};
// return std::make_tuple(-1, cdef);
// }
// throw Exception("Unsupported function");
//
// } else if (select_col_node->value->node_type == NodeType::arithmetical_operator) {
// // TODO return correct type
// // hierarchicaly go throuhg and deduce right type
// ColDefNode cdef = ColDefNode{new_col_name, ColumnType::float_type, col_order, 1, true};
// return std::make_tuple(-1, cdef);
// }
// throw Exception("Unsupported node type");
}
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) {
auto dbval_node = static_cast<DatabaseValueNode *>(node);
ColDefNode src_cdef = table->get_column_def(dbval_node->col_name);
ColDefNode cdef = ColDefNode{col_name, src_cdef.type, col_order, src_cdef.length, src_cdef.null};
return std::make_tuple(src_cdef.order, cdef);
} else if (select_col_node->value->node_type == NodeType::function) {
auto node = static_cast<FunctionNode *>(select_col_node->value.get());
} else if (node->node_type == NodeType::function) {
auto func_node = static_cast<FunctionNode *>(node);
if (node->function == "to_string") {
ColDefNode cdef = ColDefNode{new_col_name, ColumnType::varchar_type, col_order, 32, true};
if (func_node->function == "to_string") {
ColDefNode cdef = ColDefNode{col_name, ColumnType::varchar_type, col_order, 32, true};
return std::make_tuple(-1, cdef);
} else if (node->function == "to_date") {
ColDefNode cdef = ColDefNode{new_col_name, ColumnType::integer_type, col_order, 1, true};
} else if (func_node->function == "to_date") {
ColDefNode cdef = ColDefNode{col_name, ColumnType::integer_type, col_order, 1, true};
return std::make_tuple(-1, cdef);
}
throw Exception("Unsupported function");
} else if (select_col_node->value->node_type == NodeType::arithmetical_operator) {
// TODO return correct type
// hierarchicaly go throuhg and deduce right type
ColDefNode cdef = ColDefNode{new_col_name, ColumnType::float_type, col_order, 1, true};
} else if (node->node_type == NodeType::arithmetical_operator) {
auto ari_node = static_cast<ArithmeticalOperatorNode *>(node);
auto [left_col_index, left_tbl_col_def] = get_node_definition(table, ari_node->left.get(), col_name, col_order );
auto [right_col_index, right_tbl_col_def] = get_node_definition(table, ari_node->right.get(), col_name, col_order );
ColumnType col_type; // TODO handle varchar and it len
if (left_tbl_col_def.type==ColumnType::float_type || right_tbl_col_def.type==ColumnType::float_type)
col_type = ColumnType::float_type;
else
col_type = ColumnType::integer_type;
ColDefNode cdef = ColDefNode{col_name, col_type, col_order, 1, true};
return std::make_tuple(-1, cdef);
} else if (node->node_type == NodeType::logical_operator) {
ColDefNode cdef = ColDefNode{col_name, ColumnType::bool_type, col_order, 1, true};
return std::make_tuple(-1, cdef);
} else if (node->node_type == NodeType::int_value) {
ColDefNode cdef = ColDefNode{col_name, ColumnType::integer_type, col_order, 1, true};
return std::make_tuple(-1, cdef);
} else if (node->node_type == NodeType::float_value) {
ColDefNode cdef = ColDefNode{col_name, ColumnType::float_type, col_order, 1, true};
return std::make_tuple(-1, cdef);
} else if (node->node_type == NodeType::string_value) {
// TODO right len
ColDefNode cdef = ColDefNode{col_name, ColumnType::varchar_type, col_order, 64, true};
return std::make_tuple(-1, cdef);
}
throw Exception("Unsupported node type");
@ -375,7 +430,7 @@ bool USql::eval_relational_operator(const RelationalOperatorNode &filter, Table
} else if (left_value->node_type == NodeType::bool_value && right_value->node_type == NodeType::bool_value) {
bool bl = left_value->getBooleanValue();
bool br = right_value->getBooleanValue();
comparator = bl == br ? 0 : 1; // TODO define it
comparator = bl == br ? 0 : 1;
// TODO handle dates
} else {
throw Exception("Undefined combination of types");
@ -410,7 +465,6 @@ std::unique_ptr<ValueNode> USql::eval_value_node(Table *table, Row &row, Node *n
} else if (node->node_type == NodeType::null_value) {
return std::make_unique<NullValueNode>();
} else if (node->node_type == NodeType::arithmetical_operator) {
// TODO correct type here
return eval_arithmetic_operator(ColumnType::float_type, static_cast<ArithmeticalOperatorNode &>(*node), table, row);
}
throw Exception("unsupported node type");
@ -584,7 +638,7 @@ std::unique_ptr<Table> USql::create_stmt_result_table(long code, const std::stri
Row& new_row = table_def->create_empty_row();
new_row.setIntColumnValue(0, code);
new_row.setStringColumnValue(1, text.size() <= 48 ? text : text.substr(0,48));
new_row.setIntColumnValue(2, affected_rows);
new_row.setIntColumnValue(2, (long)affected_rows);
table_def->commit_row(new_row);
return table_def;

2
usql.h
View File

@ -48,7 +48,7 @@ private:
static std::unique_ptr<Table> create_stmt_result_table(long code, const std::string &text, size_t affected_rows);
static std::tuple<int, ColDefNode> get_column_definition(Table *table, SelectColNode *select_col_node, int col_order) ;
static std::tuple<int, ColDefNode> get_column_definition2(Table *table, Node *select_col_node, const std::string & col_name, int col_order) ;
static std::tuple<int, ColDefNode> get_node_definition(Table *table, Node *select_col_node, const std::string & col_name, int col_order) ;
Table *find_table(const std::string &name);
void check_table_not_exists(const std::string &name);