maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #13273
Re: 4ddf606debf: MDEV-30151 parse error 1=2 not between/in
Hi, Alexander,
I'm not sure I understand everything you did there, so questions below
On Dec 28, Alexander Barkov wrote:
> revision-id: 4ddf606debf (mariadb-10.3.37-59-g4ddf606debf)
> parent(s): 8f30973234d
> author: Alexander Barkov
> committer: Alexander Barkov
> timestamp: 2022-12-13 10:35:16 +0400
> message:
>
> MDEV-30151 parse error 1=2 not between/in
>
> diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
> index 1f6485dac6a..ca614ff63e9 100644
> --- a/sql/sql_yacc.yy
> +++ b/sql/sql_yacc.yy
> @@ -1687,7 +1687,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
>
> %left PREC_BELOW_NOT
>
> -%nonassoc NOT_SYM
> +/* The precendence of boolean NOT is in fact here. See the comment below. */
> +
> %left '=' EQUAL_SYM GE '>' LE '<' NE
> %nonassoc IS
> %right BETWEEN_SYM
> @@ -1699,6 +1700,24 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
> %left '*' '/' '%' DIV_SYM MOD_SYM
> %left '^'
> %left MYSQL_CONCAT_SYM
> +/*
> + Boolean negation has a special branch in "expr" starting with NOT_SYM.
> + The precedence of logical negation is determined by the grammar itself
> + (without using Bison terminal symbol precedence) in this order
> + - Boolean factor (i.e. logical AND)
> + - Boolean NOT
> + - Boolean test (such as '=', IS NULL, IS TRUE)
> +
> + But we also need a precedence for NOT_SYM in other contexts,
> + to shift (without reduce) in these cases:
> + predicate <here> NOT IN ...
> + predicate <here> NOT BETWEEN ...
> + predicate <here> NOT LIKE ...
> + predicate <here> NOT REGEXP ...
> + If the precedence of NOT_SYM was low, it would reduce immediately
> + after scanning "predicate" and then produce a syntax error on "NOT".
> +*/
> +%nonassoc NOT_SYM
> %nonassoc NEG '~' NOT2_SYM BINARY
> %nonassoc COLLATE_SYM
>
> @@ -1938,6 +1957,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
> literal insert_ident order_ident temporal_literal
> simple_ident expr sum_expr in_sum_expr
> variable variable_aux
> + boolean_test boolean_factor
> predicate bit_expr parenthesized_expr
> table_wild simple_expr column_default_non_parenthesized_expr udf_expr
> primary_expr string_factor_expr mysql_concatenation_expr
> @@ -9840,79 +9860,87 @@ expr:
> MYSQL_YYABORT;
> }
> }
> - | NOT_SYM expr %prec NOT_SYM
> + | boolean_factor
what does that achieve?
> + ;
> +
> +boolean_factor:
> + NOT_SYM boolean_factor
> {
> $$= negate_expression(thd, $2);
> if (unlikely($$ == NULL))
> MYSQL_YYABORT;
> }
> - | expr IS TRUE_SYM %prec IS
> + | boolean_test %prec PREC_BELOW_NOT
> + ;
> +
> +boolean_test:
> + boolean_test IS TRUE_SYM %prec IS
> {
> $$= new (thd->mem_root) Item_func_istrue(thd, $1);
> if (unlikely($$ == NULL))
> MYSQL_YYABORT;
> }
> - | expr IS not TRUE_SYM %prec IS
> + | boolean_test IS not TRUE_SYM %prec IS
> {
> $$= new (thd->mem_root) Item_func_isnottrue(thd, $1);
> if (unlikely($$ == NULL))
> MYSQL_YYABORT;
> }
> - | expr IS FALSE_SYM %prec IS
> + | boolean_test IS FALSE_SYM %prec IS
> {
> $$= new (thd->mem_root) Item_func_isfalse(thd, $1);
> if (unlikely($$ == NULL))
> MYSQL_YYABORT;
> }
> - | expr IS not FALSE_SYM %prec IS
> + | boolean_test IS not FALSE_SYM %prec IS
> {
> $$= new (thd->mem_root) Item_func_isnotfalse(thd, $1);
> if (unlikely($$ == NULL))
> MYSQL_YYABORT;
> }
> - | expr IS UNKNOWN_SYM %prec IS
> + | boolean_test IS UNKNOWN_SYM %prec IS
> {
> $$= new (thd->mem_root) Item_func_isnull(thd, $1);
> if (unlikely($$ == NULL))
> MYSQL_YYABORT;
> }
> - | expr IS not UNKNOWN_SYM %prec IS
> + | boolean_test IS not UNKNOWN_SYM %prec IS
> {
> $$= new (thd->mem_root) Item_func_isnotnull(thd, $1);
> if (unlikely($$ == NULL))
> MYSQL_YYABORT;
> }
> - | expr IS NULL_SYM %prec PREC_BELOW_NOT
> + | boolean_test IS NULL_SYM %prec PREC_BELOW_NOT
can you try %prec IS here?
I suspect that if this affects anything, it'll cause bugs
> {
> $$= new (thd->mem_root) Item_func_isnull(thd, $1);
> if (unlikely($$ == NULL))
> MYSQL_YYABORT;
> }
> - | expr IS not NULL_SYM %prec IS
> + | boolean_test IS not NULL_SYM %prec IS
> {
> $$= new (thd->mem_root) Item_func_isnotnull(thd, $1);
> if (unlikely($$ == NULL))
> MYSQL_YYABORT;
> }
> - | expr EQUAL_SYM predicate %prec EQUAL_SYM
> + | boolean_test EQUAL_SYM predicate %prec EQUAL_SYM
> {
> $$= new (thd->mem_root) Item_func_equal(thd, $1, $3);
> if (unlikely($$ == NULL))
> MYSQL_YYABORT;
> }
> - | expr comp_op predicate %prec '='
> + | boolean_test comp_op predicate %prec '='
> {
> $$= (*$2)(0)->create(thd, $1, $3);
> if (unlikely($$ == NULL))
> MYSQL_YYABORT;
> }
> - | expr comp_op all_or_any '(' subselect ')' %prec '='
> + | boolean_test comp_op all_or_any '(' subselect ')' %prec '='
> {
> $$= all_any_subquery_creator(thd, $1, $2, $3, $5);
> if (unlikely($$ == NULL))
> MYSQL_YYABORT;
> }
> - | predicate
> + | predicate %prec BETWEEN_SYM
> ;
>
Regards,
Sergei
VP of MariaDB Server Engineering
and security@xxxxxxxxxxx