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 <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 table_ref_name_no_alias | ||||||
| %type <expr> 		expr operand scalar_expr unary_expr binary_expr logic_expr exists_expr | %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>		function_expr between_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 | ||||||
| @ -229,7 +229,7 @@ int yyerror(YYLTYPE* llocp, SQLParserResult* result, yyscan_t scanner, const cha | |||||||
| %left		'[' ']' | %left		'[' ']' | ||||||
| %left		'(' ')' | %left		'(' ')' | ||||||
| %left		'.' | %left		'.' | ||||||
| 
 | %left   JOIN | ||||||
| %% | %% | ||||||
| /********************************* | /********************************* | ||||||
|  ** Section 3: Grammar Definition |  ** Section 3: Grammar Definition | ||||||
| @ -817,7 +817,7 @@ opt_alias: | |||||||
|  ******************************/ |  ******************************/ | ||||||
| 
 | 
 | ||||||
| join_clause: | 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); | 			$$ = new TableRef(kTableJoin); | ||||||
| 			$$->join = new JoinDefinition(); | 			$$->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: | join_condition: | ||||||
| 		expr | 		expr | ||||||
| 		; | 		; | ||||||
|  | |||||||
| @ -205,3 +205,45 @@ TEST(SelectCaseWhen) { | |||||||
|   ASSERT(caseExpr->expr->isSimpleOp('=')); |   ASSERT(caseExpr->expr->isSimpleOp('=')); | ||||||
|   ASSERT_EQ(caseExpr->exprList->size(), 2); |   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 TOP 10 * FROM t1 ORDER BY col1, col2; | ||||||
| SELECT a, MAX(b), MAX(c, d), CUSTOM(q, UP(r)) AS f FROM t1; | 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 * 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 | # 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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Pedro Flemming
						Pedro Flemming