work on order by began

This commit is contained in:
2021-07-28 22:29:05 +02:00
parent 7d91319f0b
commit 34e432d031
10 changed files with 184 additions and 92 deletions

View File

@@ -155,8 +155,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);
@@ -176,8 +175,7 @@ std::unique_ptr<Table> USql::execute_select(SelectFromTableNode &node) {
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());
auto evaluated_value = eval_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);
@@ -192,9 +190,51 @@ std::unique_ptr<Table> USql::execute_select(SelectFromTableNode &node) {
}
}
// order by
execute_order_by(node, table, result);
return std::move(result);
}
void USql::execute_order_by(SelectFromTableNode &node, Table *table, std::__unique_if<Table>::__unique_single &result) const {
if (node.order_by.size() == 0) return;
auto compare_rows = [&node, &table, this](const Row &a, const Row &b) {
for(auto order_by_col_def : node.order_by) {
ColDefNode col_def = table->get_column_def(order_by_col_def.col_index - 1); // TODO validate index
ColValue *a_val = a.ith_column(col_def.order);
ColValue *b_val = b.ith_column(col_def.order);
if (a_val->isNull() && b_val->isNull()) return true; // both is null so a goes to end
if (!a_val->isNull() && b_val->isNull()) return true; // b is null so goes to end
if (a_val->isNull() && !b_val->isNull()) return false; // a is null so goes to end
int compare = compare_col_values(col_def, a_val, b_val);
if (compare < 0) return order_by_col_def.ascending ? true : false;
if (compare > 0) return order_by_col_def.ascending ? false : true;
}
return false;
};
result->m_rows.sort(compare_rows);
}
int USql::compare_col_values(const ColDefNode &col_def, ColValue *a_val, ColValue *b_val) const {
double c;
switch (col_def.type) {
case (ColumnType::integer_type):
return a_val->getIntValue() - b_val->getIntValue();
case (ColumnType::float_type):
c = a_val->getDoubleValue() - b_val->getDoubleValue();
return c < 0 ? -1 : c==0.0 ? 0 : 1;
case (ColumnType::varchar_type):
return a_val->getStringValue().compare(b_val->getStringValue());
default:
throw Exception("Unsupported data type");
}
}
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;