From 7c30786b53a00c6b75db2e96b2fb335481ad4e14 Mon Sep 17 00:00:00 2001 From: Pedro Date: Fri, 7 Nov 2014 01:09:06 +0100 Subject: [PATCH] now parsing ImportStatements --- src/build_and_run_tests.sh | 14 +++++---- src/lib/ImportStatement.h | 36 +++++++++++++++++++++++ src/lib/SelectStatement.h | 60 ++++++++++++++++++++++++++++++++++++++ src/lib/Statement.h | 60 +++++--------------------------------- src/lib/sqlhelper.h | 2 +- src/lib/sqllib.h | 8 +++++ src/parser/SQLParser.h | 2 +- src/parser/bison_parser.y | 44 +++++++++++++++++++++++----- src/parser/flex_lexer.l | 6 +++- src/sql_grammar_test.cpp | 2 +- 10 files changed, 163 insertions(+), 71 deletions(-) create mode 100644 src/lib/ImportStatement.h create mode 100644 src/lib/SelectStatement.h create mode 100644 src/lib/sqllib.h diff --git a/src/build_and_run_tests.sh b/src/build_and_run_tests.sh index 3227fa9..ea396d7 100644 --- a/src/build_and_run_tests.sh +++ b/src/build_and_run_tests.sh @@ -17,19 +17,21 @@ echo "\n\n" ./bin/grammar_test "(SELECT a FROM foo WHERE a > 12 OR b > 3 AND c NOT LIKE 's%' LIMIT 10);" ./bin/grammar_test "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/grammar_test "IMPORT FROM TBL FILE 'students.tbl' INTO table" + # Error: Where clause in between join statement -./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 -f "SELECT * 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 -f "SELECT * table WHERE (b OR NOT a) AND a = 12.5 AS t1 JOIN table2 ON a = b" 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 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 "-- test -SELECT * FROM table WHERE a NOT LIKE '%s' -- inline comment ---my comment" +# ./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 "-- test +# SELECT * FROM table WHERE a NOT LIKE '%s' -- inline comment +# --my comment" # ./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/ImportStatement.h b/src/lib/ImportStatement.h new file mode 100644 index 0000000..5ecc7c1 --- /dev/null +++ b/src/lib/ImportStatement.h @@ -0,0 +1,36 @@ +#ifndef __IMPORT_STATEMENT_H__ +#define __IMPORT_STATEMENT_H__ + +#include "Statement.h" + +namespace hsql { + + +typedef enum { + kImportCSV, + kImportTbl, // Hyrise file format + // HANA supports a second file type CONTROL FILE + // we don't need that so far, but we leave the option + // to expand it here +} ImportFileType; + + +/** + * @struct ImportStatement + */ +struct ImportStatement : Statement { + ImportStatement() : Statement(kStmtSelect) {}; + + ImportFileType file_type; + const char* file_path; + const char* table_name; + + +}; + + + +} // namespace hsql + + +#endif \ No newline at end of file diff --git a/src/lib/SelectStatement.h b/src/lib/SelectStatement.h new file mode 100644 index 0000000..a44cb9c --- /dev/null +++ b/src/lib/SelectStatement.h @@ -0,0 +1,60 @@ +#ifndef __SELECT_STATEMENT_H__ +#define __SELECT_STATEMENT_H__ + +#include "Statement.h" +#include "Expr.h" +#include "List.h" +#include "Table.h" + +namespace hsql { + + +/** + * @struct OrderDescription + * Description of the order by clause within a select statement + * TODO: hold multiple expressions to be sorted by + */ +typedef enum { + kOrderAsc, + kOrderDesc +} OrderType; + +struct OrderDescription { + OrderDescription(OrderType type, Expr* expr) : type(type), expr(expr) {} + OrderType type; + Expr* expr; +}; + +/** + * @struct LimitDescription + * Description of the limit clause within a select statement + */ +const int64_t kNoLimit = -1; +const int64_t kNoOffset = -1; +struct LimitDescription { + LimitDescription(int64_t limit, int64_t offset) : limit(limit), offset(offset) {} + int64_t limit; + int64_t offset; +}; + +/** + * @struct SelectStatement + * Representation of a full select statement. + */ +struct SelectStatement : Statement { + SelectStatement() : Statement(kStmtSelect) {}; + + TableRef* from_table; + List* select_list; + Expr* where_clause; + + List* group_by; + + OrderDescription* order; + LimitDescription* limit; +}; + + +} // namespace hsql + +#endif \ No newline at end of file diff --git a/src/lib/Statement.h b/src/lib/Statement.h index 12941ba..c82ede2 100644 --- a/src/lib/Statement.h +++ b/src/lib/Statement.h @@ -5,43 +5,24 @@ #ifndef __STATEMENT_H__ #define __STATEMENT_H__ -#include "Expr.h" -#include "List.h" -#include "Table.h" namespace hsql { typedef enum { kStmtError, kStmtSelect, + kStmtImport, + // Following types are planned but not supported yet kStmtDelete, kStmtInsert, - kStmtCreate + kStmtCreate, + kStmtDrop, + kStmtExport, + kStmtRename, + kStmtAlter } StatementType; -typedef enum { - kOrderAsc, - kOrderDesc -} OrderType; - - -struct OrderDescription { - OrderDescription(OrderType type, Expr* expr) : type(type), expr(expr) {} - OrderType type; - Expr* expr; -}; - -const int64_t kNoLimit = -1; -const int64_t kNoOffset = -1; -struct LimitDescription { - LimitDescription(int64_t limit, int64_t offset) : limit(limit), offset(offset) {} - int64_t limit; - int64_t offset; -}; - - - struct Statement { Statement(StatementType type) : type(type) {}; @@ -49,33 +30,6 @@ struct Statement { const char* parser_msg; }; - -struct SelectStatement : Statement { - SelectStatement() : Statement(kStmtSelect) {}; - - TableRef* from_table; - List* select_list; - Expr* where_clause; - - List* group_by; - - OrderDescription* order; - LimitDescription* limit; -}; - - -struct DeleteStatement : Statement { - // TODO -}; - -struct InsertStatement : Statement { - // TODO -}; - -struct CreateStatement : Statement { - // TODO -}; - } // namespace hsql #endif // __STATEMENT_H__ diff --git a/src/lib/sqlhelper.h b/src/lib/sqlhelper.h index 5613754..f1006bd 100644 --- a/src/lib/sqlhelper.h +++ b/src/lib/sqlhelper.h @@ -3,7 +3,7 @@ #define __SQLHELPER_H__ -#include "Statement.h" +#include "sqllib.h" namespace hsql { diff --git a/src/lib/sqllib.h b/src/lib/sqllib.h new file mode 100644 index 0000000..cb663f1 --- /dev/null +++ b/src/lib/sqllib.h @@ -0,0 +1,8 @@ + +#ifndef __SQLLIB_H__ +#define __SQLLIB_H__ + +#include "SelectStatement.h" +#include "ImportStatement.h" + +#endif \ No newline at end of file diff --git a/src/parser/SQLParser.h b/src/parser/SQLParser.h index e320efa..47d5f07 100644 --- a/src/parser/SQLParser.h +++ b/src/parser/SQLParser.h @@ -1,7 +1,7 @@ #ifndef __SQLPARSER_H_ #define __SQLPARSER_H_ -#include "Statement.h" +#include "sqllib.h" #include "bison_parser.h" namespace hsql { diff --git a/src/parser/bison_parser.y b/src/parser/bison_parser.y index b124bd4..b1b8c38 100644 --- a/src/parser/bison_parser.y +++ b/src/parser/bison_parser.y @@ -11,7 +11,7 @@ ** Section 1: C Declarations *********************************/ -#include "Statement.h" +#include "sqllib.h" #include "bison_parser.h" #include "flex_lexer.h" @@ -75,6 +75,7 @@ typedef void* yyscan_t; hsql::Statement* statement; hsql::SelectStatement* select_stmt; + hsql::ImportStatement* import_stmt; hsql::TableRef* table; hsql::Expr* expr; @@ -95,6 +96,7 @@ typedef void* yyscan_t; %token SELECT FROM WHERE GROUP BY HAVING ORDER ASC DESC LIMIT DISTINCT OFFSET %token JOIN ON INNER OUTER LEFT RIGHT CROSS USING NATURAL %token CREATE TABLE DATABASE INDEX +%token IMPORT CSV FILE TBL CONTROL INTO %token DELETE INSERT %token AS NOT AND OR NULL LIKE %token NAME STRING COMPARISON @@ -107,9 +109,10 @@ typedef void* yyscan_t; *********************************/ %type statement %type select_statement -%type table_name opt_alias alias +%type import_statement +%type table_name opt_alias alias file_path %type from_clause table_ref table_ref_atomic table_ref_name -%type
join_stmt join_table +%type
join_clause 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 @@ -118,6 +121,7 @@ typedef void* yyscan_t; %type order_by_clause %type limit_clause %type order_type +%type import_file_type /****************************** @@ -156,17 +160,38 @@ input: ; // All types of statements -// Atm: only select statements (future: insert, delete, etc...) +// TODO: insert, delete, etc... statement: select_statement { $$ = $1; } + | import_statement { $$ = $1; } ; +/****************************** + ** Import Statement + ******************************/ +import_statement: + IMPORT FROM import_file_type FILE file_path INTO table_name { + $$ = new ImportStatement(); + $$->file_type = (ImportFileType) $3; + $$->file_path = $5; + $$->table_name = $7; + } + ; + +import_file_type: + CSV { $$ = kImportCSV; } + | TBL { $$ = kImportTbl; } + ; + +file_path: + STRING + ; /****************************** - ** Select Statements + ** Select Statement ******************************/ select_statement: @@ -182,7 +207,7 @@ select_statement: $$ = s; } | '(' select_statement ')' { $$ = $2; } - ; + ; select_list: @@ -210,15 +235,18 @@ group_clause: order_by_clause: ORDER BY expr order_type { $$ = new OrderDescription($4, $3); } | /* empty */ { $$ = NULL; } + ; order_type: ASC { $$ = kOrderAsc; } | DESC { $$ = kOrderDesc; } | /* empty */ { $$ = kOrderAsc; } + ; limit_clause: LIMIT int_literal { $$ = new LimitDescription($2->ival, kNoOffset); delete $2; } | /* empty */ { $$ = NULL; } + ; /****************************** ** Expressions @@ -320,7 +348,7 @@ table_ref_atomic: tbl->alias = $4; $$ = tbl; } - | join_stmt + | join_clause ; @@ -359,7 +387,7 @@ opt_alias: ** Join Statements ******************************/ -join_stmt: +join_clause: join_table JOIN join_table ON join_condition { $$ = new TableRef(kTableJoin); diff --git a/src/parser/flex_lexer.l b/src/parser/flex_lexer.l index fba200a..71d623b 100644 --- a/src/parser/flex_lexer.l +++ b/src/parser/flex_lexer.l @@ -10,7 +10,7 @@ ***************************/ %{ -#include "Statement.h" +#include "sqllib.h" #include "bison_parser.h" #include @@ -60,6 +60,7 @@ DISTINCT TOKEN(DISTINCT) OFFSET TOKEN(OFFSET) SELECT TOKEN(SELECT) INSERT TOKEN(INSERT) +IMPORT TOKEN(IMPORT) CREATE TOKEN(CREATE) DELETE TOKEN(DELETE) HAVING TOKEN(HAVING) @@ -71,11 +72,14 @@ INNER TOKEN(INNER) OUTER TOKEN(OUTER) CROSS TOKEN(CROSS) FROM TOKEN(FROM) +INTO TOKEN(INTO) LIKE TOKEN(LIKE) JOIN TOKEN(JOIN) +FILE TOKEN(FILE) DESC TOKEN(DESC) ASC TOKEN(ASC) NOT TOKEN(NOT) +TBL TOKEN(TBL) AND TOKEN(AND) BY TOKEN(BY) OR TOKEN(OR) diff --git a/src/sql_grammar_test.cpp b/src/sql_grammar_test.cpp index 511d7c3..d9b3e1d 100644 --- a/src/sql_grammar_test.cpp +++ b/src/sql_grammar_test.cpp @@ -29,7 +29,7 @@ int main(int argc, char *argv[]) { std::chrono::duration elapsed_seconds = end-start; if (expectFalse != (stmt->type == kStmtError)) { - fprintf(stderr, "-> Failed (%.3fms)! \"%s\"\n", elapsed_seconds.count()*1000, sql); + fprintf(stderr, "-> Failed (%.3fms)! %s: \"%s\"\n", elapsed_seconds.count()*1000, stmt->parser_msg, sql); continue; } else { if (expectFalse) {