refactored grammar. now includes where clause

This commit is contained in:
Pedro 2014-10-08 17:55:07 -07:00
parent dee7fb6468
commit 592d427f7a
5 changed files with 122 additions and 45 deletions

View File

@ -4,5 +4,5 @@ make clean
make tests make tests
./bin/tests ./bin/tests
make execution # make execution
./bin/sql_execution "SELECT col1, col2 FROM table GROUP BY col1;" # ./bin/sql_execution "SELECT col1, col2 FROM table GROUP BY col1;"

View File

@ -32,6 +32,18 @@ SELECT TOK(SELECT)
FROM TOK(FROM) FROM TOK(FROM)
GROUP TOK(GROUP) GROUP TOK(GROUP)
BY TOK(BY) BY TOK(BY)
WHERE TOK(WHERE)
NOT TOK(NOT)
AND TOK(AND)
OR TOK(OR)
"=" |
"<>" |
"<" |
">" |
"<=" |
">=" TOK(COMPARISON)
[-+*/(),.;] TOK(yytext[0]) [-+*/(),.;] TOK(yytext[0])
@ -40,6 +52,12 @@ BY TOK(BY)
"."[0-9]* TOK(INTNUM) "."[0-9]* TOK(INTNUM)
[A-Za-z][A-Za-z0-9_]* { [A-Za-z][A-Za-z0-9_]* {
yylval->sval = strdup(yytext);
return NAME;
}
'[^'\n]*' {
yylval->sval = strdup(yytext); yylval->sval = strdup(yytext);
return STRING; return STRING;
} }

View File

@ -48,73 +48,131 @@ typedef void* yyscan_t;
List<Expression*>* explist; List<Expression*>* explist;
} }
%token SELECT FROM GROUP BY INTNUM %token SELECT FROM GROUP BY WHERE NOT AND OR
%token <sval> STRING %token INTNUM COMPARISON STRING
%token <sval> NAME
%type <statement> statement %type <statement> statement
%type <select_statement> select_statement %type <select_statement> select_statement
%type <table> from_clause %type <sval> column_name table_name
%type <slist> string_list %type <table> from_clause table_exp
%type <explist> expr_list group_clause
%type <expr> expr; %type <expr> expr;
%type <slist> table_ref_commalist
%type <explist> expr_list group_clause
%% %%
input: input:
statement opt_semicolon { *statement = $1; }; statement opt_semicolon { *statement = $1; }
;
opt_semicolon:
';' | ;
statement: statement:
select_statement { $$ = $1; } select_statement { $$ = $1; }
| { $$ = NULL; }; | /* empty */ { $$ = NULL; }
;
select_statement: select_statement:
SELECT expr_list from_clause group_clause SELECT expr_list from_clause where_clause group_clause
{ {
SelectStatement* s = new SelectStatement(); SelectStatement* s = new SelectStatement();
s->_select_list = $2; s->_select_list = $2;
s->_from_table = $3; s->_from_table = $3;
s->_group_by = $4; s->_group_by = $5;
$$ = s; $$ = s;
}; }
;
expr_list:
expr { $$ = new List<Expression*>($1); }
| expr_list ',' expr { $1->push_back($3); $$ = $1; };
expr:
STRING { $$ = new Expression($1); }
| STRING '(' STRING ')' { $$ = new Expression($3, $1); };
from_clause: from_clause:
FROM string_list FROM table_exp { $$ = $2; }
{ ;
TableRef* t = new TableRef(eTableName);
t->_table_names = $2;
$$ = t;
}
| FROM '(' select_statement ')'
{
TableRef* t = new TableRef(eTableSelect);
t->_stmt = $3;
$$ = t;
};
where_clause:
WHERE search_condition
| /* empty */
;
group_clause: group_clause:
GROUP BY expr_list { $$ = $3; } GROUP BY expr_list { $$ = $3; }
| { $$ = NULL; }; | /* empty */ { $$ = NULL; }
;
string_list:
STRING { $$ = new List<char*>($1); }
| string_list ',' STRING { $1->push_back($3); $$ = $1; }
table_exp:
table_ref_commalist {
TableRef* t = new TableRef(eTableName);
t->_table_names = $1;
$$ = t;
}
| '(' select_statement ')' {
TableRef* t = new TableRef(eTableSelect);
t->_stmt = $2;
$$ = t;
}
;
search_condition:
predicate
;
predicate:
comparison_predicate
;
comparison_predicate:
scalar_exp COMPARISON scalar_exp
;
expr:
column_name { $$ = new Expression($1); }
| NAME '(' column_name ')' { $$ = new Expression($3, $1); }
;
/* Lists */
expr_list:
expr { $$ = new List<Expression*>($1); }
| expr_list ',' expr { $1->push_back($3); $$ = $1; }
;
// TODO: add table_ref to include names and select queries
table_ref_commalist:
table_name { $$ = new List<char*>($1); }
| table_ref_commalist ',' table_name { $1->push_back($3); $$ = $1; }
;
/* / Lists */
column_name:
NAME
;
table_name:
NAME
| NAME '.' NAME
;
literal:
STRING
| INTNUM
;
scalar_exp:
column_name
| literal
;
opt_semicolon:
';'
| /* empty */
;
%% %%

View File

@ -1,11 +1,12 @@
#ifndef __EXPRESSION_H__ #ifndef __EXPRESSION_H__
#define __EXPRESSION_H__ #define __EXPRESSION_H__
#include <cstdlib>
class Expression { class Expression {
public: public:
Expression(char* name) : name(name) {}; Expression(char* name) : name(name), func_name(NULL) {};
Expression(char* name, char* func_name) : name(name), func_name(func_name) {}; Expression(char* name, char* func_name) : name(name), func_name(func_name) {};
char* name; char* name;

View File

@ -17,7 +17,7 @@ void SelectTest1() {
printf("Test: SelectTest1... "); printf("Test: SelectTest1... ");
fflush(stdout); fflush(stdout);
const char* sql = "SELECT age, name, address from table;"; const char* sql = "SELECT age, name, address from table WHERE age > 12.5;";
Statement* stmt = SQLParser::parseSQL(sql); Statement* stmt = SQLParser::parseSQL(sql);
ASSERT(stmt != NULL); ASSERT(stmt != NULL);
ASSERT(stmt->_type == eSelect); ASSERT(stmt->_type == eSelect);