implemented join grammar
This commit is contained in:
parent
1ee767a31e
commit
71e80cc17e
|
@ -39,5 +39,5 @@ parser/bison_parser.cpp:
|
||||||
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o *~ $(EXECUTION_BIN) $(TESTS_BIN)
|
rm -f *.o *~ $(EXECUTION_BIN) $(TESTS_BIN) bin/grammar_test
|
||||||
make clean -C parser/
|
make clean -C parser/
|
||||||
|
|
|
@ -14,8 +14,10 @@ make grammar_test
|
||||||
echo "\n\n"
|
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 a FROM foo WHERE a > 12 OR b > 3 AND c = 3 LIMIT 10"
|
||||||
./bin/grammar_test "(SELECT col1, col2, 'test' FROM table, foo WHERE age > 12 AND zipcode = 12345 GROUP BY col1);"
|
./bin/grammar_test "SELECT col1, col2, 'test' FROM table, foo WHERE age > 12 AND zipcode = 12345 GROUP BY col1;"
|
||||||
./bin/grammar_test "SELECT age FROM table, (SELECT * FROM table2) ORDER BY age DESC"
|
./bin/grammar_test "SELECT age FROM table, (SELECT * FROM table2) ORDER BY age DESC"
|
||||||
./bin/grammar_test "(SELECT * from table WHERE (b OR NOT a) AND a = 12.5) JOIN table2 ON a = b"
|
./bin/grammar_test "SELECT * from table WHERE (b OR NOT a) AND a = 12.5 JOIN table2 ON a = b"
|
||||||
|
|
||||||
|
./bin/grammar_test -f "(SELECT a FROM foo WHERE a > 12 OR b > 3 AND c = 3 LIMIT 10)"
|
||||||
|
|
||||||
echo "\n\n"
|
echo "\n\n"
|
|
@ -2,7 +2,7 @@
|
||||||
all: bison_parser.cpp flex_lexer.cpp
|
all: bison_parser.cpp flex_lexer.cpp
|
||||||
|
|
||||||
bison_parser.cpp: bison_parser.y
|
bison_parser.cpp: bison_parser.y
|
||||||
bison bison_parser.y
|
bison bison_parser.y -v
|
||||||
|
|
||||||
flex_lexer.cpp: flex_lexer.l
|
flex_lexer.cpp: flex_lexer.l
|
||||||
flex flex_lexer.l
|
flex flex_lexer.l
|
||||||
|
|
|
@ -20,7 +20,7 @@ Statement* SQLParser::parseSQLString(const char *text) {
|
||||||
|
|
||||||
if (hsql_lex_init(&scanner)) {
|
if (hsql_lex_init(&scanner)) {
|
||||||
// couldn't initialize
|
// couldn't initialize
|
||||||
fprintf(stderr, "Error when initializing!\n");
|
fprintf(stderr, "[Error] SQLParser: Error when initializing lexer!\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ Statement* SQLParser::parseSQLString(const char *text) {
|
||||||
|
|
||||||
if (hsql_parse(&stmt, scanner)) {
|
if (hsql_parse(&stmt, scanner)) {
|
||||||
// error parsing
|
// error parsing
|
||||||
fprintf(stderr, "Error when parsing!\n");
|
// fprintf(stderr, "Error when parsing!\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
using namespace hsql;
|
using namespace hsql;
|
||||||
|
|
||||||
int yyerror(Statement **expression, yyscan_t scanner, const char *msg) {
|
int yyerror(Statement **expression, yyscan_t scanner, const char *msg) {
|
||||||
fprintf(stderr, "[Error] SQL Parser: %s\n", msg);
|
// fprintf(stderr, "[Error] SQL Parser: %s\n", msg);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ typedef void* yyscan_t;
|
||||||
%type <select_stmt> select_statement
|
%type <select_stmt> select_statement
|
||||||
%type <join_stmt> join_statement
|
%type <join_stmt> join_statement
|
||||||
%type <sval> table_name
|
%type <sval> table_name
|
||||||
%type <table> from_clause table_ref table_ref_atomic
|
%type <table> from_clause table_ref table_ref_atomic table_ref_atomic_opt_paren
|
||||||
%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
|
%type <expr> comp_expr where_clause
|
||||||
|
@ -167,7 +167,7 @@ statement:
|
||||||
******************************/
|
******************************/
|
||||||
|
|
||||||
join_statement:
|
join_statement:
|
||||||
select_statement JOIN table_ref ON join_condition
|
table_ref_atomic_opt_paren JOIN table_ref_atomic_opt_paren ON join_condition
|
||||||
{
|
{
|
||||||
$$ = new JoinStatement();
|
$$ = new JoinStatement();
|
||||||
}
|
}
|
||||||
|
@ -194,7 +194,6 @@ select_statement:
|
||||||
s->limit = $7;
|
s->limit = $7;
|
||||||
$$ = s;
|
$$ = s;
|
||||||
}
|
}
|
||||||
| '(' select_statement ')' { $$ = $2; }
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
@ -334,11 +333,24 @@ table_ref_atomic:
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
table_ref_commalist:
|
table_ref_commalist:
|
||||||
table_ref_atomic { $$ = new List<TableRef*>($1); }
|
table_ref_atomic { $$ = new List<TableRef*>($1); }
|
||||||
| table_ref_commalist ',' table_ref_atomic { $1->push_back($3); $$ = $1; }
|
| table_ref_commalist ',' table_ref_atomic { $1->push_back($3); $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
/* For join statements, where a select statement is allowed to be used without parenthesis */
|
||||||
|
table_ref_atomic_opt_paren:
|
||||||
|
table_ref_atomic
|
||||||
|
| select_statement {
|
||||||
|
auto tbl = new TableRef(kTableSelect);
|
||||||
|
tbl->select = $1;
|
||||||
|
$$ = tbl;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
table_name:
|
table_name:
|
||||||
NAME
|
NAME
|
||||||
| NAME '.' NAME
|
| NAME '.' NAME
|
||||||
|
|
|
@ -12,7 +12,10 @@ int main(int argc, char *argv[]) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int n = 1; n < argc; ++n) {
|
bool expectFalse = (std::string("-f").compare(std::string(argv[1])) == 0);
|
||||||
|
|
||||||
|
int n = (expectFalse) ? 2 : 1;
|
||||||
|
for (; n < argc; ++n) {
|
||||||
char* sql = argv[n];
|
char* sql = argv[n];
|
||||||
|
|
||||||
// Measuring the parsing time
|
// Measuring the parsing time
|
||||||
|
@ -25,11 +28,11 @@ int main(int argc, char *argv[]) {
|
||||||
end = std::chrono::system_clock::now();
|
end = std::chrono::system_clock::now();
|
||||||
std::chrono::duration<double> elapsed_seconds = end-start;
|
std::chrono::duration<double> elapsed_seconds = end-start;
|
||||||
|
|
||||||
if (stmt == NULL) {
|
if (expectFalse != (stmt == NULL)) {
|
||||||
fprintf(stderr, "-> Failed (%.3fms)! \"%s\"\n", elapsed_seconds.count()*1000, sql);
|
fprintf(stderr, "-> Failed (%.3fms)! \"%s\"\n", elapsed_seconds.count()*1000, sql);
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Success (%.3fms)! \"%s\"\n", elapsed_seconds.count()*1000, sql);
|
printf("Success (%.3fms%s)! \"%s\"\n", elapsed_seconds.count()*1000, (expectFalse) ? ", expected error" : "", sql);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue