issue修复:操作符优先级问题导致特定表达式语法解析失败问题修复
This commit is contained in:
@ -940,6 +940,7 @@ static void setDelimiterName(core_yyscan_t yyscanner, char*input, VariableSetStm
|
||||
END_OF_INPUT
|
||||
END_OF_INPUT_COLON
|
||||
END_OF_PROC
|
||||
NOT_IN
|
||||
|
||||
/* Precedence: lowest to highest */
|
||||
%nonassoc COMMENT
|
||||
@ -960,7 +961,7 @@ static void setDelimiterName(core_yyscan_t yyscanner, char*input, VariableSetStm
|
||||
%nonassoc ESCAPE
|
||||
%nonassoc OVERLAPS
|
||||
%nonassoc BETWEEN
|
||||
%nonassoc IN_P
|
||||
%nonassoc IN_P NOT_IN
|
||||
%left POSTFIXOP /* dummy for postfix Op rules */
|
||||
/*
|
||||
* To support target_el without AS, we must give IDENT an explicit priority
|
||||
@ -1646,18 +1647,18 @@ CreateUserStmt:
|
||||
IsValidIdentUsername($3);
|
||||
n->role = $3;
|
||||
n->options = $6;
|
||||
n->missing_ok = false;
|
||||
$$ = (Node *)n;
|
||||
u_sess->parser_cxt.isForbidTruncate = false;
|
||||
}
|
||||
| CREATE USER IF_P NOT EXISTS RoleId opt_with {u_sess->parser_cxt.isForbidTruncate = true;} OptRoleList
|
||||
{
|
||||
CreateRoleStmt *n = makeNode(CreateRoleStmt);
|
||||
n->stmt_type = ROLESTMT_USER;
|
||||
IsValidIdentUsername($6);
|
||||
n->role = $6;
|
||||
n->options = $9;
|
||||
n->missing_ok = true;
|
||||
n->missing_ok = false;
|
||||
$$ = (Node *)n;
|
||||
u_sess->parser_cxt.isForbidTruncate = false;
|
||||
}
|
||||
| CREATE USER IF_P NOT EXISTS RoleId opt_with {u_sess->parser_cxt.isForbidTruncate = true;} OptRoleList
|
||||
{
|
||||
CreateRoleStmt *n = makeNode(CreateRoleStmt);
|
||||
n->stmt_type = ROLESTMT_USER;
|
||||
IsValidIdentUsername($6);
|
||||
n->role = $6;
|
||||
n->options = $9;
|
||||
n->missing_ok = true;
|
||||
$$ = (Node *)n;
|
||||
u_sess->parser_cxt.isForbidTruncate = false;
|
||||
}
|
||||
@ -1850,7 +1851,7 @@ CreateGroupStmt:
|
||||
n->stmt_type = ROLESTMT_GROUP;
|
||||
n->role = $3;
|
||||
n->options = $5;
|
||||
n->missing_ok = false;
|
||||
n->missing_ok = false;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
;
|
||||
@ -23861,25 +23862,25 @@ a_expr: c_expr { $$ = $1; }
|
||||
$$ = (Node *) makeSimpleA_Expr(AEXPR_IN, "=", $1, $3, @2);
|
||||
}
|
||||
}
|
||||
| a_expr NOT IN_P in_expr
|
||||
| a_expr NOT_IN in_expr %prec NOT_IN
|
||||
{
|
||||
/* in_expr returns a SubLink or a list of a_exprs */
|
||||
if (IsA($4, SubLink))
|
||||
if (IsA($3, SubLink))
|
||||
{
|
||||
/* generate NOT (foo = ANY (subquery)) */
|
||||
/* Make an = ANY node */
|
||||
SubLink *n = (SubLink *) $4;
|
||||
SubLink *n = (SubLink *) $3;
|
||||
n->subLinkType = ANY_SUBLINK;
|
||||
n->testexpr = $1;
|
||||
n->operName = list_make1(makeString("="));
|
||||
n->location = @3;
|
||||
n->location = @2;
|
||||
/* Stick a NOT on top */
|
||||
$$ = (Node *) makeA_Expr(AEXPR_NOT, NIL, NULL, (Node *) n, @2);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* generate scalar NOT IN expression */
|
||||
$$ = (Node *) makeSimpleA_Expr(AEXPR_IN, "<>", $1, $4, @2);
|
||||
$$ = (Node *) makeSimpleA_Expr(AEXPR_IN, "<>", $1, $3, @2);
|
||||
}
|
||||
}
|
||||
| a_expr subquery_Op sub_type select_with_parens %prec Op
|
||||
|
||||
@ -231,6 +231,9 @@ int base_yylex(YYSTYPE* lvalp, YYLTYPE* llocp, core_yyscan_t yyscanner)
|
||||
case ENFORCED:
|
||||
cur_token = NOT_ENFORCED;
|
||||
break;
|
||||
case IN_P:
|
||||
cur_token = NOT_IN;
|
||||
break;
|
||||
default:
|
||||
/* save the lookahead token for next time */
|
||||
SET_LOOKAHEAD_TOKEN();
|
||||
|
||||
@ -470,6 +470,12 @@ SELECT 1-2::bool;
|
||||
0
|
||||
(1 row)
|
||||
|
||||
select true >= 'ss' not in (md5('ss'));
|
||||
?column?
|
||||
----------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
--
|
||||
-- Clean up
|
||||
-- Many tables are retained by the regression test, but these do not seem
|
||||
|
||||
@ -206,6 +206,8 @@ SELECT -2::bool;
|
||||
|
||||
SELECT 1-2::bool;
|
||||
|
||||
select true >= 'ss' not in (md5('ss'));
|
||||
|
||||
--
|
||||
-- Clean up
|
||||
-- Many tables are retained by the regression test, but these do not seem
|
||||
|
||||
Reference in New Issue
Block a user