mirror of
https://github.com/postgres/postgres.git
synced 2025-07-09 22:41:56 +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:
contrib/pg_stat_statements
src
backend
executor
nodes
optimizer
util
parser
utils
include
pl
plpgsql
src
test
regress
@ -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,
|
||||
@ -3530,6 +3535,75 @@ ExecEvalMinMax(MinMaxExprState *minmaxExpr, ExprContext *econtext,
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* 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;
|
||||
|
Reference in New Issue
Block a user