mirror of
https://github.com/postgres/postgres.git
synced 2025-07-27 12:41:57 +03:00
Allow bare column names to be subscripted as arrays. This
creates a reduce/reduce conflict, which I resolved by changing the 'AexprConst -> Typename Sconst' rule to 'AexprConst -> SimpleTypename Sconst'. In other words, a subscripted type declaration can't be used in that syntax any longer. This seems a small price to pay for not having to qualify subscripted columns anymore. Other cleanups: rename res_target_list to update_target_list, and remove productions for variants that are not legal in an UPDATE target list; rename res_target_list2 to plain target_list; delete position_expr in favor of using b_expr in that production; merge opt_indirection into attr nonterminal, since there are no places where an unsubscripted attr is wanted; fix typos in Param support; change case_arg so that an arbitrary a_expr is allowed, not only a column name.
This commit is contained in:
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.91 1999/07/16 04:59:29 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.92 1999/07/16 22:29:42 tgl Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -169,8 +169,8 @@ Oid param_type(int t); /* used in parse_expr.c */
|
|||||||
oper_argtypes, RuleActionList, RuleActionBlock, RuleActionMulti,
|
oper_argtypes, RuleActionList, RuleActionBlock, RuleActionMulti,
|
||||||
opt_column_list, columnList, opt_va_list, va_list,
|
opt_column_list, columnList, opt_va_list, va_list,
|
||||||
sort_clause, sortby_list, index_params, index_list, name_list,
|
sort_clause, sortby_list, index_params, index_list, name_list,
|
||||||
from_clause, from_expr, table_list, opt_array_bounds, nest_array_bounds,
|
from_clause, from_expr, table_list, opt_array_bounds,
|
||||||
expr_list, attrs, res_target_list, res_target_list2,
|
expr_list, attrs, target_list, update_target_list,
|
||||||
def_list, opt_indirection, group_clause, TriggerFuncArgs,
|
def_list, opt_indirection, group_clause, TriggerFuncArgs,
|
||||||
opt_select_limit
|
opt_select_limit
|
||||||
|
|
||||||
@ -189,7 +189,6 @@ Oid param_type(int t); /* used in parse_expr.c */
|
|||||||
%type <str> join_outer
|
%type <str> join_outer
|
||||||
%type <ival> join_type
|
%type <ival> join_type
|
||||||
|
|
||||||
%type <node> position_expr
|
|
||||||
%type <list> extract_list, position_list
|
%type <list> extract_list, position_list
|
||||||
%type <list> substr_list, substr_from, substr_for, trim_list
|
%type <list> substr_list, substr_from, substr_for, trim_list
|
||||||
%type <list> opt_interval
|
%type <list> opt_interval
|
||||||
@ -232,10 +231,11 @@ Oid param_type(int t); /* used in parse_expr.c */
|
|||||||
%type <ielem> index_elem, func_index
|
%type <ielem> index_elem, func_index
|
||||||
%type <range> table_expr
|
%type <range> table_expr
|
||||||
%type <relexp> relation_expr
|
%type <relexp> relation_expr
|
||||||
%type <target> res_target_el, res_target_el2
|
%type <target> target_el, update_target_el
|
||||||
%type <paramno> ParamNo
|
%type <paramno> ParamNo
|
||||||
|
|
||||||
%type <typnam> Typename, opt_type, Array, Generic, Character, Datetime, Numeric
|
%type <typnam> Typename, opt_type, SimpleTypename,
|
||||||
|
Generic, Numeric, Character, Datetime
|
||||||
%type <str> generic, numeric, character, datetime
|
%type <str> generic, numeric, character, datetime
|
||||||
%type <str> extract_arg
|
%type <str> extract_arg
|
||||||
%type <str> opt_charset, opt_collate
|
%type <str> opt_charset, opt_collate
|
||||||
@ -687,6 +687,10 @@ ClosePortalStmt: CLOSE opt_id
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
opt_id: ColId { $$ = $1; }
|
||||||
|
| /*EMPTY*/ { $$ = NULL; }
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
@ -2476,7 +2480,7 @@ InsertStmt: INSERT INTO relation_name insert_rest
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
insert_rest: VALUES '(' res_target_list2 ')'
|
insert_rest: VALUES '(' target_list ')'
|
||||||
{
|
{
|
||||||
$$ = makeNode(InsertStmt);
|
$$ = makeNode(InsertStmt);
|
||||||
$$->cols = NULL;
|
$$->cols = NULL;
|
||||||
@ -2519,7 +2523,7 @@ insert_rest: VALUES '(' res_target_list2 ')'
|
|||||||
$$->intersectClause = n->intersectClause;
|
$$->intersectClause = n->intersectClause;
|
||||||
$$->forUpdate = n->forUpdate;
|
$$->forUpdate = n->forUpdate;
|
||||||
}
|
}
|
||||||
| '(' columnList ')' VALUES '(' res_target_list2 ')'
|
| '(' columnList ')' VALUES '(' target_list ')'
|
||||||
{
|
{
|
||||||
$$ = makeNode(InsertStmt);
|
$$ = makeNode(InsertStmt);
|
||||||
$$->cols = $2;
|
$$->cols = $2;
|
||||||
@ -2621,7 +2625,7 @@ opt_lmode: SHARE { $$ = TRUE; }
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
UpdateStmt: UPDATE relation_name
|
UpdateStmt: UPDATE relation_name
|
||||||
SET res_target_list
|
SET update_target_list
|
||||||
from_clause
|
from_clause
|
||||||
where_clause
|
where_clause
|
||||||
{
|
{
|
||||||
@ -2804,7 +2808,7 @@ select_clause: '(' select_clause ')'
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
SubSelect: SELECT opt_unique res_target_list2
|
SubSelect: SELECT opt_unique target_list
|
||||||
result from_clause where_clause
|
result from_clause where_clause
|
||||||
group_clause having_clause
|
group_clause having_clause
|
||||||
{
|
{
|
||||||
@ -3183,17 +3187,9 @@ relation_expr: relation_name
|
|||||||
$$->inh = TRUE;
|
$$->inh = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
opt_array_bounds: '[' ']' nest_array_bounds
|
opt_array_bounds: '[' ']' opt_array_bounds
|
||||||
{ $$ = lcons(makeInteger(-1), $3); }
|
{ $$ = lcons(makeInteger(-1), $3); }
|
||||||
| '[' Iconst ']' nest_array_bounds
|
| '[' Iconst ']' opt_array_bounds
|
||||||
{ $$ = lcons(makeInteger($2), $4); }
|
|
||||||
| /*EMPTY*/
|
|
||||||
{ $$ = NIL; }
|
|
||||||
;
|
|
||||||
|
|
||||||
nest_array_bounds: '[' ']' nest_array_bounds
|
|
||||||
{ $$ = lcons(makeInteger(-1), $3); }
|
|
||||||
| '[' Iconst ']' nest_array_bounds
|
|
||||||
{ $$ = lcons(makeInteger($2), $4); }
|
{ $$ = lcons(makeInteger($2), $4); }
|
||||||
| /*EMPTY*/
|
| /*EMPTY*/
|
||||||
{ $$ = NIL; }
|
{ $$ = NIL; }
|
||||||
@ -3210,7 +3206,7 @@ nest_array_bounds: '[' ']' nest_array_bounds
|
|||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
Typename: Array opt_array_bounds
|
Typename: SimpleTypename opt_array_bounds
|
||||||
{
|
{
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
$$->arrayBounds = $2;
|
$$->arrayBounds = $2;
|
||||||
@ -3232,17 +3228,17 @@ Typename: Array opt_array_bounds
|
|||||||
else
|
else
|
||||||
$$->setof = FALSE;
|
$$->setof = FALSE;
|
||||||
}
|
}
|
||||||
| SETOF Array
|
| SETOF SimpleTypename
|
||||||
{
|
{
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
$$->setof = TRUE;
|
$$->setof = TRUE;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
Array: Generic
|
SimpleTypename: Generic
|
||||||
| Datetime
|
|
||||||
| Numeric
|
| Numeric
|
||||||
| Character
|
| Character
|
||||||
|
| Datetime
|
||||||
;
|
;
|
||||||
|
|
||||||
Generic: generic
|
Generic: generic
|
||||||
@ -3254,7 +3250,7 @@ Generic: generic
|
|||||||
;
|
;
|
||||||
|
|
||||||
generic: IDENT { $$ = $1; }
|
generic: IDENT { $$ = $1; }
|
||||||
| TYPE_P { $$ = xlateSqlType("type"); }
|
| TYPE_P { $$ = "type"; }
|
||||||
;
|
;
|
||||||
|
|
||||||
/* SQL92 numeric data types
|
/* SQL92 numeric data types
|
||||||
@ -3615,21 +3611,18 @@ sub_type: ANY { $$ = ANY_SUBLINK; }
|
|||||||
* All operations/expressions are allowed in a BETWEEN clause
|
* All operations/expressions are allowed in a BETWEEN clause
|
||||||
* if surrounded by parens.
|
* if surrounded by parens.
|
||||||
*/
|
*/
|
||||||
a_expr: attr opt_indirection
|
a_expr: attr
|
||||||
{
|
{ $$ = (Node *) $1; }
|
||||||
$1->indirection = $2;
|
|
||||||
$$ = (Node *)$1;
|
|
||||||
}
|
|
||||||
| row_expr
|
| row_expr
|
||||||
{ $$ = $1; }
|
{ $$ = $1; }
|
||||||
| AexprConst
|
| AexprConst
|
||||||
{ $$ = $1; }
|
{ $$ = $1; }
|
||||||
| ColId
|
| ColId opt_indirection
|
||||||
{
|
{
|
||||||
/* could be a column name or a relation_name */
|
/* could be a column name or a relation_name */
|
||||||
Ident *n = makeNode(Ident);
|
Ident *n = makeNode(Ident);
|
||||||
n->name = $1;
|
n->name = $1;
|
||||||
n->indirection = NULL;
|
n->indirection = $2;
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
| '-' a_expr %prec UMINUS
|
| '-' a_expr %prec UMINUS
|
||||||
@ -3679,7 +3672,7 @@ a_expr: attr opt_indirection
|
|||||||
/* AexprConst can be either A_Const or ParamNo */
|
/* AexprConst can be either A_Const or ParamNo */
|
||||||
if (nodeTag($1) == T_A_Const) {
|
if (nodeTag($1) == T_A_Const) {
|
||||||
((A_Const *)$1)->typename = $3;
|
((A_Const *)$1)->typename = $3;
|
||||||
} else if (nodeTag($1) == T_Param) {
|
} else if (nodeTag($1) == T_ParamNo) {
|
||||||
((ParamNo *)$1)->typename = $3;
|
((ParamNo *)$1)->typename = $3;
|
||||||
/* otherwise, try to transform to a function call */
|
/* otherwise, try to transform to a function call */
|
||||||
} else {
|
} else {
|
||||||
@ -3695,7 +3688,7 @@ a_expr: attr opt_indirection
|
|||||||
/* AexprConst can be either A_Const or ParamNo */
|
/* AexprConst can be either A_Const or ParamNo */
|
||||||
if (nodeTag($3) == T_A_Const) {
|
if (nodeTag($3) == T_A_Const) {
|
||||||
((A_Const *)$3)->typename = $5;
|
((A_Const *)$3)->typename = $5;
|
||||||
} else if (nodeTag($5) == T_Param) {
|
} else if (nodeTag($3) == T_ParamNo) {
|
||||||
((ParamNo *)$3)->typename = $5;
|
((ParamNo *)$3)->typename = $5;
|
||||||
/* otherwise, try to transform to a function call */
|
/* otherwise, try to transform to a function call */
|
||||||
} else {
|
} else {
|
||||||
@ -4282,21 +4275,19 @@ a_expr: attr opt_indirection
|
|||||||
/* Restricted expressions
|
/* Restricted expressions
|
||||||
* b_expr is a subset of the complete expression syntax
|
* b_expr is a subset of the complete expression syntax
|
||||||
* defined by a_expr. b_expr is used in BETWEEN clauses
|
* defined by a_expr. b_expr is used in BETWEEN clauses
|
||||||
* to eliminate parser ambiguities stemming from the AND keyword.
|
* to eliminate parser ambiguities stemming from the AND keyword,
|
||||||
|
* and also in POSITION clauses where the IN keyword gives trouble.
|
||||||
*/
|
*/
|
||||||
b_expr: attr opt_indirection
|
b_expr: attr
|
||||||
{
|
{ $$ = (Node *) $1; }
|
||||||
$1->indirection = $2;
|
|
||||||
$$ = (Node *)$1;
|
|
||||||
}
|
|
||||||
| AexprConst
|
| AexprConst
|
||||||
{ $$ = $1; }
|
{ $$ = $1; }
|
||||||
| ColId
|
| ColId opt_indirection
|
||||||
{
|
{
|
||||||
/* could be a column name or a relation_name */
|
/* could be a column name or a relation_name */
|
||||||
Ident *n = makeNode(Ident);
|
Ident *n = makeNode(Ident);
|
||||||
n->name = $1;
|
n->name = $1;
|
||||||
n->indirection = NULL;
|
n->indirection = $2;
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
| '-' b_expr %prec UMINUS
|
| '-' b_expr %prec UMINUS
|
||||||
@ -4317,10 +4308,10 @@ b_expr: attr opt_indirection
|
|||||||
{ $$ = makeA_Expr(OP, "/", $1, $3); }
|
{ $$ = makeA_Expr(OP, "/", $1, $3); }
|
||||||
| b_expr '%' b_expr
|
| b_expr '%' b_expr
|
||||||
{ $$ = makeA_Expr(OP, "%", $1, $3); }
|
{ $$ = makeA_Expr(OP, "%", $1, $3); }
|
||||||
| b_expr '^' b_expr
|
|
||||||
{ $$ = makeA_Expr(OP, "^", $1, $3); }
|
|
||||||
| b_expr '*' b_expr
|
| b_expr '*' b_expr
|
||||||
{ $$ = makeA_Expr(OP, "*", $1, $3); }
|
{ $$ = makeA_Expr(OP, "*", $1, $3); }
|
||||||
|
| b_expr '^' b_expr
|
||||||
|
{ $$ = makeA_Expr(OP, "^", $1, $3); }
|
||||||
| ':' b_expr
|
| ':' b_expr
|
||||||
{ $$ = makeA_Expr(OP, ":", NULL, $2); }
|
{ $$ = makeA_Expr(OP, ":", NULL, $2); }
|
||||||
| ';' b_expr
|
| ';' b_expr
|
||||||
@ -4333,7 +4324,7 @@ b_expr: attr opt_indirection
|
|||||||
/* AexprConst can be either A_Const or ParamNo */
|
/* AexprConst can be either A_Const or ParamNo */
|
||||||
if (nodeTag($1) == T_A_Const) {
|
if (nodeTag($1) == T_A_Const) {
|
||||||
((A_Const *)$1)->typename = $3;
|
((A_Const *)$1)->typename = $3;
|
||||||
} else if (nodeTag($1) == T_Param) {
|
} else if (nodeTag($1) == T_ParamNo) {
|
||||||
((ParamNo *)$1)->typename = $3;
|
((ParamNo *)$1)->typename = $3;
|
||||||
/* otherwise, try to transform to a function call */
|
/* otherwise, try to transform to a function call */
|
||||||
} else {
|
} else {
|
||||||
@ -4349,7 +4340,7 @@ b_expr: attr opt_indirection
|
|||||||
/* AexprConst can be either A_Const or ParamNo */
|
/* AexprConst can be either A_Const or ParamNo */
|
||||||
if (nodeTag($3) == T_A_Const) {
|
if (nodeTag($3) == T_A_Const) {
|
||||||
((A_Const *)$3)->typename = $5;
|
((A_Const *)$3)->typename = $5;
|
||||||
} else if (nodeTag($3) == T_Param) {
|
} else if (nodeTag($3) == T_ParamNo) {
|
||||||
((ParamNo *)$3)->typename = $5;
|
((ParamNo *)$3)->typename = $5;
|
||||||
/* otherwise, try to transform to a function call */
|
/* otherwise, try to transform to a function call */
|
||||||
} else {
|
} else {
|
||||||
@ -4571,140 +4562,14 @@ extract_arg: datetime { $$ = $1; }
|
|||||||
| TIMEZONE_MINUTE { $$ = "tz_minute"; }
|
| TIMEZONE_MINUTE { $$ = "tz_minute"; }
|
||||||
;
|
;
|
||||||
|
|
||||||
position_list: position_expr IN position_expr
|
/* position_list uses b_expr not a_expr to avoid conflict with general IN */
|
||||||
|
|
||||||
|
position_list: b_expr IN b_expr
|
||||||
{ $$ = makeList($3, $1, -1); }
|
{ $$ = makeList($3, $1, -1); }
|
||||||
| /*EMPTY*/
|
| /*EMPTY*/
|
||||||
{ $$ = NIL; }
|
{ $$ = NIL; }
|
||||||
;
|
;
|
||||||
|
|
||||||
position_expr: attr opt_indirection
|
|
||||||
{
|
|
||||||
$1->indirection = $2;
|
|
||||||
$$ = (Node *)$1;
|
|
||||||
}
|
|
||||||
| AexprConst
|
|
||||||
{ $$ = $1; }
|
|
||||||
| '-' position_expr %prec UMINUS
|
|
||||||
{ $$ = makeA_Expr(OP, "-", NULL, $2); }
|
|
||||||
| position_expr '+' position_expr
|
|
||||||
{ $$ = makeA_Expr(OP, "+", $1, $3); }
|
|
||||||
| position_expr '-' position_expr
|
|
||||||
{ $$ = makeA_Expr(OP, "-", $1, $3); }
|
|
||||||
| position_expr '/' position_expr
|
|
||||||
{ $$ = makeA_Expr(OP, "/", $1, $3); }
|
|
||||||
| position_expr '%' position_expr
|
|
||||||
{ $$ = makeA_Expr(OP, "%", $1, $3); }
|
|
||||||
| position_expr '*' position_expr
|
|
||||||
{ $$ = makeA_Expr(OP, "*", $1, $3); }
|
|
||||||
| '|' position_expr
|
|
||||||
{ $$ = makeA_Expr(OP, "|", NULL, $2); }
|
|
||||||
| position_expr TYPECAST Typename
|
|
||||||
{
|
|
||||||
$$ = (Node *)$1;
|
|
||||||
/* AexprConst can be either A_Const or ParamNo */
|
|
||||||
if (nodeTag($1) == T_A_Const) {
|
|
||||||
((A_Const *)$1)->typename = $3;
|
|
||||||
} else if (nodeTag($1) == T_Param) {
|
|
||||||
((ParamNo *)$1)->typename = $3;
|
|
||||||
/* otherwise, try to transform to a function call */
|
|
||||||
} else {
|
|
||||||
FuncCall *n = makeNode(FuncCall);
|
|
||||||
n->funcname = $3->name;
|
|
||||||
n->args = lcons($1,NIL);
|
|
||||||
$$ = (Node *)n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
| CAST '(' position_expr AS Typename ')'
|
|
||||||
{
|
|
||||||
$$ = (Node *)$3;
|
|
||||||
/* AexprConst can be either A_Const or ParamNo */
|
|
||||||
if (nodeTag($3) == T_A_Const) {
|
|
||||||
((A_Const *)$3)->typename = $5;
|
|
||||||
} else if (nodeTag($3) == T_Param) {
|
|
||||||
((ParamNo *)$3)->typename = $5;
|
|
||||||
/* otherwise, try to transform to a function call */
|
|
||||||
} else {
|
|
||||||
FuncCall *n = makeNode(FuncCall);
|
|
||||||
n->funcname = $5->name;
|
|
||||||
n->args = lcons($3,NIL);
|
|
||||||
$$ = (Node *)n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
| '(' position_expr ')'
|
|
||||||
{ $$ = $2; }
|
|
||||||
| position_expr Op position_expr
|
|
||||||
{ $$ = makeA_Expr(OP, $2, $1, $3); }
|
|
||||||
| Op position_expr
|
|
||||||
{ $$ = makeA_Expr(OP, $1, NULL, $2); }
|
|
||||||
| position_expr Op
|
|
||||||
{ $$ = makeA_Expr(OP, $2, $1, NULL); }
|
|
||||||
| ColId
|
|
||||||
{
|
|
||||||
/* could be a column name or a relation_name */
|
|
||||||
Ident *n = makeNode(Ident);
|
|
||||||
n->name = $1;
|
|
||||||
n->indirection = NULL;
|
|
||||||
$$ = (Node *)n;
|
|
||||||
}
|
|
||||||
| func_name '(' ')'
|
|
||||||
{
|
|
||||||
FuncCall *n = makeNode(FuncCall);
|
|
||||||
n->funcname = $1;
|
|
||||||
n->args = NIL;
|
|
||||||
$$ = (Node *)n;
|
|
||||||
}
|
|
||||||
| func_name '(' expr_list ')'
|
|
||||||
{
|
|
||||||
FuncCall *n = makeNode(FuncCall);
|
|
||||||
n->funcname = $1;
|
|
||||||
n->args = $3;
|
|
||||||
$$ = (Node *)n;
|
|
||||||
}
|
|
||||||
| POSITION '(' position_list ')'
|
|
||||||
{
|
|
||||||
FuncCall *n = makeNode(FuncCall);
|
|
||||||
n->funcname = "strpos";
|
|
||||||
n->args = $3;
|
|
||||||
$$ = (Node *)n;
|
|
||||||
}
|
|
||||||
| SUBSTRING '(' substr_list ')'
|
|
||||||
{
|
|
||||||
FuncCall *n = makeNode(FuncCall);
|
|
||||||
n->funcname = "substr";
|
|
||||||
n->args = $3;
|
|
||||||
$$ = (Node *)n;
|
|
||||||
}
|
|
||||||
/* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
|
|
||||||
| TRIM '(' BOTH trim_list ')'
|
|
||||||
{
|
|
||||||
FuncCall *n = makeNode(FuncCall);
|
|
||||||
n->funcname = "btrim";
|
|
||||||
n->args = $4;
|
|
||||||
$$ = (Node *)n;
|
|
||||||
}
|
|
||||||
| TRIM '(' LEADING trim_list ')'
|
|
||||||
{
|
|
||||||
FuncCall *n = makeNode(FuncCall);
|
|
||||||
n->funcname = "ltrim";
|
|
||||||
n->args = $4;
|
|
||||||
$$ = (Node *)n;
|
|
||||||
}
|
|
||||||
| TRIM '(' TRAILING trim_list ')'
|
|
||||||
{
|
|
||||||
FuncCall *n = makeNode(FuncCall);
|
|
||||||
n->funcname = "rtrim";
|
|
||||||
n->args = $4;
|
|
||||||
$$ = (Node *)n;
|
|
||||||
}
|
|
||||||
| TRIM '(' trim_list ')'
|
|
||||||
{
|
|
||||||
FuncCall *n = makeNode(FuncCall);
|
|
||||||
n->funcname = "btrim";
|
|
||||||
n->args = $3;
|
|
||||||
$$ = (Node *)n;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
substr_list: expr_list substr_from substr_for
|
substr_list: expr_list substr_from substr_for
|
||||||
{
|
{
|
||||||
$$ = nconc(nconc($1,$2),$3);
|
$$ = nconc(nconc($1,$2),$3);
|
||||||
@ -4846,38 +4711,27 @@ case_default: ELSE a_expr_or_null { $$ = $2; }
|
|||||||
| /*EMPTY*/ { $$ = NULL; }
|
| /*EMPTY*/ { $$ = NULL; }
|
||||||
;
|
;
|
||||||
|
|
||||||
case_arg: attr opt_indirection
|
case_arg: a_expr
|
||||||
{
|
{ $$ = $1; }
|
||||||
$1->indirection = $2;
|
|
||||||
$$ = (Node *)$1;
|
|
||||||
}
|
|
||||||
| ColId
|
|
||||||
{
|
|
||||||
/* could be a column name or a relation_name */
|
|
||||||
Ident *n = makeNode(Ident);
|
|
||||||
n->name = $1;
|
|
||||||
n->indirection = NULL;
|
|
||||||
$$ = (Node *)n;
|
|
||||||
}
|
|
||||||
| /*EMPTY*/
|
| /*EMPTY*/
|
||||||
{ $$ = NULL; }
|
{ $$ = NULL; }
|
||||||
;
|
;
|
||||||
|
|
||||||
attr: relation_name '.' attrs
|
attr: relation_name '.' attrs opt_indirection
|
||||||
{
|
{
|
||||||
$$ = makeNode(Attr);
|
$$ = makeNode(Attr);
|
||||||
$$->relname = $1;
|
$$->relname = $1;
|
||||||
$$->paramNo = NULL;
|
$$->paramNo = NULL;
|
||||||
$$->attrs = $3;
|
$$->attrs = $3;
|
||||||
$$->indirection = NULL;
|
$$->indirection = $4;
|
||||||
}
|
}
|
||||||
| ParamNo '.' attrs
|
| ParamNo '.' attrs opt_indirection
|
||||||
{
|
{
|
||||||
$$ = makeNode(Attr);
|
$$ = makeNode(Attr);
|
||||||
$$->relname = NULL;
|
$$->relname = NULL;
|
||||||
$$->paramNo = $1;
|
$$->paramNo = $1;
|
||||||
$$->attrs = $3;
|
$$->attrs = $3;
|
||||||
$$->indirection = NULL;
|
$$->indirection = $4;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -4896,66 +4750,16 @@ attrs: attr_name
|
|||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
res_target_list: res_target_list ',' res_target_el
|
/* Target lists as found in SELECT ... and INSERT VALUES ( ... ) */
|
||||||
{ $$ = lappend($1,$3); }
|
|
||||||
| res_target_el
|
|
||||||
{ $$ = lcons($1, NIL); }
|
|
||||||
| '*'
|
|
||||||
{
|
|
||||||
ResTarget *rt = makeNode(ResTarget);
|
|
||||||
Attr *att = makeNode(Attr);
|
|
||||||
att->relname = "*";
|
|
||||||
att->paramNo = NULL;
|
|
||||||
att->attrs = NULL;
|
|
||||||
att->indirection = NIL;
|
|
||||||
rt->name = NULL;
|
|
||||||
rt->indirection = NULL;
|
|
||||||
rt->val = (Node *)att;
|
|
||||||
$$ = lcons(rt, NIL);
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
res_target_el: ColId opt_indirection '=' a_expr_or_null
|
target_list: target_list ',' target_el
|
||||||
{
|
|
||||||
$$ = makeNode(ResTarget);
|
|
||||||
$$->name = $1;
|
|
||||||
$$->indirection = $2;
|
|
||||||
$$->val = (Node *)$4;
|
|
||||||
}
|
|
||||||
| attr opt_indirection
|
|
||||||
{
|
|
||||||
$$ = makeNode(ResTarget);
|
|
||||||
$$->name = NULL;
|
|
||||||
$$->indirection = $2;
|
|
||||||
$$->val = (Node *)$1;
|
|
||||||
}
|
|
||||||
| relation_name '.' '*'
|
|
||||||
{
|
|
||||||
Attr *att = makeNode(Attr);
|
|
||||||
att->relname = $1;
|
|
||||||
att->paramNo = NULL;
|
|
||||||
att->attrs = lcons(makeString("*"), NIL);
|
|
||||||
att->indirection = NIL;
|
|
||||||
$$ = makeNode(ResTarget);
|
|
||||||
$$->name = NULL;
|
|
||||||
$$->indirection = NULL;
|
|
||||||
$$->val = (Node *)att;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
/*
|
|
||||||
** target list for select.
|
|
||||||
** should get rid of the other but is still needed by the defunct select into
|
|
||||||
** and update (uses a subset)
|
|
||||||
*/
|
|
||||||
res_target_list2: res_target_list2 ',' res_target_el2
|
|
||||||
{ $$ = lappend($1, $3); }
|
{ $$ = lappend($1, $3); }
|
||||||
| res_target_el2
|
| target_el
|
||||||
{ $$ = lcons($1, NIL); }
|
{ $$ = lcons($1, NIL); }
|
||||||
;
|
;
|
||||||
|
|
||||||
/* AS is not optional because shift/red conflict with unary ops */
|
/* AS is not optional because shift/red conflict with unary ops */
|
||||||
res_target_el2: a_expr_or_null AS ColLabel
|
target_el: a_expr_or_null AS ColLabel
|
||||||
{
|
{
|
||||||
$$ = makeNode(ResTarget);
|
$$ = makeNode(ResTarget);
|
||||||
$$->name = $3;
|
$$->name = $3;
|
||||||
@ -4995,10 +4799,29 @@ res_target_el2: a_expr_or_null AS ColLabel
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_id: ColId { $$ = $1; }
|
/* Target list as found in UPDATE table SET ... */
|
||||||
| /*EMPTY*/ { $$ = NULL; }
|
|
||||||
|
update_target_list: update_target_list ',' update_target_el
|
||||||
|
{ $$ = lappend($1,$3); }
|
||||||
|
| update_target_el
|
||||||
|
{ $$ = lcons($1, NIL); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
update_target_el: ColId opt_indirection '=' a_expr_or_null
|
||||||
|
{
|
||||||
|
$$ = makeNode(ResTarget);
|
||||||
|
$$->name = $1;
|
||||||
|
$$->indirection = $2;
|
||||||
|
$$->val = (Node *)$4;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* Names and constants
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
relation_name: SpecialRuleRelation
|
relation_name: SpecialRuleRelation
|
||||||
{
|
{
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
@ -5056,7 +4879,10 @@ AexprConst: Iconst
|
|||||||
n->val.val.str = $1;
|
n->val.val.str = $1;
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
| Typename Sconst
|
/* this rule formerly used Typename, but that causes reduce conflicts
|
||||||
|
* with subscripted column names ...
|
||||||
|
*/
|
||||||
|
| SimpleTypename Sconst
|
||||||
{
|
{
|
||||||
A_Const *n = makeNode(A_Const);
|
A_Const *n = makeNode(A_Const);
|
||||||
n->typename = $1;
|
n->typename = $1;
|
||||||
|
Reference in New Issue
Block a user