Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,586 changes: 811 additions & 775 deletions src/parser/bison_parser.cpp

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions src/parser/bison_parser.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/* A Bison parser, made by GNU Bison 3.7.4. */
/* A Bison parser, made by GNU Bison 3.7.6. */

/* Bison interface for Yacc-like parsers in C

Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation,
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
Inc.

This program is free software: you can redistribute it and/or modify
Expand All @@ -16,7 +16,7 @@
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */

/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
Expand Down
16 changes: 15 additions & 1 deletion src/parser/bison_parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ int yyerror(YYLTYPE* llocp, SQLParserResult* result, yyscan_t scanner, const cha
%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 cast_expr
%type <expr> function_expr between_expr expr_alias param_expr
%type <expr> column_name literal int_literal num_literal string_literal bool_literal
%type <expr> column_name literal int_literal num_literal string_literal bool_literal date_literal
%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 <limit> opt_limit opt_top
Expand Down Expand Up @@ -1031,6 +1031,7 @@ literal:
| bool_literal
| num_literal
| null_literal
| date_literal
| param_expr
;

Expand All @@ -1056,6 +1057,19 @@ null_literal:
NULL { $$ = Expr::makeNullLiteral(); }
;

date_literal:
DATE STRING {
int day{0}, month{0}, year{0}, chars_parsed{0};
// If the whole string is parsed, chars_parsed points to the terminating null byte after the last character
if (sscanf($2, "%4d-%2d-%2d%n", &day, &month, &year, &chars_parsed) != 3 || $2[chars_parsed] != 0) {
free($2);
yyerror(&yyloc, result, scanner, "Found incorrect date format. Expected format: YYYY-MM-DD");
YYERROR;
}
$$ = Expr::makeDateLiteral($2);
}
;

param_expr:
'?' {
$$ = Expr::makeParameter(yylloc.total_column);
Expand Down
6 changes: 6 additions & 0 deletions src/sql/Expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,12 @@ Expr* Expr::makeNullLiteral() {
return e;
}

Expr* Expr::makeDateLiteral(char* string) {
Expr* e = new Expr(kExprLiteralDate);
e->name = string;
return e;
}

Expr* Expr::makeColumnRef(char* name) {
Expr* e = new Expr(kExprColumnRef);
e->name = name;
Expand Down
3 changes: 3 additions & 0 deletions src/sql/Expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ enum ExprType {
kExprLiteralString,
kExprLiteralInt,
kExprLiteralNull,
kExprLiteralDate,
kExprStar,
kExprParameter,
kExprColumnRef,
Expand Down Expand Up @@ -150,6 +151,8 @@ struct Expr {

static Expr* makeNullLiteral();

static Expr* makeDateLiteral(char* val);

static Expr* makeColumnRef(char* name);

static Expr* makeColumnRef(char* table, char* name);
Expand Down
6 changes: 6 additions & 0 deletions src/util/sqlhelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,12 @@ namespace hsql {
case kExprLiteralString:
inprint(expr->name, numIndent);
break;
case kExprLiteralDate:
inprint(expr->name, numIndent);
break;
case kExprLiteralNull:
inprint("NULL", numIndent);
break;
case kExprFunctionRef:
inprint(expr->name, numIndent);
for (Expr* e : *expr->exprList) printExpression(e, numIndent + 1);
Expand Down
7 changes: 6 additions & 1 deletion test/queries/queries-bad.sql
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,9 @@
!WITH a AS (SELECT ) b AS (SELECT ) SELECT 1; # Missing comma between WITH descriptions
!BEGIN TRANSACTION transName; # Transaction naming is currently not supported
!SELECT -9223372036854775809; # Out of int64_t range
!SELECT 9223372036854775808; # Out of int64_t range
!SELECT 9223372036854775808; # Out of int64_t range
!SELECT * FROM t WHERE a = DATE 'anystring';
!SELECT * FROM t WHERE a = DATE '1996-12-310';
!SELECT * FROM t WHERE a = DATE '1996-120-31';
!SELECT * FROM t WHERE a = DATE '19960-12-31';
!SELECT * FROM t WHERE a = DATE 'asdf-gh-jkl';
1 change: 1 addition & 0 deletions test/queries/queries-good.sql
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ SELECT * FROM t WHERE a BETWEEN 1 and c;
SELECT * FROM t WHERE a = ? AND b = ?;
SELECT City.name, Product.category, SUM(price) FROM fact INNER JOIN City ON fact.city_id = City.id INNER JOIN Product ON fact.product_id = Product.id GROUP BY City.name, Product.category;
SELECT SUBSTR(a, 3, 5) FROM t;
SELECT * FROM t WHERE a = DATE '1996-12-31';
# JOIN
SELECT t1.a, t1.b, t2.c FROM "table" AS t1 JOIN (SELECT * FROM foo JOIN bar ON foo.id = bar.id) t2 ON t1.a = t2.b WHERE (t1.b OR NOT t1.a) AND t2.c = 12.5
SELECT * FROM t1 JOIN t2 ON c1 = c2;
Expand Down
13 changes: 13 additions & 0 deletions test/select_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -836,3 +836,16 @@ TEST(CastAsDate) {
ASSERT_STREQ("CAST", stmt->selectList->front()->name);
ASSERT_EQ(DataType::DATE, stmt->selectList->front()->columnType.data_type);
}

TEST(DateLiteral) {
TEST_PARSE_SINGLE_SQL(
"SELECT * FROM t WHERE a = DATE '1996-12-31'",
kStmtSelect,
SelectStatement,
result,
stmt);
ASSERT_TRUE(result.isValid());
stmt = (SelectStatement*) result.getStatement(0);
ASSERT_EQ(stmt->whereClause->opType, kOpEquals);
ASSERT_STREQ(stmt->whereClause->expr2->name, "1996-12-31");
}