1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-05 07:21:24 +03:00

Improve parsetree representation of special functions such as CURRENT_DATE.

We implement a dozen or so parameterless functions that the SQL standard
defines special syntax for.  Up to now, that was done by converting them
into more or less ad-hoc constructs such as "'now'::text::date".  That's
messy for multiple reasons: it exposes what should be implementation
details to users, and performance is worse than it needs to be in several
cases.  To improve matters, invent a new expression node type
SQLValueFunction that can represent any of these parameterless functions.

Bump catversion because this changes stored parsetrees for rules.

Discussion: <30058.1463091294@sss.pgh.pa.us>
This commit is contained in:
Tom Lane
2016-08-16 20:33:01 -04:00
parent 4bc4cfe3bd
commit 0bb51aa967
24 changed files with 626 additions and 168 deletions

View File

@ -218,6 +218,9 @@ exprType(const Node *expr)
case T_MinMaxExpr:
type = ((const MinMaxExpr *) expr)->minmaxtype;
break;
case T_SQLValueFunction:
type = ((const SQLValueFunction *) expr)->type;
break;
case T_XmlExpr:
if (((const XmlExpr *) expr)->op == IS_DOCUMENT)
type = BOOLOID;
@ -479,6 +482,8 @@ exprTypmod(const Node *expr)
return typmod;
}
break;
case T_SQLValueFunction:
return ((const SQLValueFunction *) expr)->typmod;
case T_CoerceToDomain:
return ((const CoerceToDomain *) expr)->resulttypmod;
case T_CoerceToDomainValue:
@ -718,6 +723,8 @@ expression_returns_set_walker(Node *node, void *context)
return false;
if (IsA(node, MinMaxExpr))
return false;
if (IsA(node, SQLValueFunction))
return false;
if (IsA(node, XmlExpr))
return false;
@ -883,6 +890,9 @@ exprCollation(const Node *expr)
case T_MinMaxExpr:
coll = ((const MinMaxExpr *) expr)->minmaxcollid;
break;
case T_SQLValueFunction:
coll = InvalidOid; /* all cases return non-collatable types */
break;
case T_XmlExpr:
/*
@ -1091,6 +1101,9 @@ exprSetCollation(Node *expr, Oid collation)
case T_MinMaxExpr:
((MinMaxExpr *) expr)->minmaxcollid = collation;
break;
case T_SQLValueFunction:
Assert(!OidIsValid(collation)); /* no collatable results */
break;
case T_XmlExpr:
Assert((((XmlExpr *) expr)->op == IS_XMLSERIALIZE) ?
(collation == DEFAULT_COLLATION_OID) :
@ -1364,6 +1377,10 @@ exprLocation(const Node *expr)
/* GREATEST/LEAST keyword should always be the first thing */
loc = ((const MinMaxExpr *) expr)->location;
break;
case T_SQLValueFunction:
/* function keyword should always be the first thing */
loc = ((const SQLValueFunction *) expr)->location;
break;
case T_XmlExpr:
{
const XmlExpr *xexpr = (const XmlExpr *) expr;
@ -1633,9 +1650,10 @@ set_sa_opfuncid(ScalarArrayOpExpr *opexpr)
* for themselves, in case additional checks should be made, or because they
* have special rules about which parts of the tree need to be visited.
*
* Note: we ignore MinMaxExpr, XmlExpr, and CoerceToDomain nodes, because they
* do not contain SQL function OIDs. However, they can invoke SQL-visible
* functions, so callers should take thought about how to treat them.
* Note: we ignore MinMaxExpr, SQLValueFunction, XmlExpr, and CoerceToDomain
* nodes, because they do not contain SQL function OIDs. However, they can
* invoke SQL-visible functions, so callers should take thought about how to
* treat them.
*/
bool
check_functions_in_node(Node *node, check_function_callback checker,
@ -1859,6 +1877,7 @@ expression_tree_walker(Node *node,
case T_CaseTestExpr:
case T_SetToDefault:
case T_CurrentOfExpr:
case T_SQLValueFunction:
case T_RangeTblRef:
case T_SortGroupClause:
/* primitive node types with no expression subnodes */
@ -2433,6 +2452,7 @@ expression_tree_mutator(Node *node,
case T_CaseTestExpr:
case T_SetToDefault:
case T_CurrentOfExpr:
case T_SQLValueFunction:
case T_RangeTblRef:
case T_SortGroupClause:
return (Node *) copyObject(node);
@ -3197,6 +3217,7 @@ raw_expression_tree_walker(Node *node,
{
case T_SetToDefault:
case T_CurrentOfExpr:
case T_SQLValueFunction:
case T_Integer:
case T_Float:
case T_String: