diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2016-08-16 20:33:01 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2016-08-16 20:33:01 -0400 |
commit | 0bb51aa96783e8a6c473c2b5e3725e23e95db834 (patch) | |
tree | f4d4077257f5a4937fefafd0fe6f914f5e4027fd /src/backend/executor | |
parent | 4bc4cfe3bd186b4a1d1b01279bfd0e6ab11268b2 (diff) | |
download | postgresql-0bb51aa96783e8a6c473c2b5e3725e23e95db834.tar.gz postgresql-0bb51aa96783e8a6c473c2b5e3725e23e95db834.zip |
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>
Diffstat (limited to 'src/backend/executor')
-rw-r--r-- | src/backend/executor/execQual.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c index cbb76d1f1cd..743e7d636a0 100644 --- a/src/backend/executor/execQual.c +++ b/src/backend/executor/execQual.c @@ -53,8 +53,10 @@ #include "pgstat.h" #include "utils/acl.h" #include "utils/builtins.h" +#include "utils/date.h" #include "utils/lsyscache.h" #include "utils/memutils.h" +#include "utils/timestamp.h" #include "utils/typcache.h" #include "utils/xml.h" @@ -147,6 +149,9 @@ static Datum ExecEvalCoalesce(CoalesceExprState *coalesceExpr, static Datum ExecEvalMinMax(MinMaxExprState *minmaxExpr, ExprContext *econtext, bool *isNull, ExprDoneCond *isDone); +static Datum ExecEvalSQLValueFunction(ExprState *svfExpr, + ExprContext *econtext, + bool *isNull, ExprDoneCond *isDone); static Datum ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext, bool *isNull, ExprDoneCond *isDone); static Datum ExecEvalNullIf(FuncExprState *nullIfExpr, @@ -3531,6 +3536,75 @@ ExecEvalMinMax(MinMaxExprState *minmaxExpr, ExprContext *econtext, } /* ---------------------------------------------------------------- + * ExecEvalSQLValueFunction + * ---------------------------------------------------------------- + */ +static Datum +ExecEvalSQLValueFunction(ExprState *svfExpr, + ExprContext *econtext, + bool *isNull, ExprDoneCond *isDone) +{ + Datum result = (Datum) 0; + SQLValueFunction *svf = (SQLValueFunction *) svfExpr->expr; + FunctionCallInfoData fcinfo; + + if (isDone) + *isDone = ExprSingleResult; + *isNull = false; + + /* + * Note: current_schema() can return NULL. current_user() etc currently + * cannot, but might as well code those cases the same way for safety. + */ + switch (svf->op) + { + case SVFOP_CURRENT_DATE: + result = DateADTGetDatum(GetSQLCurrentDate()); + break; + case SVFOP_CURRENT_TIME: + case SVFOP_CURRENT_TIME_N: + result = TimeTzADTPGetDatum(GetSQLCurrentTime(svf->typmod)); + break; + case SVFOP_CURRENT_TIMESTAMP: + case SVFOP_CURRENT_TIMESTAMP_N: + result = TimestampTzGetDatum(GetSQLCurrentTimestamp(svf->typmod)); + break; + case SVFOP_LOCALTIME: + case SVFOP_LOCALTIME_N: + result = TimeADTGetDatum(GetSQLLocalTime(svf->typmod)); + break; + case SVFOP_LOCALTIMESTAMP: + case SVFOP_LOCALTIMESTAMP_N: + result = TimestampGetDatum(GetSQLLocalTimestamp(svf->typmod)); + break; + case SVFOP_CURRENT_ROLE: + case SVFOP_CURRENT_USER: + case SVFOP_USER: + InitFunctionCallInfoData(fcinfo, NULL, 0, InvalidOid, NULL, NULL); + result = current_user(&fcinfo); + *isNull = fcinfo.isnull; + break; + case SVFOP_SESSION_USER: + InitFunctionCallInfoData(fcinfo, NULL, 0, InvalidOid, NULL, NULL); + result = session_user(&fcinfo); + *isNull = fcinfo.isnull; + break; + case SVFOP_CURRENT_CATALOG: + InitFunctionCallInfoData(fcinfo, NULL, 0, InvalidOid, NULL, NULL); + result = current_database(&fcinfo); + *isNull = fcinfo.isnull; + break; + case SVFOP_CURRENT_SCHEMA: + InitFunctionCallInfoData(fcinfo, NULL, 0, InvalidOid, NULL, NULL); + result = current_schema(&fcinfo); + *isNull = fcinfo.isnull; + break; + } + + return result; +} + +/* ---------------------------------------------------------------- * ExecEvalXml * ---------------------------------------------------------------- */ @@ -5086,6 +5160,10 @@ ExecInitExpr(Expr *node, PlanState *parent) state = (ExprState *) mstate; } break; + case T_SQLValueFunction: + state = (ExprState *) makeNode(ExprState); + state->evalfunc = ExecEvalSQLValueFunction; + break; case T_XmlExpr: { XmlExpr *xexpr = (XmlExpr *) node; |