simple distinct added
This commit is contained in:
parent
4a344d0e77
commit
50a7993a2e
|
|
@ -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;
|
||||||
|
|
|
||||||
1
lexer.h
1
lexer.h
|
|
@ -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,
|
||||||
|
|
|
||||||
1
main.cpp
1
main.cpp
|
|
@ -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'",
|
||||||
|
|
|
||||||
|
|
@ -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() {
|
||||||
|
|
|
||||||
5
parser.h
5
parser.h
|
|
@ -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 {
|
||||||
|
|
|
||||||
8
row.cpp
8
row.cpp
|
|
@ -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
10
row.h
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
13
usql.cpp
13
usql.cpp
|
|
@ -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
2
usql.h
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue