* 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
* 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 '[' ']'
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");
* a ISNULL
* a NOTNULL
*/
- | a_expr IS NULL_P
+ | a_expr IS NULL_P %prec IS
{
NullTest *n = makeNode(NullTest);
n->arg = (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;
{
$$ = (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;