From 070ea2de28601269f6b14ff8a7473159353a38a4 Mon Sep 17 00:00:00 2001 From: Pedro Date: Mon, 17 Nov 2014 22:13:11 +0100 Subject: [PATCH] added join types and algorithms --- src/lib/Table.h | 69 +++++++++++++++++++++++++++---------- src/lib/destructors.cpp | 31 +++++++++-------- src/lib/sqlhelper.cpp | 6 ++-- src/parser/bison_parser.y | 37 ++++++++++++++------ src/parser/flex_lexer.l | 3 ++ src/parser/sql_keywords.txt | 3 ++ test/valid_queries.sql | 4 ++- 7 files changed, 106 insertions(+), 47 deletions(-) diff --git a/src/lib/Table.h b/src/lib/Table.h index a1951f2..f5ba457 100644 --- a/src/lib/Table.h +++ b/src/lib/Table.h @@ -2,9 +2,12 @@ #define __TABLEREF_H__ #include + namespace hsql { -class SelectStatement; +struct SelectStatement; +struct JoinDefinition; +struct TableRef; /** * TableRef @@ -18,16 +21,8 @@ typedef enum { } TableRefType; -typedef enum { - kJoinInner, - kJoinOuter, - kJoinLeft, - kJoinRight -} JoinType; -typedef struct TableRef TableRef; - struct TableRef { TableRef(TableRefType type) : type(type), @@ -36,9 +31,7 @@ struct TableRef { alias(NULL), select(NULL), list(NULL), - left(NULL), - right(NULL), - join_condition(NULL) {} + join(NULL) {} virtual ~TableRef(); // defined in destructors.cpp @@ -50,12 +43,7 @@ struct TableRef { SelectStatement* select; List* list; - - // Join members - TableRef* left; - TableRef* right; - JoinType join_type; - Expr* join_condition; + JoinDefinition* join; /** @@ -70,6 +58,49 @@ struct TableRef { }; -} // namespace hsql +/** + * Following are definitions needed to specify join tables + */ +typedef enum { + kJoinInner, + kJoinOuter, + kJoinLeft, + kJoinRight, +} JoinType; + +/** + * Specifying a join algorithm is not standard. + * This is specific to Hyrise. + */ +typedef enum { + kJoinAlgoScan, + kJoinAlgoHash, + kJoinAlgoRadix +} JoinAlgorithm; + +/** + * Definition of a join table + */ +struct JoinDefinition { + JoinDefinition() : + left(NULL), + right(NULL), + condition(NULL), + type(kJoinInner), + algorithm(kJoinAlgoScan) {} + + virtual ~JoinDefinition(); // defined in destructors.cpp + + TableRef* left; + TableRef* right; + Expr* condition; + + JoinType type; + JoinAlgorithm algorithm; +}; + + + +} // namespace hsql #endif diff --git a/src/lib/destructors.cpp b/src/lib/destructors.cpp index add324c..6cd803b 100644 --- a/src/lib/destructors.cpp +++ b/src/lib/destructors.cpp @@ -12,16 +12,6 @@ StatementList::~StatementList() { delete parser_msg; } -TableRef::~TableRef() { - delete name; - delete alias; - delete select; - delete list; - delete left; - delete right; - delete join_condition; -} - SelectStatement::~SelectStatement() { delete from_table; delete select_list; @@ -31,10 +21,6 @@ SelectStatement::~SelectStatement() { delete limit; } -OrderDescription::~OrderDescription() { - delete expr; -} - ImportStatement::~ImportStatement() { delete file_path; delete table_name; @@ -45,4 +31,21 @@ CreateStatement::~CreateStatement() { delete table_name; } +OrderDescription::~OrderDescription() { + delete expr; +} + +TableRef::~TableRef() { + delete name; + delete alias; + delete select; + delete list; +} + +JoinDefinition::~JoinDefinition() { + delete left; + delete right; + delete condition; +} + } // namespace hsql \ No newline at end of file diff --git a/src/lib/sqlhelper.cpp b/src/lib/sqlhelper.cpp index 9b22100..e062169 100644 --- a/src/lib/sqlhelper.cpp +++ b/src/lib/sqlhelper.cpp @@ -27,11 +27,11 @@ void printTableRefInfo(TableRef* table, uint num_indent) { case kTableJoin: inprint("Join Table", num_indent); inprint("Left", num_indent+1); - printTableRefInfo(table->left, num_indent+2); + printTableRefInfo(table->join->left, num_indent+2); inprint("Right", num_indent+1); - printTableRefInfo(table->right, num_indent+2); + printTableRefInfo(table->join->right, num_indent+2); inprint("Join Condition", num_indent+1); - printExpression(table->join_condition, num_indent+2); + printExpression(table->join->condition, num_indent+2); break; case kTableCrossProduct: for (TableRef* tbl : table->list->vector()) printTableRefInfo(tbl, num_indent); diff --git a/src/parser/bison_parser.y b/src/parser/bison_parser.y index c84c48b..1dd0040 100644 --- a/src/parser/bison_parser.y +++ b/src/parser/bison_parser.y @@ -109,9 +109,10 @@ typedef void* yyscan_t; %token DATABASE DISTINCT BETWEEN CONTROL NATURAL COLUMN %token CREATE DELETE EXISTS HAVING IMPORT INSERT ISNULL %token OFFSET RENAME SELECT UNLOAD UPDATE ALTER CROSS GROUP -%token INDEX INNER LIMIT ORDER OUTER RIGHT TABLE UNION USING -%token WHERE DESC DROP FILE FROM INTO JOIN LEFT LIKE LOAD -%token NULL ALL AND ASC CSV NOT TBL TOP AS BY IF IN IS ON OR +%token INDEX INNER LIMIT ORDER OUTER RADIX RIGHT TABLE UNION +%token USING WHERE DESC DROP FILE FROM HASH INTO JOIN LEFT +%token LIKE LOAD NULL SCAN ALL AND ASC CSV NOT TBL TOP AS BY +%token IF IN IS ON OR /********************************* @@ -134,8 +135,7 @@ typedef void* yyscan_t; %type opt_order %type opt_limit %type opt_order_type -%type import_file_type - +%type import_file_type opt_join_type opt_join_algorithm /****************************** ** Token Precedence and Associativity @@ -466,16 +466,33 @@ opt_alias: ******************************/ join_clause: - join_table JOIN join_table ON join_condition + join_table opt_join_algorithm opt_join_type JOIN join_table ON join_condition { $$ = new TableRef(kTableJoin); - $$->left = $1; - $$->right = $3; - $$->join_condition = $5; - $$->join_type = kJoinInner; + $$->join = new JoinDefinition(); + $$->join->type = (JoinType) $2; + $$->join->algorithm = (JoinAlgorithm) $3; + $$->join->left = $1; + $$->join->right = $5; + $$->join->condition = $7; } ; +opt_join_type: + INNER { $$ = kJoinInner; } + | OUTER { $$ = kJoinOuter; } + | LEFT { $$ = kJoinLeft; } + | RIGHT { $$ = kJoinRight; } + | /* empty, default */ { $$ = kJoinInner; } + ; + +opt_join_algorithm: + SCAN { $$ = kJoinAlgoScan; } + | HASH { $$ = kJoinAlgoHash; } + | RADIX { $$ = kJoinAlgoRadix; } + | /* empty, default */ { $$ = kJoinAlgoScan; } + + join_table: '(' select_statement ')' alias { diff --git a/src/parser/flex_lexer.l b/src/parser/flex_lexer.l index 6b1a518..a129951 100644 --- a/src/parser/flex_lexer.l +++ b/src/parser/flex_lexer.l @@ -83,6 +83,7 @@ INNER TOKEN(INNER) LIMIT TOKEN(LIMIT) ORDER TOKEN(ORDER) OUTER TOKEN(OUTER) +RADIX TOKEN(RADIX) RIGHT TOKEN(RIGHT) TABLE TOKEN(TABLE) UNION TOKEN(UNION) @@ -92,12 +93,14 @@ DESC TOKEN(DESC) DROP TOKEN(DROP) FILE TOKEN(FILE) FROM TOKEN(FROM) +HASH TOKEN(HASH) INTO TOKEN(INTO) JOIN TOKEN(JOIN) LEFT TOKEN(LEFT) LIKE TOKEN(LIKE) LOAD TOKEN(LOAD) NULL TOKEN(NULL) +SCAN TOKEN(SCAN) ALL TOKEN(ALL) AND TOKEN(AND) ASC TOKEN(ASC) diff --git a/src/parser/sql_keywords.txt b/src/parser/sql_keywords.txt index 312ef4f..0e2e44e 100644 --- a/src/parser/sql_keywords.txt +++ b/src/parser/sql_keywords.txt @@ -27,6 +27,9 @@ RIGHT CROSS USING NATURAL +HASH +RADIX +SCAN // Create statement CREATE diff --git a/test/valid_queries.sql b/test/valid_queries.sql index 626c555..a2cb3b3 100644 --- a/test/valid_queries.sql +++ b/test/valid_queries.sql @@ -4,11 +4,13 @@ SELECT a FROM foo WHERE a > 12 OR b > 3 AND NOT c LIMIT 10 SELECT col1 AS myname, col2, 'test' FROM "table", foo AS t WHERE age > 12 AND zipcode = 12345 GROUP BY col1; SELECT * from "table" JOIN table2 ON a = b WHERE (b OR NOT a) AND a = 12.5 (SELECT a FROM foo WHERE a > 12 OR b > 3 AND c NOT LIKE 's%' LIMIT 10); -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 "table" LIMIT 10 OFFSET 10; SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY col1; SELECT * FROM t1 UNION (SELECT * FROM t2) ORDER BY col1; SELECT * FROM t1 UNION (SELECT * FROM t2 UNION SELECT * FROM t3) ORDER BY col1; +# 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 HASH JOIN t2 ON c1 = c2; # CREATE statement CREATE TABLE "table" FROM TBL FILE 'students.tbl' CREATE TABLE IF NOT EXISTS "table" FROM TBL FILE 'students.tbl'