simple distinct added

This commit is contained in:
VaclavT 2021-08-01 14:31:19 +02:00
parent 4a344d0e77
commit 50a7993a2e
9 changed files with 41 additions and 12 deletions

View File

@ -197,6 +197,8 @@ namespace usql {
return TokenType::keyword_float; return TokenType::keyword_float;
if (token == "varchar") if (token == "varchar")
return TokenType::keyword_varchar; return TokenType::keyword_varchar;
if (token == "distinct")
return TokenType::keyword_distinct;
if (token == "or") if (token == "or")
return TokenType::logical_or; return TokenType::logical_or;
if (token == "and") if (token == "and")
@ -382,6 +384,9 @@ namespace usql {
case TokenType::keyword_varchar: case TokenType::keyword_varchar:
txt = "varchar"; txt = "varchar";
break; break;
case TokenType::keyword_distinct:
txt = "distinct";
break;
case TokenType::int_number: case TokenType::int_number:
txt = "int number"; txt = "int number";
break; break;

View File

@ -47,6 +47,7 @@ namespace usql {
keyword_integer, keyword_integer,
keyword_float, keyword_float,
keyword_varchar, keyword_varchar,
keyword_distinct,
int_number, int_number,
double_number, double_number,
string_literal, string_literal,

View File

@ -18,6 +18,7 @@ int main(int argc, char *argv[]) {
"insert into a (i, s) values(to_date('20.12.1973', '%d.%m.%Y'), 'six')", "insert into a (i, s) values(to_date('20.12.1973', '%d.%m.%Y'), 'six')",
"save table a into '/tmp/a.csv'", "save table a into '/tmp/a.csv'",
"select i, s from a where i > 2 order by 1 desc offset 1 limit 1", "select i, s from a where i > 2 order by 1 desc offset 1 limit 1",
"select distinct s from a",
// "select i, s from a where i = 1", // "select i, s from a where i = 1",
// "select i, s from a where s = 'two'", // "select i, s from a where s = 'two'",
// "select i, s from a where i <= 3 and s = 'one'", // "select i, s from a where i <= 3 and s = 'one'",

View File

@ -208,10 +208,16 @@ namespace usql {
} }
std::unique_ptr<Node> Parser::parse_select_from_table() { std::unique_ptr<Node> Parser::parse_select_from_table() {
bool distinct = false;
auto cols = std::make_unique<std::vector<SelectColNode>>(); auto cols = std::make_unique<std::vector<SelectColNode>>();
m_lexer.skipToken(TokenType::keyword_select); m_lexer.skipToken(TokenType::keyword_select);
if (m_lexer.tokenType() == TokenType::keyword_distinct) {
distinct = true;
m_lexer.skipToken(TokenType::keyword_distinct);
}
int i = 1; int i = 1;
while (m_lexer.tokenType() != TokenType::keyword_from) { while (m_lexer.tokenType() != TokenType::keyword_from) {
auto column_value = parse_value(); auto column_value = parse_value();
@ -240,7 +246,7 @@ namespace usql {
OffsetLimitNode offsetlimit_node = parse_offset_limit_clause(); OffsetLimitNode offsetlimit_node = parse_offset_limit_clause();
return std::make_unique<SelectFromTableNode>(table_name, std::move(cols), std::move(where_node), orderby_node, offsetlimit_node); return std::make_unique<SelectFromTableNode>(table_name, std::move(cols), std::move(where_node), orderby_node, offsetlimit_node, distinct);
} }
std::unique_ptr<Node> Parser::parse_delete_from_table() { std::unique_ptr<Node> Parser::parse_delete_from_table() {

View File

@ -239,9 +239,10 @@ namespace usql {
std::unique_ptr<Node> where; std::unique_ptr<Node> where;
std::vector<ColOrderNode> order_by; std::vector<ColOrderNode> order_by;
OffsetLimitNode offset_limit; OffsetLimitNode offset_limit;
bool distinct;
SelectFromTableNode(std::string name, std::unique_ptr<std::vector<SelectColNode>> names, std::unique_ptr<Node> where_clause, std::vector<ColOrderNode> orderby, OffsetLimitNode offlim) : SelectFromTableNode(std::string name, std::unique_ptr<std::vector<SelectColNode>> names, std::unique_ptr<Node> where_clause, std::vector<ColOrderNode> orderby, OffsetLimitNode offlim, bool distinct_):
Node(NodeType::select_from), table_name(name), cols_names(std::move(names)), where(std::move(where_clause)), order_by(orderby), offset_limit(offlim) {} Node(NodeType::select_from), table_name(name), cols_names(std::move(names)), where(std::move(where_clause)), order_by(orderby), offset_limit(offlim), distinct(distinct_) {}
}; };
struct CreateTableAsSelectNode : Node { struct CreateTableAsSelectNode : Node {

View File

@ -97,6 +97,14 @@ namespace usql {
} }
} }
int Row::compare(const Row & other) const {
for (int ci = 0; ci < m_columns.size(); ci++) {
int cmp = m_columns[ci]->compare(other.ith_column(ci));
if (cmp != 0) return cmp;
}
return 0;
}
void Row::print(const std::vector<int> & col_char_sizes) { void Row::print(const std::vector<int> & col_char_sizes) {
std::string out{"| "}; std::string out{"| "};

10
row.h
View File

@ -84,6 +84,7 @@ namespace usql {
Row(const Row &other); Row(const Row &other);
Row &operator=(Row other); Row &operator=(Row other);
bool operator==(const Row &other) const {return this->compare(other) == 0; };
void setColumnNull(int col_index); void setColumnNull(int col_index);
void setColumnValue(int col_index, long value); void setColumnValue(int col_index, long value);
@ -92,13 +93,10 @@ namespace usql {
void setColumnValue(ColDefNode *col_def, ColValue *col_value); void setColumnValue(ColDefNode *col_def, ColValue *col_value);
void setColumnValue(ColDefNode *col_def, ValueNode *col_value); void setColumnValue(ColDefNode *col_def, ValueNode *col_value);
ColValue &operator[](int i) { ColValue &operator[](int i) { return *m_columns[i]; }
return *m_columns[i];
}
ColValue * ith_column(int i) const { ColValue * ith_column(int i) const { return m_columns[i].get(); }
return m_columns[i].get(); int compare(const Row &other) const;
}
void print(const std::vector<int> & col_char_sizes); void print(const std::vector<int> & col_char_sizes);

View File

@ -190,15 +190,24 @@ std::unique_ptr<Table> USql::execute_select(SelectFromTableNode &node) {
} }
} }
// order by execute_distinct(node, result.get());
execute_order_by(node, table, result.get()); execute_order_by(node, table, result.get());
// offset & limit
execute_offset_limit(node.offset_limit, result.get()); execute_offset_limit(node.offset_limit, result.get());
return std::move(result); return std::move(result);
} }
void USql::execute_distinct(SelectFromTableNode &node, Table *result) const {
if (!node.distinct) return;
auto compare_rows = [](const Row &a, const Row &b) { return a.compare(b) >= 0; };
std::sort(result->m_rows.begin(), result->m_rows.end(), compare_rows);
result->m_rows.erase(std::unique(result->m_rows.begin(), result->m_rows.end()), result->m_rows.end());
}
void USql::execute_order_by(SelectFromTableNode &node, Table *table, Table *result) const { void USql::execute_order_by(SelectFromTableNode &node, Table *table, Table *result) const {
if (node.order_by.size() == 0) return; if (node.order_by.size() == 0) return;

2
usql.h
View File

@ -55,8 +55,8 @@ private:
Parser m_parser; Parser m_parser;
std::list<Table> m_tables; std::list<Table> m_tables;
void execute_distinct(SelectFromTableNode &node, Table *result) const;
void execute_order_by(SelectFromTableNode &node, Table *table, Table *result) const; void execute_order_by(SelectFromTableNode &node, Table *table, Table *result) const;
void execute_offset_limit(OffsetLimitNode &node, Table *result) const; void execute_offset_limit(OffsetLimitNode &node, Table *result) const;
}; };