implemented where clause into parser

This commit is contained in:
Pedro 2014-10-08 19:46:25 -07:00
parent d6598d6cf6
commit 97465b12e2
6 changed files with 74 additions and 26 deletions

View File

@ -43,13 +43,20 @@ OR TOK(OR)
"<" |
">" |
"<=" |
">=" TOK(COMPARISON)
">=" {
yylval->sval = strdup(yytext);
return COMPARISON;
}
[-+*/(),.;] TOK(yytext[0])
[0-9]+ |
[0-9]+"."[0-9]* |
"."[0-9]* TOK(INTNUM)
"."[0-9]* {
yylval->number = atof(yytext);
return INTNUM;
}
[A-Za-z][A-Za-z0-9_]* {
yylval->sval = strdup(yytext);

View File

@ -36,7 +36,7 @@ typedef void* yyscan_t;
%parse-param { yyscan_t scanner }
%union {
int value;
float number;
char* sval;
Statement* statement;
@ -49,14 +49,18 @@ typedef void* yyscan_t;
}
%token SELECT FROM GROUP BY WHERE NOT AND OR
%token INTNUM COMPARISON STRING
%token <sval> NAME
%token <sval> NAME STRING COMPARISON
%token <number> INTNUM
%type <statement> statement
%type <select_statement> select_statement
%type <sval> column_name table_name
%type <sval> table_name
%type <table> from_clause table_exp
%type <expr> expr;
%type <expr> expr column_name scalar_exp literal
%type <expr> comparison_predicate predicate search_condition where_clause
%type <slist> table_ref_commalist
%type <explist> expr_list group_clause
%%
@ -80,6 +84,7 @@ select_statement:
SelectStatement* s = new SelectStatement();
s->_select_list = $2;
s->_from_table = $3;
s->_where_clause = $4;
s->_group_by = $5;
$$ = s;
}
@ -92,8 +97,8 @@ from_clause:
;
where_clause:
WHERE search_condition
| /* empty */
WHERE search_condition { $$ = $2; }
| /* empty */ { $$ = NULL; }
;
group_clause:
@ -126,12 +131,12 @@ predicate:
;
comparison_predicate:
scalar_exp COMPARISON scalar_exp
scalar_exp COMPARISON scalar_exp { $$ = makePredicate($1, $2, $3); }
;
expr:
column_name { $$ = makeColumnRef($1); }
column_name
| NAME '(' expr ')' { $$ = makeFunctionRef($1, $3); }
;
@ -153,7 +158,7 @@ table_ref_commalist:
column_name:
NAME
NAME { $$ = makeColumnRef($1); }
;
table_name:
@ -162,8 +167,8 @@ table_name:
;
literal:
STRING
| INTNUM
STRING { $$ = makeStringLiteral($1); }
| INTNUM { $$ = makeFloatLiteral($1); }
;
scalar_exp:

View File

@ -1,6 +1,6 @@
#include "Expr.h"
#include <stdio.h>
Expr* makeColumnRef(char* name) {
ALLOC_EXPR(e, eExprColumnRef);
@ -12,5 +12,26 @@ Expr* makeColumnRef(char* name) {
Expr* makeFunctionRef(char* func_name, Expr* expr) {
ALLOC_EXPR(e, eExprFunctionRef);
e->name = func_name;
e->expr = expr;
return e;
}
Expr* makePredicate(Expr* expr1, char* op, Expr* expr2) {
ALLOC_EXPR(e, eExprPredicate);
e->name = op;
e->expr = expr1;
e->expr2 = expr2;
return e;
}
Expr* makeFloatLiteral(float value) {
ALLOC_EXPR(e, eExprLiteralFloat);
e->float_literal = value;
return e;
}
Expr* makeStringLiteral(char* string) {
ALLOC_EXPR(e, eExprLiteralString);
e->name = string;
return e;
}

View File

@ -17,9 +17,12 @@ struct Expr {
char* name;
Expr* expr;
Expr* expr2;
float float_literal;
};
// Zero initializes an Expr object and assigns it to a space in the heap
// http://www.ex-parrot.com/~chris/random/initialise.html
#define ALLOC_EXPR(var, type) \
Expr* var; \
do { \
@ -31,6 +34,9 @@ struct Expr {
Expr* makeColumnRef(char* name);
Expr* makeFunctionRef(char* func_name, Expr* expr);
Expr* makePredicate(Expr* expr1, char* op, Expr* expr2);
Expr* makeFloatLiteral(float value);
Expr* makeStringLiteral(char* string);
#endif

View File

@ -34,6 +34,7 @@ public:
TableRef* _from_table;
List<Expr*>* _select_list;
List<Expr*>* _group_by;
Expr* _where_clause;
};

View File

@ -18,20 +18,28 @@ void SelectTest1() {
fflush(stdout);
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);
Statement* sqlStatement = SQLParser::parseSQL(sql);
ASSERT(sqlStatement != NULL);
ASSERT(sqlStatement->_type == eSelect);
SelectStatement* select = (SelectStatement*) stmt;
SelectStatement* stmt = (SelectStatement*) sqlStatement;
ASSERT(select->_select_list->size() == 3);
ASSERT_STR(select->_select_list->at(0)->name, "age");
ASSERT_STR(select->_select_list->at(1)->name, "name");
ASSERT_STR(select->_select_list->at(2)->name, "address");
ASSERT(stmt->_select_list->size() == 3);
ASSERT_STR(stmt->_select_list->at(0)->name, "age");
ASSERT_STR(stmt->_select_list->at(1)->name, "name");
ASSERT_STR(stmt->_select_list->at(2)->name, "address");
ASSERT(select->_from_table != NULL);
ASSERT(select->_from_table->_type == eTableName);
ASSERT_STR(select->_from_table->_table_names->at(0), "table");
ASSERT(stmt->_from_table != NULL);
ASSERT(stmt->_from_table->_type == eTableName);
ASSERT_STR(stmt->_from_table->_table_names->at(0), "table");
// WHERE
ASSERT(stmt->_where_clause != NULL);
ASSERT(stmt->_where_clause->expr->type == eExprColumnRef);
ASSERT_STR(stmt->_where_clause->expr->name, "age");
ASSERT_STR(stmt->_where_clause->name, ">");
ASSERT(stmt->_where_clause->expr2->type == eExprLiteralFloat);
ASSERT(stmt->_where_clause->expr2->float_literal == 12.5);
printf("passed!\n");
}