Added boolean literal support (#103)

* Added boolean support

* Made bool literals int vals

With a flag indicating if they came from boolean literals.

* Add makeLiteral(bool val);
This commit is contained in:
alkim0 2018-11-02 06:42:23 -04:00 committed by mrks
parent a122effd46
commit a59deb43c3
9 changed files with 2216 additions and 2141 deletions

File diff suppressed because it is too large Load Diff

View File

@ -212,14 +212,16 @@ extern int hsql_debug;
SQL_DAY = 388, SQL_DAY = 388,
SQL_MONTH = 389, SQL_MONTH = 389,
SQL_YEAR = 390, SQL_YEAR = 390,
SQL_EQUALS = 391, SQL_TRUE = 391,
SQL_NOTEQUALS = 392, SQL_FALSE = 392,
SQL_LESS = 393, SQL_EQUALS = 393,
SQL_GREATER = 394, SQL_NOTEQUALS = 394,
SQL_LESSEQ = 395, SQL_LESS = 395,
SQL_GREATEREQ = 396, SQL_GREATER = 396,
SQL_NOTNULL = 397, SQL_LESSEQ = 397,
SQL_UMINUS = 398 SQL_GREATEREQ = 398,
SQL_NOTNULL = 399,
SQL_UMINUS = 400
}; };
#endif #endif
@ -270,7 +272,7 @@ union HSQL_STYPE
std::vector<hsql::Expr*>* expr_vec; std::vector<hsql::Expr*>* expr_vec;
std::vector<hsql::OrderDescription*>* order_vec; std::vector<hsql::OrderDescription*>* order_vec;
#line 274 "bison_parser.h" /* yacc.c:1919 */ #line 276 "bison_parser.h" /* yacc.c:1919 */
}; };
typedef union HSQL_STYPE HSQL_STYPE; typedef union HSQL_STYPE HSQL_STYPE;

View File

@ -175,6 +175,7 @@ int yyerror(YYLTYPE* llocp, SQLParserResult* result, yyscan_t scanner, const cha
%token VIEW WHEN WITH ADD ALL AND ASC CSV END FOR INT KEY %token VIEW WHEN WITH ADD ALL AND ASC CSV END FOR INT KEY
%token NOT OFF SET TBL TOP AS BY IF IN IS OF ON OR TO %token NOT OFF SET TBL TOP AS BY IF IN IS OF ON OR TO
%token ARRAY CONCAT ILIKE SECOND MINUTE HOUR DAY MONTH YEAR %token ARRAY CONCAT ILIKE SECOND MINUTE HOUR DAY MONTH YEAR
%token TRUE FALSE
/********************************* /*********************************
** Non-Terminal types (http://www.gnu.org/software/bison/manual/html_node/Type-Decl.html) ** Non-Terminal types (http://www.gnu.org/software/bison/manual/html_node/Type-Decl.html)
@ -199,7 +200,7 @@ int yyerror(YYLTYPE* llocp, SQLParserResult* result, yyscan_t scanner, const cha
%type <table> join_clause table_ref_name_no_alias %type <table> join_clause table_ref_name_no_alias
%type <expr> expr operand scalar_expr unary_expr binary_expr logic_expr exists_expr extract_expr %type <expr> expr operand scalar_expr unary_expr binary_expr logic_expr exists_expr extract_expr
%type <expr> function_expr between_expr expr_alias param_expr %type <expr> function_expr between_expr expr_alias param_expr
%type <expr> column_name literal int_literal num_literal string_literal %type <expr> column_name literal int_literal num_literal string_literal bool_literal
%type <expr> comp_expr opt_where join_condition opt_having case_expr case_list in_expr hint %type <expr> comp_expr opt_where join_condition opt_having case_expr case_list in_expr hint
%type <expr> array_expr array_index null_literal %type <expr> array_expr array_index null_literal
%type <limit> opt_limit opt_top %type <limit> opt_limit opt_top
@ -888,6 +889,7 @@ column_name:
literal: literal:
string_literal string_literal
| bool_literal
| num_literal | num_literal
| null_literal | null_literal
| param_expr | param_expr
@ -897,6 +899,10 @@ string_literal:
STRING { $$ = Expr::makeLiteral($1); } STRING { $$ = Expr::makeLiteral($1); }
; ;
bool_literal:
TRUE { $$ = Expr::makeLiteral(true); }
| FALSE { $$ = Expr::makeLiteral(false); }
;
num_literal: num_literal:
FLOATVAL { $$ = Expr::makeLiteral($1); } FLOATVAL { $$ = Expr::makeLiteral($1); }

File diff suppressed because it is too large Load Diff

View File

@ -729,7 +729,7 @@ extern int yylex \
#undef yyTABLES_NAME #undef yyTABLES_NAME
#endif #endif
#line 229 "flex_lexer.l" #line 231 "flex_lexer.l"
#line 735 "flex_lexer.h" #line 735 "flex_lexer.h"

View File

@ -184,6 +184,8 @@ HOUR TOKEN(HOUR)
DAY TOKEN(DAY) DAY TOKEN(DAY)
MONTH TOKEN(MONTH) MONTH TOKEN(MONTH)
YEAR TOKEN(YEAR) YEAR TOKEN(YEAR)
TRUE TOKEN(TRUE)
FALSE TOKEN(FALSE)
/* Allow =/== see https://sqlite.org/lang_expr.html#collateop */ /* Allow =/== see https://sqlite.org/lang_expr.html#collateop */
"==" TOKEN(EQUALS) "==" TOKEN(EQUALS)

View File

@ -1,4 +1,3 @@
#include "Expr.h" #include "Expr.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -6,7 +5,7 @@
namespace hsql { namespace hsql {
Expr::Expr(ExprType type) Expr::Expr(ExprType type)
: type(type), : type(type),
expr(nullptr), expr(nullptr),
expr2(nullptr), expr2(nullptr),
@ -19,10 +18,11 @@ namespace hsql {
ival(0), ival(0),
ival2(0), ival2(0),
datetimeField(kDatetimeNone), datetimeField(kDatetimeNone),
isBoolLiteral(false),
opType(kOpNone), opType(kOpNone),
distinct(false) {}; distinct(false){};
Expr::~Expr() { Expr::~Expr() {
delete expr; delete expr;
delete expr2; delete expr2;
delete select; delete select;
@ -31,35 +31,35 @@ namespace hsql {
free(alias); free(alias);
if (exprList != nullptr) { if (exprList != nullptr) {
for (Expr* e : *exprList) { for (Expr* e : *exprList) {
delete e; delete e;
} }
delete exprList; delete exprList;
} }
} }
Expr* Expr::make(ExprType type) { Expr* Expr::make(ExprType type) {
Expr* e = new Expr(type); Expr* e = new Expr(type);
return e; return e;
} }
Expr* Expr::makeOpUnary(OperatorType op, Expr* expr) { Expr* Expr::makeOpUnary(OperatorType op, Expr* expr) {
Expr* e = new Expr(kExprOperator); Expr* e = new Expr(kExprOperator);
e->opType = op; e->opType = op;
e->expr = expr; e->expr = expr;
e->expr2 = nullptr; e->expr2 = nullptr;
return e; return e;
} }
Expr* Expr::makeOpBinary(Expr* expr1, OperatorType op, Expr* expr2) { Expr* Expr::makeOpBinary(Expr* expr1, OperatorType op, Expr* expr2) {
Expr* e = new Expr(kExprOperator); Expr* e = new Expr(kExprOperator);
e->opType = op; e->opType = op;
e->expr = expr1; e->expr = expr1;
e->expr2 = expr2; e->expr2 = expr2;
return e; return e;
} }
Expr* Expr::makeBetween(Expr* expr, Expr* left, Expr* right) { Expr* Expr::makeBetween(Expr* expr, Expr* left, Expr* right) {
Expr* e = new Expr(kExprOperator); Expr* e = new Expr(kExprOperator);
e->expr = expr; e->expr = expr;
e->opType = kOpBetween; e->opType = kOpBetween;
@ -67,32 +67,32 @@ namespace hsql {
e->exprList->push_back(left); e->exprList->push_back(left);
e->exprList->push_back(right); e->exprList->push_back(right);
return e; return e;
} }
Expr* Expr::makeCaseList(Expr* caseListElement) { Expr* Expr::makeCaseList(Expr* caseListElement) {
Expr* e = new Expr(kExprOperator); Expr* e = new Expr(kExprOperator);
// Case list expressions are temporary and will be integrated into the case expressions exprList - thus assign // Case list expressions are temporary and will be integrated into the case
// operator type kOpNone // expressions exprList - thus assign operator type kOpNone
e->opType = kOpNone; e->opType = kOpNone;
e->exprList = new std::vector<Expr*>(); e->exprList = new std::vector<Expr*>();
e->exprList->push_back(caseListElement); e->exprList->push_back(caseListElement);
return e; return e;
} }
Expr* Expr::makeCaseListElement(Expr* when, Expr* then) { Expr* Expr::makeCaseListElement(Expr* when, Expr* then) {
Expr* e = new Expr(kExprOperator); Expr* e = new Expr(kExprOperator);
e->opType = kOpCaseListElement; e->opType = kOpCaseListElement;
e->expr = when; e->expr = when;
e->expr2 = then; e->expr2 = then;
return e; return e;
} }
Expr* Expr::caseListAppend(Expr* caseList, Expr* caseListElement) { Expr* Expr::caseListAppend(Expr* caseList, Expr* caseListElement) {
caseList->exprList->push_back(caseListElement); caseList->exprList->push_back(caseListElement);
return caseList; return caseList;
} }
Expr* Expr::makeCase(Expr* expr, Expr* caseList, Expr* elseExpr) { Expr* Expr::makeCase(Expr* expr, Expr* caseList, Expr* elseExpr) {
Expr* e = new Expr(kExprOperator); Expr* e = new Expr(kExprOperator);
e->opType = kOpCase; e->opType = kOpCase;
e->expr = expr; e->expr = expr;
@ -101,153 +101,154 @@ namespace hsql {
caseList->exprList = nullptr; caseList->exprList = nullptr;
delete caseList; delete caseList;
return e; return e;
} }
Expr* Expr::makeLiteral(int64_t val) { Expr* Expr::makeLiteral(int64_t val) {
Expr* e = new Expr(kExprLiteralInt); Expr* e = new Expr(kExprLiteralInt);
e->ival = val; e->ival = val;
return e; return e;
} }
Expr* Expr::makeLiteral(double value) { Expr* Expr::makeLiteral(double value) {
Expr* e = new Expr(kExprLiteralFloat); Expr* e = new Expr(kExprLiteralFloat);
e->fval = value; e->fval = value;
return e; return e;
} }
Expr* Expr::makeLiteral(char* string) { Expr* Expr::makeLiteral(char* string) {
Expr* e = new Expr(kExprLiteralString); Expr* e = new Expr(kExprLiteralString);
e->name = string; e->name = string;
return e; return e;
} }
Expr* Expr::makeNullLiteral() { Expr* Expr::makeLiteral(bool val) {
Expr* e = new Expr(kExprLiteralInt);
e->ival = (int)val;
e->isBoolLiteral = true;
return e;
}
Expr* Expr::makeNullLiteral() {
Expr* e = new Expr(kExprLiteralNull); Expr* e = new Expr(kExprLiteralNull);
return e; return e;
} }
Expr* Expr::makeColumnRef(char* name) { Expr* Expr::makeColumnRef(char* name) {
Expr* e = new Expr(kExprColumnRef); Expr* e = new Expr(kExprColumnRef);
e->name = name; e->name = name;
return e; return e;
} }
Expr* Expr::makeColumnRef(char* table, char* name) { Expr* Expr::makeColumnRef(char* table, char* name) {
Expr* e = new Expr(kExprColumnRef); Expr* e = new Expr(kExprColumnRef);
e->name = name; e->name = name;
e->table = table; e->table = table;
return e; return e;
} }
Expr* Expr::makeStar(void) { Expr* Expr::makeStar(void) {
Expr* e = new Expr(kExprStar); Expr* e = new Expr(kExprStar);
return e; return e;
} }
Expr* Expr::makeStar(char* table) { Expr* Expr::makeStar(char* table) {
Expr* e = new Expr(kExprStar); Expr* e = new Expr(kExprStar);
e->table = table; e->table = table;
return e; return e;
} }
Expr* Expr::makeFunctionRef(char* func_name, std::vector<Expr*>* exprList, Expr* Expr::makeFunctionRef(char* func_name, std::vector<Expr*>* exprList,
bool distinct) { bool distinct) {
Expr* e = new Expr(kExprFunctionRef); Expr* e = new Expr(kExprFunctionRef);
e->name = func_name; e->name = func_name;
e->exprList = exprList; e->exprList = exprList;
e->distinct = distinct; e->distinct = distinct;
return e; return e;
} }
Expr* Expr::makeArray(std::vector<Expr*>* exprList) { Expr* Expr::makeArray(std::vector<Expr*>* exprList) {
Expr* e = new Expr(kExprArray); Expr* e = new Expr(kExprArray);
e->exprList = exprList; e->exprList = exprList;
return e; return e;
} }
Expr* Expr::makeArrayIndex(Expr* expr, int64_t index) { Expr* Expr::makeArrayIndex(Expr* expr, int64_t index) {
Expr* e = new Expr(kExprArrayIndex); Expr* e = new Expr(kExprArrayIndex);
e->expr = expr; e->expr = expr;
e->ival = index; e->ival = index;
return e; return e;
} }
Expr* Expr::makeParameter(int id) { Expr* Expr::makeParameter(int id) {
Expr* e = new Expr(kExprParameter); Expr* e = new Expr(kExprParameter);
e->ival = id; e->ival = id;
return e; return e;
} }
Expr* Expr::makeSelect(SelectStatement* select) { Expr* Expr::makeSelect(SelectStatement* select) {
Expr* e = new Expr(kExprSelect); Expr* e = new Expr(kExprSelect);
e->select = select; e->select = select;
return e; return e;
} }
Expr* Expr::makeExists(SelectStatement* select) { Expr* Expr::makeExists(SelectStatement* select) {
Expr* e = new Expr(kExprOperator); Expr* e = new Expr(kExprOperator);
e->opType = kOpExists; e->opType = kOpExists;
e->select = select; e->select = select;
return e; return e;
} }
Expr* Expr::makeInOperator(Expr* expr, std::vector<Expr*>* exprList) { Expr* Expr::makeInOperator(Expr* expr, std::vector<Expr*>* exprList) {
Expr* e = new Expr(kExprOperator); Expr* e = new Expr(kExprOperator);
e->opType = kOpIn; e->opType = kOpIn;
e->expr = expr; e->expr = expr;
e->exprList = exprList; e->exprList = exprList;
return e; return e;
} }
Expr* Expr::makeInOperator(Expr* expr, SelectStatement* select) { Expr* Expr::makeInOperator(Expr* expr, SelectStatement* select) {
Expr* e = new Expr(kExprOperator); Expr* e = new Expr(kExprOperator);
e->opType = kOpIn; e->opType = kOpIn;
e->expr = expr; e->expr = expr;
e->select = select; e->select = select;
return e; return e;
} }
Expr* Expr::makeExtract(DatetimeField datetimeField, Expr* expr) { Expr* Expr::makeExtract(DatetimeField datetimeField, Expr* expr) {
Expr* e = new Expr(kExprFunctionRef); Expr* e = new Expr(kExprFunctionRef);
e->name = strdup("EXTRACT"); e->name = strdup("EXTRACT");
e->datetimeField = datetimeField; e->datetimeField = datetimeField;
e->expr = expr; e->expr = expr;
return e; return e;
} }
bool Expr::isType(ExprType exprType) const { bool Expr::isType(ExprType exprType) const { return exprType == type; }
return exprType == type;
}
bool Expr::isLiteral() const { bool Expr::isLiteral() const {
return isType(kExprLiteralInt) || isType(kExprLiteralFloat) || return isType(kExprLiteralInt) || isType(kExprLiteralFloat) ||
isType(kExprLiteralString) || isType(kExprParameter) || isType(kExprLiteralString) || isType(kExprParameter) ||
isType(kExprLiteralNull); isType(kExprLiteralNull);
} }
bool Expr::hasAlias() const { bool Expr::hasAlias() const { return alias != nullptr; }
return alias != nullptr;
}
bool Expr::hasTable() const { bool Expr::hasTable() const { return table != nullptr; }
return table != nullptr;
}
const char* Expr::getName() const { const char* Expr::getName() const {
if (alias != nullptr) if (alias != nullptr)
return alias; return alias;
else else
return name; return name;
} }
char* substr(const char* source, int from, int to) { char* substr(const char* source, int from, int to) {
int len = to - from; int len = to - from;
char* copy = (char*)malloc(len + 1); char* copy = (char*)malloc(len + 1);
; ;
strncpy(copy, source + from, len); strncpy(copy, source + from, len);
copy[len] = '\0'; copy[len] = '\0';
return copy; return copy;
} }
} // namespace hsql } // namespace hsql

View File

@ -6,13 +6,13 @@
#include <vector> #include <vector>
namespace hsql { namespace hsql {
struct SelectStatement; struct SelectStatement;
// Helper function used by the lexer. // Helper function used by the lexer.
// TODO: move to more appropriate place. // TODO: move to more appropriate place.
char* substr(const char* source, int from, int to); char* substr(const char* source, int from, int to);
enum ExprType { enum ExprType {
kExprLiteralFloat, kExprLiteralFloat,
kExprLiteralString, kExprLiteralString,
kExprLiteralInt, kExprLiteralInt,
@ -27,10 +27,10 @@ namespace hsql {
kExprArray, kExprArray,
kExprArrayIndex, kExprArrayIndex,
kExprDatetimeField kExprDatetimeField
}; };
// Operator types. These are important for expressions of type kExprOperator. // Operator types. These are important for expressions of type kExprOperator.
enum OperatorType { enum OperatorType {
kOpNone, kOpNone,
// Ternary operator // Ternary operator
@ -38,7 +38,7 @@ namespace hsql {
// n-nary special case // n-nary special case
kOpCase, kOpCase,
kOpCaseListElement, // `WHEN expr THEN expr` kOpCaseListElement, // `WHEN expr THEN expr`
// Binary operators. // Binary operators.
kOpPlus, kOpPlus,
@ -67,9 +67,9 @@ namespace hsql {
kOpUnaryMinus, kOpUnaryMinus,
kOpIsNull, kOpIsNull,
kOpExists kOpExists
}; };
enum DatetimeField { enum DatetimeField {
kDatetimeNone, kDatetimeNone,
kDatetimeSecond, kDatetimeSecond,
kDatetimeMinute, kDatetimeMinute,
@ -77,14 +77,14 @@ namespace hsql {
kDatetimeDay, kDatetimeDay,
kDatetimeMonth, kDatetimeMonth,
kDatetimeYear, kDatetimeYear,
}; };
typedef struct Expr Expr; typedef struct Expr Expr;
// Represents SQL expressions (i.e. literals, operators, column_refs). // Represents SQL expressions (i.e. literals, operators, column_refs).
// TODO: When destructing a placeholder expression, we might need to alter the // TODO: When destructing a placeholder expression, we might need to alter the
// placeholder_list. // placeholder_list.
struct Expr { struct Expr {
Expr(ExprType type); Expr(ExprType type);
virtual ~Expr(); virtual ~Expr();
@ -102,6 +102,7 @@ namespace hsql {
int64_t ival; int64_t ival;
int64_t ival2; int64_t ival2;
DatetimeField datetimeField; DatetimeField datetimeField;
bool isBoolLiteral;
OperatorType opType; OperatorType opType;
bool distinct; bool distinct;
@ -142,6 +143,8 @@ namespace hsql {
static Expr* makeLiteral(char* val); static Expr* makeLiteral(char* val);
static Expr* makeLiteral(bool val);
static Expr* makeNullLiteral(); static Expr* makeNullLiteral();
static Expr* makeColumnRef(char* name); static Expr* makeColumnRef(char* name);
@ -170,7 +173,7 @@ namespace hsql {
static Expr* makeInOperator(Expr* expr, SelectStatement* select); static Expr* makeInOperator(Expr* expr, SelectStatement* select);
static Expr* makeExtract(DatetimeField datetimeField1, Expr* expr); static Expr* makeExtract(DatetimeField datetimeField1, Expr* expr);
}; };
// 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
// For Hyrise we still had to put in the explicit NULL constructor // For Hyrise we still had to put in the explicit NULL constructor

View File

@ -428,19 +428,24 @@ TEST(Operators) {
SQLParserResult result; SQLParserResult result;
SQLParser::parse("SELECT * FROM foo where a = 1; \ SQLParser::parse("SELECT * FROM foo where a = 1; \
SELECT * FROM foo where a == 1; \ SELECT * FROM foo where a == 2; \
SELECT * FROM foo where a != 1; \ SELECT * FROM foo where a != 1; \
SELECT * FROM foo where a <> 1; \ SELECT * FROM foo where a <> 1; \
SELECT * FROM foo where a > 1; \ SELECT * FROM foo where a > 1; \
SELECT * FROM foo where a < 1; \ SELECT * FROM foo where a < 1; \
SELECT * FROM foo where a >= 1; \ SELECT * FROM foo where a >= 1; \
SELECT * FROM foo where a <= 1;", &result); SELECT * FROM foo where a <= 1; \
SELECT * FROM foo where a = TRUE; \
SELECT * FROM foo where a = false;", &result);
stmt = (SelectStatement*) result.getStatement(0); stmt = (SelectStatement*) result.getStatement(0);
ASSERT_EQ(stmt->whereClause->opType, kOpEquals); ASSERT_EQ(stmt->whereClause->opType, kOpEquals);
ASSERT_EQ(stmt->whereClause->expr2->ival, 1);
ASSERT_EQ(stmt->whereClause->expr2->isBoolLiteral, false);
stmt = (SelectStatement*) result.getStatement(1); stmt = (SelectStatement*) result.getStatement(1);
ASSERT_EQ(stmt->whereClause->opType, kOpEquals); ASSERT_EQ(stmt->whereClause->opType, kOpEquals);
ASSERT_EQ(stmt->whereClause->expr2->ival, 2);
stmt = (SelectStatement*) result.getStatement(2); stmt = (SelectStatement*) result.getStatement(2);
ASSERT_EQ(stmt->whereClause->opType, kOpNotEquals); ASSERT_EQ(stmt->whereClause->opType, kOpNotEquals);
@ -459,6 +464,16 @@ TEST(Operators) {
stmt = (SelectStatement*) result.getStatement(7); stmt = (SelectStatement*) result.getStatement(7);
ASSERT_EQ(stmt->whereClause->opType, kOpLessEq); ASSERT_EQ(stmt->whereClause->opType, kOpLessEq);
stmt = (SelectStatement*) result.getStatement(8);
ASSERT_EQ(stmt->whereClause->opType, kOpEquals);
ASSERT_EQ(stmt->whereClause->expr2->ival, 1);
ASSERT_EQ(stmt->whereClause->expr2->isBoolLiteral, true);
stmt = (SelectStatement*) result.getStatement(9);
ASSERT_EQ(stmt->whereClause->opType, kOpEquals);
ASSERT_EQ(stmt->whereClause->expr2->ival, 0);
ASSERT_EQ(stmt->whereClause->expr2->isBoolLiteral, true);
} }
TEST(JoinTypes) { TEST(JoinTypes) {