diff --git a/src/Makefile b/src/Makefile index e1f4bfc..79d861f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -37,4 +37,5 @@ parser/bison_parser.cpp: clean: rm -f *.o *~ bin/analysis $(TESTS_BIN) bin/grammar_test + rm -rf build/ make clean -C parser/ diff --git a/src/build_and_run_tests.sh b/src/build_and_run_tests.sh index da3cd18..4e3370d 100644 --- a/src/build_and_run_tests.sh +++ b/src/build_and_run_tests.sh @@ -13,7 +13,8 @@ echo "\n\n" ./bin/grammar_test "SELECT a FROM foo WHERE a > 12 OR b > 3 AND c = 3 LIMIT 10" ./bin/grammar_test "SELECT col1, col2, 'test' FROM table, foo AS t WHERE age > 12 AND zipcode = 12345 GROUP BY col1;" ./bin/grammar_test "SELECT age FROM table AS t1, (SELECT * FROM table2) AS t2 ORDER BY age DESC" -./bin/grammar_test "SELECT * from table WHERE (b OR NOT a) AND a = 12.5 AS t1 JOIN table2 ON a = b" +./bin/grammar_test -f "SELECT * from table WHERE (b OR NOT a) AND a = 12.5 AS t1 JOIN table2 ON a = b" +./bin/grammar_test "SELECT * from table JOIN table2 ON a = b WHERE (b OR NOT a) AND a = 12.5" ./bin/grammar_test "(SELECT a FROM foo WHERE a > 12 OR b > 3 AND c = 3 LIMIT 10)" @@ -21,7 +22,8 @@ echo "\n\n" # ./bin/analysis "SELECT a FROM foo WHERE a > 12 OR b > 3 AND c = 3" ./bin/analysis "SELECT col1, col2, 'test' FROM table t1, foo WHERE age > 12 AND zipcode = 12345 GROUP BY col1 ORDER BY col2 DESC LIMIT 100;" -./bin/analysis "SELECT * from table WHERE (b OR NOT a) AND a = 12.5 AS t1 JOIN table2 AS t2 ON t1.a = t2.b" +./bin/analysis "SELECT * from table AS t1 JOIN table2 AS t2 ON t1.a = t2.b WHERE (b OR NOT a) AND a = 12.5" +./bin/analysis "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" # ./bin/analysis "SELECT * from table WHERE (b OR NOT a) AND a = 12.5 JOIN table2 ON a = b" echo "\n\n" \ No newline at end of file diff --git a/src/lib/Statement.h b/src/lib/Statement.h index 5879311..12941ba 100644 --- a/src/lib/Statement.h +++ b/src/lib/Statement.h @@ -14,7 +14,6 @@ namespace hsql { typedef enum { kStmtError, kStmtSelect, - kStmtJoin, kStmtDelete, kStmtInsert, kStmtCreate @@ -42,15 +41,6 @@ struct LimitDescription { }; -typedef enum { - kJoinInner, - kJoinOuter, - kJoinLeft, - kJoinRight -} JoinType; - - - struct Statement { Statement(StatementType type) : type(type) {}; @@ -74,16 +64,6 @@ struct SelectStatement : Statement { }; -struct JoinStatement : Statement { - JoinStatement() : Statement(kStmtJoin) {}; - - TableRef* left; - TableRef* right; - JoinType join_type; - Expr* join_condition; -}; - - struct DeleteStatement : Statement { // TODO }; diff --git a/src/lib/Table.h b/src/lib/Table.h index cdbe34d..db8764a 100644 --- a/src/lib/Table.h +++ b/src/lib/Table.h @@ -5,7 +5,6 @@ namespace hsql { class SelectStatement; -class JoinStatement; /** * TableRef @@ -18,6 +17,15 @@ typedef enum { kTableCrossProduct } TableRefType; + +typedef enum { + kJoinInner, + kJoinOuter, + kJoinLeft, + kJoinRight +} JoinType; + + typedef struct TableRef TableRef; struct TableRef { @@ -27,9 +35,15 @@ struct TableRef { char* name; char* alias; + SelectStatement* select; - JoinStatement* join; List* list; + + // Join memberbs + TableRef* left; + TableRef* right; + JoinType join_type; + Expr* join_condition; }; diff --git a/src/lib/sqlhelper.cpp b/src/lib/sqlhelper.cpp index 7c45e06..2ff0680 100644 --- a/src/lib/sqlhelper.cpp +++ b/src/lib/sqlhelper.cpp @@ -24,6 +24,15 @@ void printTableRefInfo(TableRef* table, uint num_indent) { case kTableSelect: printSelectStatementInfo(table->select, num_indent); break; + case kTableJoin: + inprint("Join Table", num_indent); + inprint("Left", num_indent+1); + printTableRefInfo(table->left, num_indent+2); + inprint("Right", num_indent+1); + printTableRefInfo(table->right, num_indent+2); + inprint("Join Condition", num_indent+1); + printExpression(table->join_condition, num_indent+2); + break; case kTableCrossProduct: for (TableRef* tbl : table->list->_vector) printTableRefInfo(tbl, num_indent); break; @@ -88,16 +97,5 @@ void printSelectStatementInfo(SelectStatement* stmt, uint num_indent) { } } -void printJoinStatementInfo(JoinStatement* stmt, uint num_indent) { - inprint("JoinStatement", num_indent); - inprint("JoinType:", num_indent+1); - inprintU(stmt->join_type, num_indent+2); - inprint("Left Table:", num_indent+1); - printTableRefInfo(stmt->left, num_indent+2); - inprint("Right Table:", num_indent+1); - printTableRefInfo(stmt->right, num_indent+2); - inprint("Join Condition:", num_indent+1); - printExpression(stmt->join_condition, num_indent+2); -} } // namespace hsql \ No newline at end of file diff --git a/src/lib/sqlhelper.h b/src/lib/sqlhelper.h index 49c4e3a..5613754 100644 --- a/src/lib/sqlhelper.h +++ b/src/lib/sqlhelper.h @@ -8,7 +8,6 @@ namespace hsql { void printSelectStatementInfo(SelectStatement* stmt, uint num_indent); -void printJoinStatementInfo(JoinStatement* stmt, uint num_indent); } // namespace hsql diff --git a/src/parser/bison_parser.y b/src/parser/bison_parser.y index fe800e6..41d6639 100644 --- a/src/parser/bison_parser.y +++ b/src/parser/bison_parser.y @@ -74,7 +74,6 @@ typedef void* yyscan_t; hsql::Statement* statement; hsql::SelectStatement* select_stmt; - hsql::JoinStatement* join_stmt; hsql::TableRef* table; hsql::Expr* expr; @@ -106,10 +105,9 @@ typedef void* yyscan_t; *********************************/ %type statement %type select_statement -%type join_statement %type table_name opt_alias alias %type from_clause table_ref table_ref_atomic table_ref_name -%type
join_table +%type
join_stmt join_table %type expr scalar_expr unary_expr binary_expr function_expr star_expr %type column_name literal int_literal num_literal %type comp_expr where_clause join_condition @@ -159,42 +157,11 @@ input: // Atm: only select statements (future: insert, delete, etc...) statement: select_statement { $$ = $1; } - | join_statement { $$ = $1; } ; -/****************************** - ** Join Statements - ******************************/ - -join_statement: - join_table JOIN join_table ON join_condition - { - $$ = new JoinStatement(); - $$->left = $1; - $$->right = $3; - $$->join_condition = $5; - $$->join_type = kJoinInner; - } - ; - - -join_table: - select_statement alias { - auto tbl = new TableRef(kTableSelect); - tbl->select = $1; - tbl->alias = $2; - $$ = tbl; - } - | table_ref_name; - - -join_condition: - expr - ; - /****************************** ** Select Statements @@ -333,11 +300,11 @@ star_expr: table_ref: table_ref_atomic | table_ref_atomic ',' table_ref_commalist { - $3->push_back($1); - auto tbl = new TableRef(kTableCrossProduct); - tbl->list = $3; - $$ = tbl; - } + $3->push_back($1); + auto tbl = new TableRef(kTableCrossProduct); + tbl->list = $3; + $$ = tbl; + } ; @@ -349,6 +316,7 @@ table_ref_atomic: tbl->alias = $4; $$ = tbl; } + | join_stmt ; @@ -382,6 +350,42 @@ opt_alias: alias | /* empty */ { $$ = NULL; } + +/****************************** + ** Join Statements + ******************************/ + +join_stmt: + join_table JOIN join_table ON join_condition + { + $$ = new TableRef(kTableJoin); + $$->left = $1; + $$->right = $3; + $$->join_condition = $5; + $$->join_type = kJoinInner; + } + ; + + +join_table: + '(' select_statement ')' alias { + auto tbl = new TableRef(kTableSelect); + tbl->select = $2; + tbl->alias = $4; + $$ = tbl; + } + | table_ref_name; + + +join_condition: + expr + ; + + +/****************************** + ** Misc + ******************************/ + opt_semicolon: ';' | /* empty */ diff --git a/src/sql_analysis.cpp b/src/sql_analysis.cpp index dfe7a66..980c7c5 100644 --- a/src/sql_analysis.cpp +++ b/src/sql_analysis.cpp @@ -25,8 +25,6 @@ int main(int argc, char *argv[]) { if (stmt->type == kStmtSelect) { printSelectStatementInfo((SelectStatement*) stmt, 0); - } else if (stmt->type == kStmtJoin) { - printJoinStatementInfo((JoinStatement*) stmt, 0); } else { if (stmt->type == kStmtError) { fprintf(stderr, "%s!\n", stmt->parser_msg);