Allow order by to define a list of expressions to order by
This commit is contained in:
parent
36adab70c5
commit
f82504b319
|
@ -131,6 +131,7 @@ int yyerror(YYLTYPE* llocp, SQLParserResult** result, yyscan_t scanner, const ch
|
||||||
std::vector<hsql::ColumnDefinition*>* column_vec;
|
std::vector<hsql::ColumnDefinition*>* column_vec;
|
||||||
std::vector<hsql::UpdateClause*>* update_vec;
|
std::vector<hsql::UpdateClause*>* update_vec;
|
||||||
std::vector<hsql::Expr*>* expr_vec;
|
std::vector<hsql::Expr*>* expr_vec;
|
||||||
|
std::vector<hsql::OrderDescription*>* order_vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -146,7 +147,7 @@ int yyerror(YYLTYPE* llocp, SQLParserResult** result, yyscan_t scanner, const ch
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete ($$);
|
delete ($$);
|
||||||
} <str_vec> <table_vec> <column_vec> <update_vec> <expr_vec>
|
} <str_vec> <table_vec> <column_vec> <update_vec> <expr_vec> <order_vec>
|
||||||
%destructor { delete ($$); } <*>
|
%destructor { delete ($$); } <*>
|
||||||
|
|
||||||
|
|
||||||
|
@ -197,8 +198,8 @@ int yyerror(YYLTYPE* llocp, SQLParserResult** result, yyscan_t scanner, const ch
|
||||||
%type <expr> expr scalar_expr unary_expr binary_expr function_expr star_expr expr_alias placeholder_expr
|
%type <expr> expr scalar_expr unary_expr binary_expr function_expr star_expr expr_alias placeholder_expr
|
||||||
%type <expr> column_name literal int_literal num_literal string_literal
|
%type <expr> column_name literal int_literal num_literal string_literal
|
||||||
%type <expr> comp_expr opt_where join_condition opt_having
|
%type <expr> comp_expr opt_where join_condition opt_having
|
||||||
%type <order> opt_order
|
%type <limit> opt_limit opt_top
|
||||||
%type <limit> opt_limit
|
%type <order> order_desc
|
||||||
%type <order_type> opt_order_type
|
%type <order_type> opt_order_type
|
||||||
%type <column_t> column_def
|
%type <column_t> column_def
|
||||||
%type <update_t> update_clause
|
%type <update_t> update_clause
|
||||||
|
@ -207,6 +208,7 @@ int yyerror(YYLTYPE* llocp, SQLParserResult** result, yyscan_t scanner, const ch
|
||||||
%type <str_vec> ident_commalist opt_column_list
|
%type <str_vec> ident_commalist opt_column_list
|
||||||
%type <expr_vec> expr_list select_list literal_list
|
%type <expr_vec> expr_list select_list literal_list
|
||||||
%type <table_vec> table_ref_commalist
|
%type <table_vec> table_ref_commalist
|
||||||
|
%type <order_vec> opt_order order_list
|
||||||
%type <update_vec> update_clause_commalist
|
%type <update_vec> update_clause_commalist
|
||||||
%type <column_vec> column_def_commalist
|
%type <column_vec> column_def_commalist
|
||||||
|
|
||||||
|
@ -502,13 +504,14 @@ set_operator:
|
||||||
;
|
;
|
||||||
|
|
||||||
select_clause:
|
select_clause:
|
||||||
SELECT opt_distinct select_list from_clause opt_where opt_group {
|
SELECT opt_top opt_distinct select_list from_clause opt_where opt_group {
|
||||||
$$ = new SelectStatement();
|
$$ = new SelectStatement();
|
||||||
$$->selectDistinct = $2;
|
$$->limit = $2;
|
||||||
$$->selectList = $3;
|
$$->selectDistinct = $3;
|
||||||
$$->fromTable = $4;
|
$$->selectList = $4;
|
||||||
$$->whereClause = $5;
|
$$->fromTable = $5;
|
||||||
$$->groupBy = $6;
|
$$->whereClause = $6;
|
||||||
|
$$->groupBy = $7;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -521,7 +524,6 @@ select_list:
|
||||||
expr_list
|
expr_list
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
from_clause:
|
from_clause:
|
||||||
FROM table_ref { $$ = $2; }
|
FROM table_ref { $$ = $2; }
|
||||||
;
|
;
|
||||||
|
@ -546,16 +548,31 @@ opt_having:
|
||||||
| /* empty */ { $$ = NULL; }
|
| /* empty */ { $$ = NULL; }
|
||||||
|
|
||||||
opt_order:
|
opt_order:
|
||||||
ORDER BY expr opt_order_type { $$ = new OrderDescription($4, $3); }
|
ORDER BY order_list { $$ = $3; }
|
||||||
| /* empty */ { $$ = NULL; }
|
| /* empty */ { $$ = NULL; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
order_list:
|
||||||
|
order_desc { $$ = new std::vector<OrderDescription*>(); $$->push_back($1); }
|
||||||
|
| order_list ',' order_desc { $1->push_back($3); $$ = $1; }
|
||||||
|
;
|
||||||
|
|
||||||
|
order_desc:
|
||||||
|
expr opt_order_type { $$ = new OrderDescription($2, $1); }
|
||||||
|
;
|
||||||
|
|
||||||
opt_order_type:
|
opt_order_type:
|
||||||
ASC { $$ = kOrderAsc; }
|
ASC { $$ = kOrderAsc; }
|
||||||
| DESC { $$ = kOrderDesc; }
|
| DESC { $$ = kOrderDesc; }
|
||||||
| /* empty */ { $$ = kOrderAsc; }
|
| /* empty */ { $$ = kOrderAsc; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
// TODO: TOP and LIMIT can take more than just int literals.
|
||||||
|
|
||||||
|
opt_top:
|
||||||
|
TOP int_literal { $$ = new LimitDescription($2->ival, kNoOffset); delete $2; }
|
||||||
|
| /* empty */ { $$ = NULL; }
|
||||||
|
;
|
||||||
|
|
||||||
opt_limit:
|
opt_limit:
|
||||||
LIMIT int_literal { $$ = new LimitDescription($2->ival, kNoOffset); delete $2; }
|
LIMIT int_literal { $$ = new LimitDescription($2->ival, kNoOffset); delete $2; }
|
||||||
|
|
|
@ -63,7 +63,7 @@ namespace hsql {
|
||||||
GroupByDescription* groupBy;
|
GroupByDescription* groupBy;
|
||||||
|
|
||||||
SelectStatement* unionSelect;
|
SelectStatement* unionSelect;
|
||||||
OrderDescription* order;
|
std::vector<OrderDescription*>* order;
|
||||||
LimitDescription* limit;
|
LimitDescription* limit;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -139,8 +139,8 @@ namespace hsql {
|
||||||
|
|
||||||
if (stmt->order != NULL) {
|
if (stmt->order != NULL) {
|
||||||
inprint("OrderBy:", numIndent + 1);
|
inprint("OrderBy:", numIndent + 1);
|
||||||
printExpression(stmt->order->expr, numIndent + 2);
|
printExpression(stmt->order->at(0)->expr, numIndent + 2);
|
||||||
if (stmt->order->type == kOrderAsc) inprint("ascending", numIndent + 2);
|
if (stmt->order->at(0)->type == kOrderAsc) inprint("ascending", numIndent + 2);
|
||||||
else inprint("descending", numIndent + 2);
|
else inprint("descending", numIndent + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,3 +73,23 @@ TEST(SelectGroupDistinctTest) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST(OrderByTest) {
|
||||||
|
TEST_PARSE_SINGLE_SQL(
|
||||||
|
"SELECT grade, city FROM students ORDER BY grade, city DESC;",
|
||||||
|
kStmtSelect,
|
||||||
|
SelectStatement,
|
||||||
|
result,
|
||||||
|
stmt);
|
||||||
|
|
||||||
|
ASSERT_NULL(stmt->whereClause);
|
||||||
|
ASSERT_NOTNULL(stmt->order);
|
||||||
|
|
||||||
|
ASSERT_EQ(stmt->order->size(), 2);
|
||||||
|
ASSERT_EQ(stmt->order->at(0)->type, kOrderAsc);
|
||||||
|
ASSERT_STREQ(stmt->order->at(0)->expr->name, "grade");
|
||||||
|
|
||||||
|
ASSERT_EQ(stmt->order->at(1)->type, kOrderDesc);
|
||||||
|
ASSERT_STREQ(stmt->order->at(1)->expr->name, "city");
|
||||||
|
|
||||||
|
delete result;
|
||||||
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ SELECT * FROM "table" LIMIT 10 OFFSET 10; SELECT * FROM second;
|
||||||
SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY col1;
|
SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY col1;
|
||||||
SELECT * FROM (SELECT * FROM t1);
|
SELECT * FROM (SELECT * FROM t1);
|
||||||
SELECT * FROM t1 UNION (SELECT * FROM t2 UNION SELECT * FROM t3) ORDER BY col1;
|
SELECT * FROM t1 UNION (SELECT * FROM t2 UNION SELECT * FROM t3) ORDER BY col1;
|
||||||
|
SELECT TOP 10 * FROM t1 ORDER BY col1, col2;
|
||||||
# JOIN
|
# JOIN
|
||||||
SELECT t1.a, t1.b, t2.c FROM "table" AS t1 JOIN (SELECT * FROM foo JOIN bar ON foo.id = bar.id) t2 ON t1.a = t2.b WHERE (t1.b OR NOT t1.a) AND t2.c = 12.5
|
SELECT t1.a, t1.b, t2.c FROM "table" AS t1 JOIN (SELECT * FROM foo JOIN bar ON foo.id = bar.id) t2 ON t1.a = t2.b WHERE (t1.b OR NOT t1.a) AND t2.c = 12.5
|
||||||
SELECT * FROM t1 JOIN t2 ON c1 = c2;
|
SELECT * FROM t1 JOIN t2 ON c1 = c2;
|
||||||
|
|
Loading…
Reference in New Issue