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]) [-+*/(),.;] TOK(yytext[0])
[0-9]+ | [0-9]+ |
[0-9]+"."[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_]* { [A-Za-z][A-Za-z0-9_]* {
yylval->sval = strdup(yytext); yylval->sval = strdup(yytext);

View File

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

View File

@ -1,6 +1,6 @@
#include "Expr.h" #include "Expr.h"
#include <stdio.h>
Expr* makeColumnRef(char* name) { Expr* makeColumnRef(char* name) {
ALLOC_EXPR(e, eExprColumnRef); ALLOC_EXPR(e, eExprColumnRef);
@ -12,5 +12,26 @@ Expr* makeColumnRef(char* name) {
Expr* makeFunctionRef(char* func_name, Expr* expr) { Expr* makeFunctionRef(char* func_name, Expr* expr) {
ALLOC_EXPR(e, eExprFunctionRef); ALLOC_EXPR(e, eExprFunctionRef);
e->name = func_name; 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; return e;
} }

View File

@ -17,9 +17,12 @@ struct Expr {
char* name; char* name;
Expr* expr; Expr* expr;
Expr* expr2;
float float_literal;
}; };
// Zero initializes an Expr object and assigns it to a space in the heap // 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) \ #define ALLOC_EXPR(var, type) \
Expr* var; \ Expr* var; \
do { \ do { \
@ -31,6 +34,9 @@ struct Expr {
Expr* makeColumnRef(char* name); Expr* makeColumnRef(char* name);
Expr* makeFunctionRef(char* func_name, Expr* expr); Expr* makeFunctionRef(char* func_name, Expr* expr);
Expr* makePredicate(Expr* expr1, char* op, Expr* expr2);
Expr* makeFloatLiteral(float value);
Expr* makeStringLiteral(char* string);
#endif #endif

View File

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

View File

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