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);