mirror of
https://github.com/postgres/postgres.git
synced 2025-05-02 11:44:50 +03:00
Split out everything that looks like a function call from c_expr into
a separate production func_expr. This allows us to accept all these variants in the backwards-compatible syntax for creating a functional index; which beats documenting exactly which things work and which don't. Interestingly, it also seems to make the generated state machine a little bit smaller.
This commit is contained in:
parent
2cda0395bd
commit
912c27f9c2
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.475 2004/08/29 04:12:35 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.476 2004/09/29 23:39:20 tgl Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -272,8 +272,8 @@ static void doNegateFloat(Value *v);
|
|||||||
%type <node> columnDef
|
%type <node> columnDef
|
||||||
%type <defelt> def_elem
|
%type <defelt> def_elem
|
||||||
%type <node> def_arg columnElem where_clause
|
%type <node> def_arg columnElem where_clause
|
||||||
a_expr b_expr c_expr AexprConst indirection_el columnref
|
a_expr b_expr c_expr func_expr AexprConst indirection_el
|
||||||
in_expr having_clause func_table array_expr
|
columnref in_expr having_clause func_table array_expr
|
||||||
%type <list> row type_list array_expr_list
|
%type <list> row type_list array_expr_list
|
||||||
%type <node> case_expr case_arg when_clause case_default
|
%type <node> case_expr case_arg when_clause case_default
|
||||||
%type <list> when_clause_list
|
%type <list> when_clause_list
|
||||||
@ -3238,18 +3238,12 @@ index_elem: ColId opt_class
|
|||||||
$$->expr = NULL;
|
$$->expr = NULL;
|
||||||
$$->opclass = $2;
|
$$->opclass = $2;
|
||||||
}
|
}
|
||||||
| func_name '(' expr_list ')' opt_class
|
| func_expr opt_class
|
||||||
{
|
{
|
||||||
FuncCall *n = makeNode(FuncCall);
|
|
||||||
n->funcname = $1;
|
|
||||||
n->args = $3;
|
|
||||||
n->agg_star = FALSE;
|
|
||||||
n->agg_distinct = FALSE;
|
|
||||||
|
|
||||||
$$ = makeNode(IndexElem);
|
$$ = makeNode(IndexElem);
|
||||||
$$->name = NULL;
|
$$->name = NULL;
|
||||||
$$->expr = (Node *)n;
|
$$->expr = $1;
|
||||||
$$->opclass = $5;
|
$$->opclass = $2;
|
||||||
}
|
}
|
||||||
| '(' a_expr ')' opt_class
|
| '(' a_expr ')' opt_class
|
||||||
{
|
{
|
||||||
@ -6479,7 +6473,55 @@ c_expr: columnref { $$ = $1; }
|
|||||||
}
|
}
|
||||||
| case_expr
|
| case_expr
|
||||||
{ $$ = $1; }
|
{ $$ = $1; }
|
||||||
| func_name '(' ')'
|
| func_expr
|
||||||
|
{ $$ = $1; }
|
||||||
|
| select_with_parens %prec UMINUS
|
||||||
|
{
|
||||||
|
SubLink *n = makeNode(SubLink);
|
||||||
|
n->subLinkType = EXPR_SUBLINK;
|
||||||
|
n->lefthand = NIL;
|
||||||
|
n->operName = NIL;
|
||||||
|
n->subselect = $1;
|
||||||
|
$$ = (Node *)n;
|
||||||
|
}
|
||||||
|
| EXISTS select_with_parens
|
||||||
|
{
|
||||||
|
SubLink *n = makeNode(SubLink);
|
||||||
|
n->subLinkType = EXISTS_SUBLINK;
|
||||||
|
n->lefthand = NIL;
|
||||||
|
n->operName = NIL;
|
||||||
|
n->subselect = $2;
|
||||||
|
$$ = (Node *)n;
|
||||||
|
}
|
||||||
|
| ARRAY select_with_parens
|
||||||
|
{
|
||||||
|
SubLink *n = makeNode(SubLink);
|
||||||
|
n->subLinkType = ARRAY_SUBLINK;
|
||||||
|
n->lefthand = NIL;
|
||||||
|
n->operName = NIL;
|
||||||
|
n->subselect = $2;
|
||||||
|
$$ = (Node *)n;
|
||||||
|
}
|
||||||
|
| ARRAY array_expr
|
||||||
|
{ $$ = $2; }
|
||||||
|
| row
|
||||||
|
{
|
||||||
|
RowExpr *r = makeNode(RowExpr);
|
||||||
|
r->args = $1;
|
||||||
|
r->row_typeid = InvalidOid; /* not analyzed yet */
|
||||||
|
$$ = (Node *)r;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* func_expr is split out from c_expr just so that we have a classification
|
||||||
|
* for "everything that is a function call or looks like one". This isn't
|
||||||
|
* very important, but it saves us having to document which variants are
|
||||||
|
* legal in the backwards-compatible functional-index syntax for CREATE INDEX.
|
||||||
|
* (Note that many of the special SQL functions wouldn't actually make any
|
||||||
|
* sense as functional index entries, but we ignore that consideration here.)
|
||||||
|
*/
|
||||||
|
func_expr: func_name '(' ')'
|
||||||
{
|
{
|
||||||
FuncCall *n = makeNode(FuncCall);
|
FuncCall *n = makeNode(FuncCall);
|
||||||
n->funcname = $1;
|
n->funcname = $1;
|
||||||
@ -6936,42 +6978,6 @@ c_expr: columnref { $$ = $1; }
|
|||||||
n->agg_distinct = FALSE;
|
n->agg_distinct = FALSE;
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
| select_with_parens %prec UMINUS
|
|
||||||
{
|
|
||||||
SubLink *n = makeNode(SubLink);
|
|
||||||
n->subLinkType = EXPR_SUBLINK;
|
|
||||||
n->lefthand = NIL;
|
|
||||||
n->operName = NIL;
|
|
||||||
n->subselect = $1;
|
|
||||||
$$ = (Node *)n;
|
|
||||||
}
|
|
||||||
| EXISTS select_with_parens
|
|
||||||
{
|
|
||||||
SubLink *n = makeNode(SubLink);
|
|
||||||
n->subLinkType = EXISTS_SUBLINK;
|
|
||||||
n->lefthand = NIL;
|
|
||||||
n->operName = NIL;
|
|
||||||
n->subselect = $2;
|
|
||||||
$$ = (Node *)n;
|
|
||||||
}
|
|
||||||
| ARRAY select_with_parens
|
|
||||||
{
|
|
||||||
SubLink *n = makeNode(SubLink);
|
|
||||||
n->subLinkType = ARRAY_SUBLINK;
|
|
||||||
n->lefthand = NIL;
|
|
||||||
n->operName = NIL;
|
|
||||||
n->subselect = $2;
|
|
||||||
$$ = (Node *)n;
|
|
||||||
}
|
|
||||||
| ARRAY array_expr
|
|
||||||
{ $$ = $2; }
|
|
||||||
| row
|
|
||||||
{
|
|
||||||
RowExpr *r = makeNode(RowExpr);
|
|
||||||
r->args = $1;
|
|
||||||
r->row_typeid = InvalidOid; /* not analyzed yet */
|
|
||||||
$$ = (Node *)r;
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user