Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit117fa25

Browse files
committed
Clean up grammar's handling of NULL in expressions: a_expr_or_null is
gone, replaced by plain a_expr. The few places where we needed todistinguish NULL from a_expr are now handled by tests inside the actionsrather than by separate productions. This allows us to accept querieslike 'SELECT 1 + NULL' without requiring parentheses around the NULL.
1 parente8be8ff commit117fa25

File tree

1 file changed

+66
-61
lines changed

1 file changed

+66
-61
lines changed

‎src/backend/parser/gram.y

Lines changed: 66 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.153 2000/03/01 05:18:19 tgl Exp $
14+
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.154 2000/03/12 00:39:52 tgl Exp $
1515
*
1616
* HISTORY
1717
* AUTHORDATEMAJOR EVENT
@@ -77,6 +77,7 @@ static Node *makeTypeCast(Node *arg, TypeName *typename);
7777
static Node *makeRowExpr(char *opr, List *largs, List *rargs);
7878
staticvoidmapTargetColumns(List *source, List *target);
7979
staticvoidparam_type_init(Oid *typev,int nargs);
80+
staticboolexprIsNullConstant(Node *arg);
8081
static Node *doNegate(Node *n);
8182
staticvoiddoNegateFloat(Value *v);
8283

@@ -229,7 +230,7 @@ static void doNegateFloat(Value *v);
229230
%type<node>columnDef
230231
%type<defelt>def_elem
231232
%type<node>def_arg,columnElem,where_clause,
232-
a_expr,a_expr_or_null,b_expr,c_expr,AexprConst,
233+
a_expr,b_expr,c_expr,AexprConst,
233234
in_expr,having_clause
234235
%type<list>row_descriptor,row_list,in_expr_nodes
235236
%type<node>row_expr
@@ -873,8 +874,14 @@ AlterTableStmt:
873874
;
874875

875876
alter_column_action:
876-
SETDEFAULTa_expr{$$ =$3; }
877-
|SETDEFAULTNULL_P{$$ =NULL; }
877+
SETDEFAULTa_expr
878+
{
879+
/* Treat SET DEFAULT NULL the same as DROP DEFAULT*/
880+
if (exprIsNullConstant($3))
881+
$$ =NULL;
882+
else
883+
$$ =$3;
884+
}
878885
|DROPDEFAULT{$$ =NULL; }
879886
;
880887

@@ -1155,22 +1162,20 @@ ColConstraintElem:
11551162
n->keys =NULL;
11561163
$$ = (Node *)n;
11571164
}
1158-
|DEFAULTNULL_P
1159-
{
1160-
Constraint *n = makeNode(Constraint);
1161-
n->contype = CONSTR_DEFAULT;
1162-
n->name =NULL;
1163-
n->raw_expr =NULL;
1164-
n->cooked_expr =NULL;
1165-
n->keys =NULL;
1166-
$$ = (Node *)n;
1167-
}
11681165
|DEFAULTb_expr
11691166
{
11701167
Constraint *n = makeNode(Constraint);
11711168
n->contype = CONSTR_DEFAULT;
11721169
n->name =NULL;
1173-
n->raw_expr =$2;
1170+
if (exprIsNullConstant($2))
1171+
{
1172+
/* DEFAULT NULL should be reported as empty expr*/
1173+
n->raw_expr =NULL;
1174+
}
1175+
else
1176+
{
1177+
n->raw_expr =$2;
1178+
}
11741179
n->cooked_expr =NULL;
11751180
n->keys =NULL;
11761181
$$ = (Node *)n;
@@ -4017,16 +4022,6 @@ opt_interval: datetime{ $$ = lcons($1, NIL); }
40174022
*
40184023
*****************************************************************************/
40194024

4020-
a_expr_or_null:a_expr
4021-
{$$ =$1; }
4022-
|NULL_P
4023-
{
4024-
A_Const *n = makeNode(A_Const);
4025-
n->val.type = T_Null;
4026-
$$ = (Node *)n;
4027-
}
4028-
;
4029-
40304025
/* Expressions using row descriptors
40314026
* Define row_descriptor to allow yacc to break the reduce/reduce conflict
40324027
* with singleton expressions.
@@ -4137,17 +4132,6 @@ a_expr: c_expr
41374132
{$$ =$1; }
41384133
|a_exprTYPECASTTypename
41394134
{$$ = makeTypeCast($1,$3); }
4140-
/*
4141-
* Can't collapse this into prior rule by using a_expr_or_null;
4142-
* that creates reduce/reduce conflicts. Grumble.
4143-
*/
4144-
|NULL_PTYPECASTTypename
4145-
{
4146-
A_Const *n = makeNode(A_Const);
4147-
n->val.type = T_Null;
4148-
n->typename =$3;
4149-
$$ = (Node *)n;
4150-
}
41514135
/*
41524136
* These operators must be called out explicitly in order to make use
41534137
* of yacc/bison's automatic operator-precedence handling. All other
@@ -4193,15 +4177,20 @@ a_expr: c_expr
41934177
{$$ = makeA_Expr(OP,"<",$1,$3); }
41944178
|a_expr'>'a_expr
41954179
{$$ = makeA_Expr(OP,">",$1,$3); }
4196-
4197-
|a_expr'='NULL_P
4198-
{$$ = makeA_Expr(ISNULL,NULL,$1,NULL); }
4199-
/* We allow this for standards-broken SQL products, like MS stuff*/
4200-
|NULL_P'='a_expr
4201-
{$$ = makeA_Expr(ISNULL,NULL,$3,NULL); }
4202-
42034180
|a_expr'='a_expr
4204-
{$$ = makeA_Expr(OP,"=",$1,$3); }
4181+
{
4182+
/*
4183+
* Special-case "foo = NULL" and "NULL = foo" for
4184+
* compatibility with standards-broken products
4185+
* (like Microsoft's). Turn these into IS NULL exprs.
4186+
*/
4187+
if (exprIsNullConstant($3))
4188+
$$ = makeA_Expr(ISNULL,NULL,$1,NULL);
4189+
elseif (exprIsNullConstant($1))
4190+
$$ = makeA_Expr(ISNULL,NULL,$3,NULL);
4191+
else
4192+
$$ = makeA_Expr(OP,"=",$1,$3);
4193+
}
42054194

42064195
|a_exprOpa_expr
42074196
{$$ = makeA_Expr(OP,$2,$1,$3); }
@@ -4360,21 +4349,14 @@ a_expr: c_expr
43604349
*
43614350
* b_expr is a subset of the complete expression syntax defined by a_expr.
43624351
*
4363-
* Presently, AND, NOT, IS,IN,andNULL are the a_expr keywords that would
4352+
* Presently, AND, NOT, IS, andIN are the a_expr keywords that would
43644353
* cause trouble in the places where b_expr is used. For simplicity, we
43654354
* just eliminate all the boolean-keyword-operator productions from b_expr.
43664355
*/
43674356
b_expr:c_expr
43684357
{$$ =$1; }
43694358
|b_exprTYPECASTTypename
43704359
{$$ = makeTypeCast($1,$3); }
4371-
|NULL_PTYPECASTTypename
4372-
{
4373-
A_Const *n = makeNode(A_Const);
4374-
n->val.type = T_Null;
4375-
n->typename =$3;
4376-
$$ = (Node *)n;
4377-
}
43784360
|'-'b_expr %precUMINUS
43794361
{$$ = doNegate($2); }
43804362
|'%'b_expr
@@ -4442,9 +4424,9 @@ c_expr: attr
44424424
}
44434425
|AexprConst
44444426
{$$ =$1; }
4445-
|'('a_expr_or_null')'
4427+
|'('a_expr')'
44464428
{$$ =$2; }
4447-
|CAST'('a_expr_or_nullASTypename')'
4429+
|CAST'('a_exprASTypename')'
44484430
{$$ = makeTypeCast($3,$5); }
44494431
|case_expr
44504432
{$$ =$1; }
@@ -4788,9 +4770,9 @@ opt_indirection: '[' a_expr ']' opt_indirection
47884770
{$$ = NIL; }
47894771
;
47904772

4791-
expr_list:a_expr_or_null
4773+
expr_list:a_expr
47924774
{$$ = lcons($1, NIL); }
4793-
|expr_list','a_expr_or_null
4775+
|expr_list','a_expr
47944776
{$$ = lappend($1,$3); }
47954777
|expr_listUSINGa_expr
47964778
{$$ = lappend($1,$3); }
@@ -4928,7 +4910,7 @@ when_clause_list: when_clause_list when_clause
49284910
{$$ = lcons($1, NIL); }
49294911
;
49304912

4931-
when_clause:WHENa_exprTHENa_expr_or_null
4913+
when_clause:WHENa_exprTHENa_expr
49324914
{
49334915
CaseWhen *w = makeNode(CaseWhen);
49344916
w->expr =$2;
@@ -4937,7 +4919,7 @@ when_clause: WHEN a_expr THEN a_expr_or_null
49374919
}
49384920
;
49394921

4940-
case_default:ELSEa_expr_or_null{$$ =$2; }
4922+
case_default:ELSEa_expr{$$ =$2; }
49414923
|/*EMPTY*/{$$ =NULL; }
49424924
;
49434925

@@ -4989,14 +4971,14 @@ target_list: target_list ',' target_el
49894971
;
49904972

49914973
/* AS is not optional because shift/red conflict with unary ops*/
4992-
target_el:a_expr_or_nullASColLabel
4974+
target_el:a_exprASColLabel
49934975
{
49944976
$$ = makeNode(ResTarget);
49954977
$$->name =$3;
49964978
$$->indirection =NULL;
49974979
$$->val = (Node *)$1;
49984980
}
4999-
|a_expr_or_null
4981+
|a_expr
50004982
{
50014983
$$ = makeNode(ResTarget);
50024984
$$->name =NULL;
@@ -5037,7 +5019,7 @@ update_target_list: update_target_list ',' update_target_el
50375019
{$$ = lcons($1, NIL); }
50385020
;
50395021

5040-
update_target_el:ColIdopt_indirection'='a_expr_or_null
5022+
update_target_el:ColIdopt_indirection'='a_expr
50415023
{
50425024
$$ = makeNode(ResTarget);
50435025
$$->name =$1;
@@ -5142,6 +5124,12 @@ AexprConst: Iconst
51425124
n->typename->typmod = -1;
51435125
$$ = (Node *)n;
51445126
}
5127+
|NULL_P
5128+
{
5129+
A_Const *n = makeNode(A_Const);
5130+
n->val.type = T_Null;
5131+
$$ = (Node *)n;
5132+
}
51455133
;
51465134

51475135
ParamNo:PARAMopt_indirection
@@ -5532,6 +5520,23 @@ Oid param_type(int t)
55325520
return param_type_info[t -1];
55335521
}
55345522

5523+
/*
5524+
* Test whether an a_expr is a plain NULL constant or not.
5525+
*/
5526+
staticbool
5527+
exprIsNullConstant(Node *arg)
5528+
{
5529+
if (arg &&IsA(arg, A_Const))
5530+
{
5531+
A_Const *con = (A_Const *) arg;
5532+
5533+
if (con->val.type == T_Null &&
5534+
con->typename ==NULL)
5535+
returntrue;
5536+
}
5537+
returnfalse;
5538+
}
5539+
55355540
/*
55365541
* doNegate --- handle negation of a numeric constant.
55375542
*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp