diff --git a/usql.cpp b/usql.cpp index 924d031..73d5eaf 100644 --- a/usql.cpp +++ b/usql.cpp @@ -170,7 +170,7 @@ std::unique_ptr 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(col.name), col.name}); } } @@ -181,7 +181,7 @@ std::unique_ptr
USql::execute_select(SelectFromTableNode &node) { std::vector 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 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(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 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(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(select_col_node->value.get()); + } else if (node->node_type == NodeType::function) { + auto func_node = static_cast(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(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 USql::eval_value_node(Table *table, Row &row, Node *n } else if (node->node_type == NodeType::null_value) { return std::make_unique(); } else if (node->node_type == NodeType::arithmetical_operator) { - // TODO correct type here return eval_arithmetic_operator(ColumnType::float_type, static_cast(*node), table, row); } throw Exception("unsupported node type"); @@ -584,7 +638,7 @@ std::unique_ptr
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; diff --git a/usql.h b/usql.h index 62f0ef5..1de5c0c 100644 --- a/usql.h +++ b/usql.h @@ -48,7 +48,7 @@ private: static std::unique_ptr
create_stmt_result_table(long code, const std::string &text, size_t affected_rows); static std::tuple get_column_definition(Table *table, SelectColNode *select_col_node, int col_order) ; - static std::tuple get_column_definition2(Table *table, Node *select_col_node, const std::string & col_name, int col_order) ; + static std::tuple 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);