From 0bb51aa96783e8a6c473c2b5e3725e23e95db834 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 16 Aug 2016 20:33:01 -0400 Subject: 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> --- src/backend/parser/parse_expr.c | 62 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'src/backend/parser/parse_expr.c') diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index cead21283d0..63f7965532e 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -34,7 +34,9 @@ #include "parser/parse_type.h" #include "parser/parse_agg.h" #include "utils/builtins.h" +#include "utils/date.h" #include "utils/lsyscache.h" +#include "utils/timestamp.h" #include "utils/xml.h" @@ -107,6 +109,8 @@ static Node *transformArrayExpr(ParseState *pstate, A_ArrayExpr *a, static Node *transformRowExpr(ParseState *pstate, RowExpr *r); static Node *transformCoalesceExpr(ParseState *pstate, CoalesceExpr *c); static Node *transformMinMaxExpr(ParseState *pstate, MinMaxExpr *m); +static Node *transformSQLValueFunction(ParseState *pstate, + SQLValueFunction *svf); static Node *transformXmlExpr(ParseState *pstate, XmlExpr *x); static Node *transformXmlSerialize(ParseState *pstate, XmlSerialize *xs); static Node *transformBooleanTest(ParseState *pstate, BooleanTest *b); @@ -306,6 +310,11 @@ transformExprRecurse(ParseState *pstate, Node *expr) result = transformMinMaxExpr(pstate, (MinMaxExpr *) expr); break; + case T_SQLValueFunction: + result = transformSQLValueFunction(pstate, + (SQLValueFunction *) expr); + break; + case T_XmlExpr: result = transformXmlExpr(pstate, (XmlExpr *) expr); break; @@ -2178,6 +2187,59 @@ transformMinMaxExpr(ParseState *pstate, MinMaxExpr *m) return (Node *) newm; } +static Node * +transformSQLValueFunction(ParseState *pstate, SQLValueFunction *svf) +{ + /* + * All we need to do is insert the correct result type and (where needed) + * validate the typmod, so we just modify the node in-place. + */ + switch (svf->op) + { + case SVFOP_CURRENT_DATE: + svf->type = DATEOID; + break; + case SVFOP_CURRENT_TIME: + svf->type = TIMETZOID; + break; + case SVFOP_CURRENT_TIME_N: + svf->type = TIMETZOID; + svf->typmod = anytime_typmod_check(true, svf->typmod); + break; + case SVFOP_CURRENT_TIMESTAMP: + svf->type = TIMESTAMPTZOID; + break; + case SVFOP_CURRENT_TIMESTAMP_N: + svf->type = TIMESTAMPTZOID; + svf->typmod = anytimestamp_typmod_check(true, svf->typmod); + break; + case SVFOP_LOCALTIME: + svf->type = TIMEOID; + break; + case SVFOP_LOCALTIME_N: + svf->type = TIMEOID; + svf->typmod = anytime_typmod_check(false, svf->typmod); + break; + case SVFOP_LOCALTIMESTAMP: + svf->type = TIMESTAMPOID; + break; + case SVFOP_LOCALTIMESTAMP_N: + svf->type = TIMESTAMPOID; + svf->typmod = anytimestamp_typmod_check(false, svf->typmod); + break; + case SVFOP_CURRENT_ROLE: + case SVFOP_CURRENT_USER: + case SVFOP_USER: + case SVFOP_SESSION_USER: + case SVFOP_CURRENT_CATALOG: + case SVFOP_CURRENT_SCHEMA: + svf->type = NAMEOID; + break; + } + + return (Node *) svf; +} + static Node * transformXmlExpr(ParseState *pstate, XmlExpr *x) { -- cgit v1.2.3