Add capability for multi join table references (#40)
This commit is contained in:
parent
0909c6a89a
commit
793258f872
File diff suppressed because it is too large
Load Diff
|
@ -188,7 +188,7 @@ int yyerror(YYLTYPE* llocp, SQLParserResult* result, yyscan_t scanner, const cha
|
|||
%type <bval> opt_not_exists opt_distinct
|
||||
%type <uval> import_file_type opt_join_type column_type
|
||||
%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 table_ref_name_no_alias
|
||||
%type <expr> expr operand scalar_expr unary_expr binary_expr logic_expr exists_expr
|
||||
%type <expr> function_expr between_expr star_expr expr_alias placeholder_expr
|
||||
%type <expr> column_name literal int_literal num_literal string_literal
|
||||
|
@ -225,11 +225,11 @@ int yyerror(YYLTYPE* llocp, SQLParserResult* result, yyscan_t scanner, const cha
|
|||
%left '^'
|
||||
|
||||
/* Unary Operators */
|
||||
%right UMINUS
|
||||
%right UMINUS
|
||||
%left '[' ']'
|
||||
%left '(' ')'
|
||||
%left '.'
|
||||
|
||||
%left JOIN
|
||||
%%
|
||||
/*********************************
|
||||
** Section 3: Grammar Definition
|
||||
|
@ -817,7 +817,7 @@ opt_alias:
|
|||
******************************/
|
||||
|
||||
join_clause:
|
||||
join_table opt_join_type JOIN join_table ON join_condition
|
||||
table_ref_atomic opt_join_type JOIN table_ref_atomic ON join_condition
|
||||
{
|
||||
$$ = new TableRef(kTableJoin);
|
||||
$$->join = new JoinDefinition();
|
||||
|
@ -841,17 +841,6 @@ opt_join_type:
|
|||
;
|
||||
|
||||
|
||||
|
||||
join_table:
|
||||
'(' select_statement ')' alias {
|
||||
auto tbl = new TableRef(kTableSelect);
|
||||
tbl->select = $2;
|
||||
tbl->alias = $4;
|
||||
$$ = tbl;
|
||||
}
|
||||
| table_ref_name;
|
||||
|
||||
|
||||
join_condition:
|
||||
expr
|
||||
;
|
||||
|
|
|
@ -205,3 +205,45 @@ TEST(SelectCaseWhen) {
|
|||
ASSERT(caseExpr->expr->isSimpleOp('='));
|
||||
ASSERT_EQ(caseExpr->exprList->size(), 2);
|
||||
}
|
||||
|
||||
TEST(SelectJoin) {
|
||||
TEST_PARSE_SINGLE_SQL(
|
||||
"SELECT City.name, Product.category, SUM(price) FROM fact\
|
||||
INNER JOIN City ON fact.city_id = City.id\
|
||||
OUTER JOIN Product ON fact.product_id = Product.id\
|
||||
GROUP BY City.name, Product.category;",
|
||||
kStmtSelect,
|
||||
SelectStatement,
|
||||
result,
|
||||
stmt);
|
||||
|
||||
const TableRef* table = stmt->fromTable;
|
||||
const JoinDefinition* outer_join = table->join;
|
||||
ASSERT_EQ(table->type, kTableJoin);
|
||||
ASSERT_EQ(outer_join->type, kJoinOuter);
|
||||
|
||||
ASSERT_EQ(outer_join->right->type, kTableName);
|
||||
ASSERT_STREQ(outer_join->right->name, "Product");
|
||||
ASSERT(outer_join->condition->isSimpleOp('='));
|
||||
ASSERT_STREQ(outer_join->condition->expr->table, "fact");
|
||||
ASSERT_STREQ(outer_join->condition->expr->name, "product_id");
|
||||
ASSERT_STREQ(outer_join->condition->expr2->table, "Product");
|
||||
ASSERT_STREQ(outer_join->condition->expr2->name, "id");
|
||||
|
||||
// Joins are are left associative.
|
||||
// So the second join should be on the left.
|
||||
ASSERT_EQ(outer_join->left->type, kTableJoin);
|
||||
|
||||
const JoinDefinition* inner_join = outer_join->left->join;
|
||||
ASSERT_EQ(inner_join->type, kJoinInner);
|
||||
ASSERT_EQ(inner_join->left->type, kTableName);
|
||||
ASSERT_STREQ(inner_join->left->name, "fact");
|
||||
ASSERT_EQ(inner_join->right->type, kTableName);
|
||||
ASSERT_STREQ(inner_join->right->name, "City");
|
||||
|
||||
ASSERT(inner_join->condition->isSimpleOp('='));
|
||||
ASSERT_STREQ(inner_join->condition->expr->table, "fact");
|
||||
ASSERT_STREQ(inner_join->condition->expr->name, "city_id");
|
||||
ASSERT_STREQ(inner_join->condition->expr2->table, "City");
|
||||
ASSERT_STREQ(inner_join->condition->expr2->name, "id");
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ SELECT * FROM t1 UNION (SELECT * FROM t2 UNION SELECT * FROM t3) ORDER BY col1;
|
|||
SELECT TOP 10 * FROM t1 ORDER BY col1, col2;
|
||||
SELECT a, MAX(b), MAX(c, d), CUSTOM(q, UP(r)) AS f FROM t1;
|
||||
SELECT * FROM t WHERE a BETWEEN 1 and c;
|
||||
SELECT City.name, Product.category, SUM(price) FROM fact INNER JOIN City ON fact.city_id = City.id INNER JOIN Product ON fact.product_id = Product.id GROUP BY City.name, Product.category;
|
||||
# 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 * FROM t1 JOIN t2 ON c1 = c2;
|
||||
|
|
Loading…
Reference in New Issue