added distinct

This commit is contained in:
Pedro 2014-12-18 12:28:24 +01:00
parent 3c98fe1bae
commit 57b062f2b0
5 changed files with 27 additions and 11 deletions

View File

@ -78,10 +78,11 @@ Expr* Expr::makeColumnRef(char* table, char* name) {
return e; return e;
} }
Expr* Expr::makeFunctionRef(char* func_name, Expr* expr) { Expr* Expr::makeFunctionRef(char* func_name, Expr* expr, bool distinct) {
Expr* e = new Expr(kExprFunctionRef); Expr* e = new Expr(kExprFunctionRef);
e->name = func_name; e->name = func_name;
e->expr = expr; e->expr = expr;
e->distinct = distinct;
return e; return e;
} }

View File

@ -22,6 +22,7 @@ typedef enum {
kExprOperator kExprOperator
} ExprType; } ExprType;
typedef struct Expr Expr; typedef struct Expr Expr;
/** /**
@ -79,6 +80,7 @@ struct Expr {
OperatorType op_type; OperatorType op_type;
char op_char; char op_char;
bool distinct;
/** /**
@ -109,7 +111,7 @@ struct Expr {
static Expr* makeColumnRef(char* name); static Expr* makeColumnRef(char* name);
static Expr* makeColumnRef(char* table, char* name); static Expr* makeColumnRef(char* table, char* name);
static Expr* makeFunctionRef(char* func_name, Expr* expr); static Expr* makeFunctionRef(char* func_name, Expr* expr, bool distinct);
}; };
// Zero initializes an Expr object and assigns it to a space in the heap // Zero initializes an Expr object and assigns it to a space in the heap

View File

@ -93,6 +93,7 @@ struct SelectStatement : SQLStatement {
} }
TableRef* from_table; TableRef* from_table;
bool select_distinct;
List<Expr*>* select_list; List<Expr*>* select_list;
Expr* where_clause; Expr* where_clause;
GroupByDescription* group_by; GroupByDescription* group_by;

View File

@ -171,7 +171,7 @@ int yyerror(YYLTYPE* llocp, SQLStatementList** result, yyscan_t scanner, const c
%type <update_stmt> update_statement %type <update_stmt> update_statement
%type <drop_stmt> drop_statement %type <drop_stmt> drop_statement
%type <sval> table_name opt_alias alias file_path %type <sval> table_name opt_alias alias file_path
%type <bval> opt_not_exists %type <bval> opt_not_exists opt_distinct
%type <uval> import_file_type opt_join_type column_type %type <uval> import_file_type opt_join_type column_type
%type <table> from_clause table_ref table_ref_atomic table_ref_name %type <table> from_clause table_ref table_ref_atomic table_ref_name
%type <table> join_clause join_table table_ref_name_no_alias %type <table> join_clause join_table table_ref_name_no_alias
@ -455,15 +455,20 @@ set_operator:
; ;
select_clause: select_clause:
SELECT select_list from_clause opt_where opt_group { SELECT opt_distinct select_list from_clause opt_where opt_group {
$$ = new SelectStatement(); $$ = new SelectStatement();
$$->select_list = $2; $$->select_distinct = $2;
$$->from_table = $3; $$->select_list = $3;
$$->where_clause = $4; $$->from_table = $4;
$$->group_by = $5; $$->where_clause = $5;
$$->group_by = $6;
} }
; ;
opt_distinct:
DISTINCT { $$ = true; }
| /* empty */ { $$ = false; }
;
select_list: select_list:
expr_list expr_list
@ -576,7 +581,7 @@ comp_expr:
; ;
function_expr: function_expr:
IDENTIFIER '(' expr ')' { $$ = Expr::makeFunctionRef($1, $3); } IDENTIFIER '(' opt_distinct expr ')' { $$ = Expr::makeFunctionRef($1, $4, $3); }
; ;
column_name: column_name:

View File

@ -16,6 +16,7 @@ TEST(SelectTest) {
TEST(SelectHavingTest) { TEST(SelectHavingTest) {
TEST_PARSE_SINGLE_SQL("SELECT city, AVG(grade) AS avg_grade FROM students GROUP BY city HAVING AVG(grade) < 2.0", kStmtSelect, SelectStatement, stmt); TEST_PARSE_SINGLE_SQL("SELECT city, AVG(grade) AS avg_grade FROM students GROUP BY city HAVING AVG(grade) < 2.0", kStmtSelect, SelectStatement, stmt);
ASSERT_FALSE(stmt->select_distinct);
GroupByDescription* group = stmt->group_by; GroupByDescription* group = stmt->group_by;
ASSERT_NOTNULL(group); ASSERT_NOTNULL(group);
@ -28,12 +29,18 @@ TEST(SelectHavingTest) {
TEST(SelectDistinctTest) { TEST(SelectDistinctTest) {
TEST_PARSE_SINGLE_SQL("SELECT DISTINCT grade, city FROM students;", kStmtSelect, SelectStatement, stmt); TEST_PARSE_SINGLE_SQL("SELECT DISTINCT grade, city FROM students;", kStmtSelect, SelectStatement, stmt);
ASSERT(stmt->select_distinct);
ASSERT_NULL(stmt->where_clause); ASSERT_NULL(stmt->where_clause);
} }
TEST(SelectGroupDistinctTest) { TEST(SelectGroupDistinctTest) {
TEST_PARSE_SINGLE_SQL("SELECT city, COUNT(DISTINCT name), SUM(DISTINCT grade) FROM students GROUP BY city;", kStmtSelect, SelectStatement, stmt); TEST_PARSE_SINGLE_SQL("SELECT city, COUNT(name), COUNT(DISTINCT grade) FROM students GROUP BY city;", kStmtSelect, SelectStatement, stmt);
ASSERT_NULL(stmt->where_clause);
ASSERT_FALSE(stmt->select_distinct);
ASSERT_EQ(stmt->select_list->size(), 3);
ASSERT(!stmt->select_list->at(1)->distinct);
ASSERT(stmt->select_list->at(2)->distinct);
} }