aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/parser/gram.y27
1 files changed, 14 insertions, 13 deletions
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 933a1a2ff9f..dd959618419 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -597,7 +597,8 @@ static void SplitColQualList(List *qualList,
* have any bad effects since obviously the keywords will still behave the
* same as if they weren't keywords). We need to do this for PARTITION,
* RANGE, ROWS to support opt_existing_window_name; and for RANGE, ROWS
- * so that they can follow a_expr without creating
+ * so that they can follow a_expr without creating postfix-operator problems;
+ * and for NULL so that it can follow b_expr in ColQualList without creating
* postfix-operator problems.
*
* The frame_bound productions UNBOUNDED PRECEDING and UNBOUNDED FOLLOWING
@@ -610,16 +611,16 @@ static void SplitColQualList(List *qualList,
* blame any funny behavior of UNBOUNDED on the SQL standard, though.
*/
%nonassoc UNBOUNDED /* ideally should have same precedence as IDENT */
-%nonassoc IDENT PARTITION RANGE ROWS PRECEDING FOLLOWING
+%nonassoc IDENT NULL_P PARTITION RANGE ROWS PRECEDING FOLLOWING
%left Op OPERATOR /* multi-character ops and user-defined operators */
%nonassoc NOTNULL
%nonassoc ISNULL
-%nonassoc IS NULL_P TRUE_P FALSE_P UNKNOWN /* sets precedence for IS NULL, etc */
+%nonassoc IS /* sets precedence for IS NULL, etc */
%left '+' '-'
%left '*' '/' '%'
%left '^'
/* Unary Operators */
-%left AT ZONE /* sets precedence for AT TIME ZONE */
+%left AT /* sets precedence for AT TIME ZONE */
%left COLLATE
%right UMINUS
%left '[' ']'
@@ -9705,7 +9706,7 @@ a_expr: c_expr { $$ = $1; }
n->location = @2;
$$ = (Node *) n;
}
- | a_expr AT TIME ZONE a_expr
+ | a_expr AT TIME ZONE a_expr %prec AT
{
FuncCall *n = makeNode(FuncCall);
n->funcname = SystemFuncName("timezone");
@@ -9887,7 +9888,7 @@ a_expr: c_expr { $$ = $1; }
* a ISNULL
* a NOTNULL
*/
- | a_expr IS NULL_P
+ | a_expr IS NULL_P %prec IS
{
NullTest *n = makeNode(NullTest);
n->arg = (Expr *) $1;
@@ -9901,7 +9902,7 @@ a_expr: c_expr { $$ = $1; }
n->nulltesttype = IS_NULL;
$$ = (Node *)n;
}
- | a_expr IS NOT NULL_P
+ | a_expr IS NOT NULL_P %prec IS
{
NullTest *n = makeNode(NullTest);
n->arg = (Expr *) $1;
@@ -9919,42 +9920,42 @@ a_expr: c_expr { $$ = $1; }
{
$$ = (Node *)makeOverlaps($1, $3, @2, yyscanner);
}
- | a_expr IS TRUE_P
+ | a_expr IS TRUE_P %prec IS
{
BooleanTest *b = makeNode(BooleanTest);
b->arg = (Expr *) $1;
b->booltesttype = IS_TRUE;
$$ = (Node *)b;
}
- | a_expr IS NOT TRUE_P
+ | a_expr IS NOT TRUE_P %prec IS
{
BooleanTest *b = makeNode(BooleanTest);
b->arg = (Expr *) $1;
b->booltesttype = IS_NOT_TRUE;
$$ = (Node *)b;
}
- | a_expr IS FALSE_P
+ | a_expr IS FALSE_P %prec IS
{
BooleanTest *b = makeNode(BooleanTest);
b->arg = (Expr *) $1;
b->booltesttype = IS_FALSE;
$$ = (Node *)b;
}
- | a_expr IS NOT FALSE_P
+ | a_expr IS NOT FALSE_P %prec IS
{
BooleanTest *b = makeNode(BooleanTest);
b->arg = (Expr *) $1;
b->booltesttype = IS_NOT_FALSE;
$$ = (Node *)b;
}
- | a_expr IS UNKNOWN
+ | a_expr IS UNKNOWN %prec IS
{
BooleanTest *b = makeNode(BooleanTest);
b->arg = (Expr *) $1;
b->booltesttype = IS_UNKNOWN;
$$ = (Node *)b;
}
- | a_expr IS NOT UNKNOWN
+ | a_expr IS NOT UNKNOWN %prec IS
{
BooleanTest *b = makeNode(BooleanTest);
b->arg = (Expr *) $1;