257257%type <expr> function_expr between_expr expr_alias param_expr
258258%type <expr> column_name literal int_literal num_literal string_literal bool_literal date_literal interval_literal
259259%type <expr> comp_expr opt_where join_condition opt_having case_expr case_list in_expr hint
260- %type <expr> array_expr array_index null_literal
260+ %type <expr> array_expr array_index null_literal extended_literal casted_extended_literal
261261%type <limit> opt_limit opt_top
262262%type <order> order_desc
263263%type <order_type> opt_order_type
284284%type <import_type_t> opt_file_type file_type
285285
286286%type <str_vec> ident_commalist opt_column_list
287- %type <expr_vec> expr_list select_list opt_literal_list literal_list hint_list opt_hints opt_partition
287+ %type <expr_vec> expr_list select_list opt_extended_literal_list extended_literal_list hint_list opt_hints opt_partition
288288%type <table_vec> table_ref_commalist
289289%type <order_vec> opt_order order_list
290290%type <with_description_vec> opt_with_clause with_clause with_description_list
@@ -397,7 +397,7 @@ hint : IDENTIFIER {
397397 $$ = Expr::make(kExprHint );
398398 $$ ->name = $1 ;
399399}
400- | IDENTIFIER ' (' literal_list ' )' {
400+ | IDENTIFIER ' (' extended_literal_list ' )' {
401401 $$ = Expr::make(kExprHint );
402402 $$ ->name = $1 ;
403403 $$ ->exprList = $3 ;
@@ -423,13 +423,13 @@ prepare_statement : PREPARE IDENTIFIER FROM prepare_target_query {
423423 $$ ->query = $4 ;
424424};
425425
426- prepare_target_query : STRING
426+ prepare_target_query : STRING ;
427427
428- execute_statement : EXECUTE IDENTIFIER {
428+ execute_statement : EXECUTE IDENTIFIER {
429429 $$ = new ExecuteStatement();
430430 $$ ->name = $2 ;
431431}
432- | EXECUTE IDENTIFIER ' (' opt_literal_list ' )' {
432+ | EXECUTE IDENTIFIER ' (' opt_extended_literal_list ' )' {
433433 $$ = new ExecuteStatement();
434434 $$ ->name = $2 ;
435435 $$ ->parameters = $4 ;
@@ -708,7 +708,7 @@ truncate_statement : TRUNCATE table_name {
708708 * INSERT INTO students VALUES ('Max', 1112233, 'Musterhausen', 2.3)
709709 * INSERT INTO employees SELECT * FROM stundents
710710 ******************************/
711- insert_statement : INSERT INTO table_name opt_column_list VALUES ' (' literal_list ' )' {
711+ insert_statement : INSERT INTO table_name opt_column_list VALUES ' (' extended_literal_list ' )' {
712712 $$ = new InsertStatement(kInsertValues );
713713 $$ ->schema = $3 .schema;
714714 $$ ->tableName = $3 .name;
@@ -914,18 +914,34 @@ expr_list : expr_alias {
914914 $$ = $1 ;
915915};
916916
917- opt_literal_list : literal_list { $$ = $1 ; }
917+ // Literals, casted literals, and negative numbers/intervals are allowed for INSERT and EXECUTE statements or hints.
918+ opt_extended_literal_list : extended_literal_list { $$ = $1 ; }
918919| /* empty */ { $$ = nullptr ; };
919920
920- literal_list : literal {
921+ extended_literal_list : casted_extended_literal {
921922 $$ = new std::vector<Expr*>();
922923 $$ ->push_back ($1 );
923924}
924- | literal_list ' ,' literal {
925+ | extended_literal_list ' ,' casted_extended_literal {
925926 $1 ->push_back ($3 );
926927 $$ = $1 ;
927928};
928929
930+ casted_extended_literal : extended_literal | CAST ' (' extended_literal AS column_type ' )' {
931+ $$ = Expr::makeCast($3 , $5 );
932+ };
933+
934+ extended_literal : literal {
935+ if ($1 ->type == ExprType::kExprParameter ) {
936+ delete $1 ;
937+ yyerror (&yyloc, result, scanner, " Parameter ? is not a valid literal." );
938+ YYERROR ;
939+ }
940+ $$ = $1 ;
941+ }
942+ | ' -' num_literal { $$ = Expr::makeOpUnary(kOpUnaryMinus , $2 ); };
943+ | '-' interval_literal { $$ = Expr::makeOpUnary(kOpUnaryMinus, $2); };
944+
929945expr_alias : expr opt_alias {
930946 $$ = $1 ;
931947 if ($2 ) {
@@ -1078,10 +1094,7 @@ date_literal : DATE STRING {
10781094 $$ = Expr::makeDateLiteral($2 );
10791095};
10801096
1081- interval_literal : int_literal duration_field {
1082- $$ = Expr::makeIntervalLiteral($1 ->ival, $2 );
1083- delete $1 ;
1084- }
1097+ interval_literal : INTVAL duration_field { $$ = Expr::makeIntervalLiteral($1 , $2 ); }
10851098| INTERVAL STRING datetime_field {
10861099 int duration{0 }, chars_parsed{0 };
10871100 // If the whole string is parsed, chars_parsed points to the terminating null byte after the last character
@@ -1314,9 +1327,11 @@ ident_commalist : IDENTIFIER {
13141327
13151328// clang-format off
13161329%%
1317- // clang-format on
1318- /* ********************************
1330+
1331+ /* ********************************
13191332 ** Section 4: Additional C code
13201333 *********************************/
13211334
1322- /* empty */
1335+ /* empty */
1336+
1337+ // clang-format on
0 commit comments