From b4adfa5b7468ad3e9b993f704ff083d927cf9dce Mon Sep 17 00:00:00 2001 From: Pedro Date: Tue, 7 Mar 2017 15:44:44 +0100 Subject: [PATCH] implement IN operator --- src/parser/bison_parser.y | 26 +++++++++++++++++--------- src/sql/Expr.cpp | 34 ++++++++++++++++++++++++++++++++++ src/sql/Expr.h | 5 +++++ 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/parser/bison_parser.y b/src/parser/bison_parser.y index d7dafa5..e98a4ef 100644 --- a/src/parser/bison_parser.y +++ b/src/parser/bison_parser.y @@ -197,7 +197,7 @@ int yyerror(YYLTYPE* llocp, SQLParserResult** result, yyscan_t scanner, const ch %type expr operand scalar_expr unary_expr binary_expr logic_expr exists_expr %type function_expr between_expr star_expr expr_alias placeholder_expr %type column_name literal int_literal num_literal string_literal -%type comp_expr opt_where join_condition opt_having case_expr +%type comp_expr opt_where join_condition opt_having case_expr in_expr %type opt_limit opt_top %type order_desc %type opt_order_type @@ -621,6 +621,7 @@ expr: | logic_expr | exists_expr | case_expr + | in_expr ; operand: @@ -645,12 +646,12 @@ unary_expr: binary_expr: comp_expr - | operand '-' operand { $$ = Expr::makeOpBinary($1, '-', $3); } - | operand '+' operand { $$ = Expr::makeOpBinary($1, '+', $3); } - | operand '/' operand { $$ = Expr::makeOpBinary($1, '/', $3); } - | operand '*' operand { $$ = Expr::makeOpBinary($1, '*', $3); } - | operand '%' operand { $$ = Expr::makeOpBinary($1, '%', $3); } - | operand '^' operand { $$ = Expr::makeOpBinary($1, '^', $3); } + | operand '-' operand { $$ = Expr::makeOpBinary($1, '-', $3); } + | operand '+' operand { $$ = Expr::makeOpBinary($1, '+', $3); } + | operand '/' operand { $$ = Expr::makeOpBinary($1, '/', $3); } + | operand '*' operand { $$ = Expr::makeOpBinary($1, '*', $3); } + | operand '%' operand { $$ = Expr::makeOpBinary($1, '%', $3); } + | operand '^' operand { $$ = Expr::makeOpBinary($1, '^', $3); } | operand LIKE operand { $$ = Expr::makeOpBinary($1, Expr::LIKE, $3); } | operand NOT LIKE operand { $$ = Expr::makeOpBinary($1, Expr::NOT_LIKE, $4); } ; @@ -660,9 +661,17 @@ logic_expr: | expr OR expr { $$ = Expr::makeOpBinary($1, Expr::OR, $3); } ; +// TODO: +in_expr: + operand IN '(' expr_list ')' { $$ = Expr::makeInOperator($1, $4, false); } + | operand NOT IN '(' expr_list ')' { $$ = Expr::makeInOperator($1, $5, true); } + | operand IN '(' select_no_paren ')' { $$ = Expr::makeInOperator($1, $4, false); } + | operand NOT IN '(' select_no_paren ')' { $$ = Expr::makeInOperator($1, $5, true); } + ; + // TODO: allow no else specified case_expr: - CASE WHEN operand THEN operand ELSE operand END { $$ = Expr::makeCase($3, $5, $7); } + CASE WHEN expr THEN operand ELSE operand END { $$ = Expr::makeCase($3, $5, $7); } ; exists_expr: @@ -715,7 +724,6 @@ star_expr: '*' { $$ = new Expr(kExprStar); } ; - placeholder_expr: '?' { $$ = Expr::makePlaceholder(yylloc.total_column); diff --git a/src/sql/Expr.cpp b/src/sql/Expr.cpp index 56d7eb2..2deb8c6 100644 --- a/src/sql/Expr.cpp +++ b/src/sql/Expr.cpp @@ -137,6 +137,40 @@ namespace hsql { return e; } + Expr* Expr::makeInOperator(Expr* expr, std::vector* exprList, bool notIn) { + Expr* e = new Expr(kExprOperator); + e->opType = IN; + e->expr = expr; + e->exprList = exprList; + + // If it is NOT IN, wrap the IN in a NOT operator. + if (notIn) { + Expr* neg = new Expr(kExprOperator); + neg->opType = NOT; + neg->expr = e; + return neg; + } + + return e; + } + + Expr* Expr::makeInOperator(Expr* expr, SelectStatement* select, bool notIn) { + Expr* e = new Expr(kExprOperator); + e->opType = IN; + e->expr = expr; + e->select = select; + + // If it is NOT IN, wrap the IN in a NOT operator. + if (notIn) { + Expr* neg = new Expr(kExprOperator); + neg->opType = NOT; + neg->expr = e; + return neg; + } + + return e; + } + bool Expr::isType(ExprType e_type) { return e_type == type; } diff --git a/src/sql/Expr.h b/src/sql/Expr.h index 48cbdbd..4bbd435 100644 --- a/src/sql/Expr.h +++ b/src/sql/Expr.h @@ -49,6 +49,7 @@ namespace hsql { NOT_LIKE, AND, OR, + IN, // Unary operators. NOT, @@ -131,6 +132,10 @@ namespace hsql { static Expr* makeSelect(SelectStatement* select); static Expr* makeExists(SelectStatement* select); + + static Expr* makeInOperator(Expr* expr, std::vector* exprList, bool notIn); + + static Expr* makeInOperator(Expr* expr, SelectStatement* select, bool notIn); }; // Zero initializes an Expr object and assigns it to a space in the heap