now parsing ImportStatements

This commit is contained in:
Pedro 2014-11-07 01:09:06 +01:00
parent 6a01ae42a4
commit 7c30786b53
10 changed files with 163 additions and 71 deletions

View File

@ -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 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 "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 # 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 * 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 * table WHERE (b OR NOT a) AND a = 12.5 AS t1 JOIN table2 ON a = b"
echo "\n\n" echo "\n\n"
# ./bin/analysis "SELECT a FROM foo WHERE a > 12 OR b > 3 AND c = 3" # ./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 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 * 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 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 # ./bin/analysis "-- test
SELECT * FROM table WHERE a NOT LIKE '%s' -- inline comment # SELECT * FROM table WHERE a NOT LIKE '%s' -- inline comment
--my comment" # --my comment"
# ./bin/analysis "SELECT * from table WHERE (b OR NOT a) AND a = 12.5 JOIN table2 ON a = b" # ./bin/analysis "SELECT * from table WHERE (b OR NOT a) AND a = 12.5 JOIN table2 ON a = b"
echo "\n\n" echo "\n\n"

36
src/lib/ImportStatement.h Normal file
View File

@ -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

60
src/lib/SelectStatement.h Normal file
View File

@ -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<Expr*>* select_list;
Expr* where_clause;
List<Expr*>* group_by;
OrderDescription* order;
LimitDescription* limit;
};
} // namespace hsql
#endif

View File

@ -5,43 +5,24 @@
#ifndef __STATEMENT_H__ #ifndef __STATEMENT_H__
#define __STATEMENT_H__ #define __STATEMENT_H__
#include "Expr.h"
#include "List.h"
#include "Table.h"
namespace hsql { namespace hsql {
typedef enum { typedef enum {
kStmtError, kStmtError,
kStmtSelect, kStmtSelect,
kStmtImport,
// Following types are planned but not supported yet
kStmtDelete, kStmtDelete,
kStmtInsert, kStmtInsert,
kStmtCreate kStmtCreate,
kStmtDrop,
kStmtExport,
kStmtRename,
kStmtAlter
} StatementType; } 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 { struct Statement {
Statement(StatementType type) : type(type) {}; Statement(StatementType type) : type(type) {};
@ -49,33 +30,6 @@ struct Statement {
const char* parser_msg; const char* parser_msg;
}; };
struct SelectStatement : Statement {
SelectStatement() : Statement(kStmtSelect) {};
TableRef* from_table;
List<Expr*>* select_list;
Expr* where_clause;
List<Expr*>* group_by;
OrderDescription* order;
LimitDescription* limit;
};
struct DeleteStatement : Statement {
// TODO
};
struct InsertStatement : Statement {
// TODO
};
struct CreateStatement : Statement {
// TODO
};
} // namespace hsql } // namespace hsql
#endif // __STATEMENT_H__ #endif // __STATEMENT_H__

View File

@ -3,7 +3,7 @@
#define __SQLHELPER_H__ #define __SQLHELPER_H__
#include "Statement.h" #include "sqllib.h"
namespace hsql { namespace hsql {

8
src/lib/sqllib.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef __SQLLIB_H__
#define __SQLLIB_H__
#include "SelectStatement.h"
#include "ImportStatement.h"
#endif

View File

@ -1,7 +1,7 @@
#ifndef __SQLPARSER_H_ #ifndef __SQLPARSER_H_
#define __SQLPARSER_H_ #define __SQLPARSER_H_
#include "Statement.h" #include "sqllib.h"
#include "bison_parser.h" #include "bison_parser.h"
namespace hsql { namespace hsql {

View File

@ -11,7 +11,7 @@
** Section 1: C Declarations ** Section 1: C Declarations
*********************************/ *********************************/
#include "Statement.h" #include "sqllib.h"
#include "bison_parser.h" #include "bison_parser.h"
#include "flex_lexer.h" #include "flex_lexer.h"
@ -75,6 +75,7 @@ typedef void* yyscan_t;
hsql::Statement* statement; hsql::Statement* statement;
hsql::SelectStatement* select_stmt; hsql::SelectStatement* select_stmt;
hsql::ImportStatement* import_stmt;
hsql::TableRef* table; hsql::TableRef* table;
hsql::Expr* expr; 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 SELECT FROM WHERE GROUP BY HAVING ORDER ASC DESC LIMIT DISTINCT OFFSET
%token JOIN ON INNER OUTER LEFT RIGHT CROSS USING NATURAL %token JOIN ON INNER OUTER LEFT RIGHT CROSS USING NATURAL
%token CREATE TABLE DATABASE INDEX %token CREATE TABLE DATABASE INDEX
%token IMPORT CSV FILE TBL CONTROL INTO
%token DELETE INSERT %token DELETE INSERT
%token AS NOT AND OR NULL LIKE %token AS NOT AND OR NULL LIKE
%token <sval> NAME STRING COMPARISON %token <sval> NAME STRING COMPARISON
@ -107,9 +109,10 @@ typedef void* yyscan_t;
*********************************/ *********************************/
%type <statement> statement %type <statement> statement
%type <select_stmt> select_statement %type <select_stmt> select_statement
%type <sval> table_name opt_alias alias %type <import_stmt> import_statement
%type <sval> table_name opt_alias alias file_path
%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_stmt join_table %type <table> join_clause join_table
%type <expr> expr scalar_expr unary_expr binary_expr function_expr star_expr %type <expr> expr scalar_expr unary_expr binary_expr function_expr star_expr
%type <expr> column_name literal int_literal num_literal %type <expr> column_name literal int_literal num_literal
%type <expr> comp_expr where_clause join_condition %type <expr> comp_expr where_clause join_condition
@ -118,6 +121,7 @@ typedef void* yyscan_t;
%type <order> order_by_clause %type <order> order_by_clause
%type <limit> limit_clause %type <limit> limit_clause
%type <order_type> order_type %type <order_type> order_type
%type <uval> import_file_type
/****************************** /******************************
@ -156,17 +160,38 @@ input:
; ;
// All types of statements // All types of statements
// Atm: only select statements (future: insert, delete, etc...) // TODO: insert, delete, etc...
statement: statement:
select_statement { $$ = $1; } 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: select_statement:
@ -210,15 +235,18 @@ group_clause:
order_by_clause: order_by_clause:
ORDER BY expr order_type { $$ = new OrderDescription($4, $3); } ORDER BY expr order_type { $$ = new OrderDescription($4, $3); }
| /* empty */ { $$ = NULL; } | /* empty */ { $$ = NULL; }
;
order_type: order_type:
ASC { $$ = kOrderAsc; } ASC { $$ = kOrderAsc; }
| DESC { $$ = kOrderDesc; } | DESC { $$ = kOrderDesc; }
| /* empty */ { $$ = kOrderAsc; } | /* empty */ { $$ = kOrderAsc; }
;
limit_clause: limit_clause:
LIMIT int_literal { $$ = new LimitDescription($2->ival, kNoOffset); delete $2; } LIMIT int_literal { $$ = new LimitDescription($2->ival, kNoOffset); delete $2; }
| /* empty */ { $$ = NULL; } | /* empty */ { $$ = NULL; }
;
/****************************** /******************************
** Expressions ** Expressions
@ -320,7 +348,7 @@ table_ref_atomic:
tbl->alias = $4; tbl->alias = $4;
$$ = tbl; $$ = tbl;
} }
| join_stmt | join_clause
; ;
@ -359,7 +387,7 @@ opt_alias:
** Join Statements ** Join Statements
******************************/ ******************************/
join_stmt: join_clause:
join_table JOIN join_table ON join_condition join_table JOIN join_table ON join_condition
{ {
$$ = new TableRef(kTableJoin); $$ = new TableRef(kTableJoin);

View File

@ -10,7 +10,7 @@
***************************/ ***************************/
%{ %{
#include "Statement.h" #include "sqllib.h"
#include "bison_parser.h" #include "bison_parser.h"
#include <stdio.h> #include <stdio.h>
@ -60,6 +60,7 @@ DISTINCT TOKEN(DISTINCT)
OFFSET TOKEN(OFFSET) OFFSET TOKEN(OFFSET)
SELECT TOKEN(SELECT) SELECT TOKEN(SELECT)
INSERT TOKEN(INSERT) INSERT TOKEN(INSERT)
IMPORT TOKEN(IMPORT)
CREATE TOKEN(CREATE) CREATE TOKEN(CREATE)
DELETE TOKEN(DELETE) DELETE TOKEN(DELETE)
HAVING TOKEN(HAVING) HAVING TOKEN(HAVING)
@ -71,11 +72,14 @@ INNER TOKEN(INNER)
OUTER TOKEN(OUTER) OUTER TOKEN(OUTER)
CROSS TOKEN(CROSS) CROSS TOKEN(CROSS)
FROM TOKEN(FROM) FROM TOKEN(FROM)
INTO TOKEN(INTO)
LIKE TOKEN(LIKE) LIKE TOKEN(LIKE)
JOIN TOKEN(JOIN) JOIN TOKEN(JOIN)
FILE TOKEN(FILE)
DESC TOKEN(DESC) DESC TOKEN(DESC)
ASC TOKEN(ASC) ASC TOKEN(ASC)
NOT TOKEN(NOT) NOT TOKEN(NOT)
TBL TOKEN(TBL)
AND TOKEN(AND) AND TOKEN(AND)
BY TOKEN(BY) BY TOKEN(BY)
OR TOKEN(OR) OR TOKEN(OR)

View File

@ -29,7 +29,7 @@ int main(int argc, char *argv[]) {
std::chrono::duration<double> elapsed_seconds = end-start; std::chrono::duration<double> elapsed_seconds = end-start;
if (expectFalse != (stmt->type == kStmtError)) { 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; continue;
} else { } else {
if (expectFalse) { if (expectFalse) {