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
./bin/tests
make execution
./bin/sql_execution "SELECT col1, col2 FROM table GROUP BY col1;"
# make execution
# ./bin/sql_execution "SELECT col1, col2 FROM table GROUP BY col1;"

View File

@ -31,7 +31,19 @@ using namespace std;
SELECT TOK(SELECT)
FROM TOK(FROM)
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])
@ -40,6 +52,12 @@ BY TOK(BY)
"."[0-9]* TOK(INTNUM)
[A-Za-z][A-Za-z0-9_]* {
yylval->sval = strdup(yytext);
return NAME;
}
'[^'\n]*' {
yylval->sval = strdup(yytext);
return STRING;
}

View File

@ -48,73 +48,131 @@ typedef void* yyscan_t;
List<Expression*>* explist;
}
%token SELECT FROM GROUP BY INTNUM
%token <sval> STRING
%token SELECT FROM GROUP BY WHERE NOT AND OR
%token INTNUM COMPARISON STRING
%token <sval> NAME
%type <statement> statement
%type <select_statement> select_statement
%type <table> from_clause
%type <slist> string_list
%type <explist> expr_list group_clause
%type <sval> column_name table_name
%type <table> from_clause table_exp
%type <expr> expr;
%type <slist> table_ref_commalist
%type <explist> expr_list group_clause
%%
input:
statement opt_semicolon { *statement = $1; };
opt_semicolon:
';' | ;
statement opt_semicolon { *statement = $1; }
;
statement:
select_statement { $$ = $1; }
| { $$ = NULL; };
select_statement { $$ = $1; }
| /* empty */ { $$ = NULL; }
;
select_statement:
SELECT expr_list from_clause group_clause
SELECT expr_list from_clause where_clause group_clause
{
SelectStatement* s = new SelectStatement();
s->_select_list = $2;
s->_from_table = $3;
s->_group_by = $4;
s->_group_by = $5;
$$ = 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 string_list
{
TableRef* t = new TableRef(eTableName);
t->_table_names = $2;
$$ = t;
}
| FROM '(' select_statement ')'
{
TableRef* t = new TableRef(eTableSelect);
t->_stmt = $3;
$$ = t;
};
FROM table_exp { $$ = $2; }
;
where_clause:
WHERE search_condition
| /* empty */
;
group_clause:
GROUP BY expr_list { $$ = $3; }
| { $$ = NULL; };
GROUP BY expr_list { $$ = $3; }
| /* 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__
#define __EXPRESSION_H__
#include <cstdlib>
class Expression {
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) {};
char* name;

View File

@ -17,7 +17,7 @@ void SelectTest1() {
printf("Test: SelectTest1... ");
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);
ASSERT(stmt != NULL);
ASSERT(stmt->_type == eSelect);