Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit f193883

Browse files
committed
Replace SQLValueFunction by COERCE_SQL_SYNTAX
This switch impacts 9 patterns related to a SQL-mandated special syntax for function calls: - LOCALTIME [ ( typmod ) ] - LOCALTIMESTAMP [ ( typmod ) ] - CURRENT_TIME [ ( typmod ) ] - CURRENT_TIMESTAMP [ ( typmod ) ] - CURRENT_DATE Five new entries are added to pg_proc to compensate the removal of SQLValueFunction to provide backward-compatibility and making this change transparent for the end-user (for example for the attribute generated when a keyword is specified in a SELECT or in a FROM clause without an alias, or when specifying something else than an Iconst to the parser). The parser included a set of checks coming from the files in charge of holding the C functions used for the SQLValueFunction calls (as of transformSQLValueFunction()), which are now moved within each function's execution path, so this reduces the dependencies between the execution and the parsing steps. As of this change, all the SQL keywords use the same paths for their work, relying only on COERCE_SQL_SYNTAX. Like fb32748, no performance difference has been noticed, while the perf profiles get reduced with ExecEvalSQLValueFunction() gone. Bump catalog version. Reviewed-by: Corey Huinker, Ted Yu Discussion: https://postgr.es/m/YzaG3MoryCguUOym@paquier.xyz
1 parent 240e0db commit f193883

File tree

24 files changed

+231
-390
lines changed

24 files changed

+231
-390
lines changed

src/backend/catalog/system_functions.sql

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,32 @@ LANGUAGE internal
594594
STRICT IMMUTABLE PARALLEL SAFE
595595
AS 'unicode_is_normalized';
596596

597+
-- Functions with SQL-mandated special syntax and some defaults.
598+
CREATE OR REPLACE FUNCTION
599+
"current_time"(int4 DEFAULT NULL)
600+
RETURNS timetz
601+
LANGUAGE internal
602+
STABLE PARALLEL SAFE
603+
AS 'current_time';
604+
CREATE OR REPLACE FUNCTION
605+
"current_timestamp"(int4 DEFAULT NULL)
606+
RETURNS timestamptz
607+
LANGUAGE internal
608+
STABLE PARALLEL SAFE
609+
AS 'current_timestamp';
610+
CREATE OR REPLACE FUNCTION
611+
"localtime"(int4 DEFAULT NULL)
612+
RETURNS time
613+
LANGUAGE internal
614+
STABLE PARALLEL SAFE
615+
AS 'sql_localtime';
616+
CREATE OR REPLACE FUNCTION
617+
"localtimestamp"(int4 DEFAULT NULL)
618+
RETURNS timestamp
619+
LANGUAGE internal
620+
STABLE PARALLEL SAFE
621+
AS 'sql_localtimestamp';
622+
597623
--
598624
-- The default permissions for functions mean that anyone can execute them.
599625
-- A number of functions shouldn't be executable by just anyone, but rather

src/backend/executor/execExpr.c

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2210,17 +2210,6 @@ ExecInitExprRec(Expr *node, ExprState *state,
22102210
break;
22112211
}
22122212

2213-
case T_SQLValueFunction:
2214-
{
2215-
SQLValueFunction *svf = (SQLValueFunction *) node;
2216-
2217-
scratch.opcode = EEOP_SQLVALUEFUNCTION;
2218-
scratch.d.sqlvaluefunction.svf = svf;
2219-
2220-
ExprEvalPushStep(state, &scratch);
2221-
break;
2222-
}
2223-
22242213
case T_XmlExpr:
22252214
{
22262215
XmlExpr *xexpr = (XmlExpr *) node;

src/backend/executor/execExprInterp.c

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,6 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
452452
&&CASE_EEOP_DISTINCT,
453453
&&CASE_EEOP_NOT_DISTINCT,
454454
&&CASE_EEOP_NULLIF,
455-
&&CASE_EEOP_SQLVALUEFUNCTION,
456455
&&CASE_EEOP_CURRENTOFEXPR,
457456
&&CASE_EEOP_NEXTVALUEEXPR,
458457
&&CASE_EEOP_ARRAYEXPR,
@@ -1301,17 +1300,6 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
13011300
EEO_NEXT();
13021301
}
13031302

1304-
EEO_CASE(EEOP_SQLVALUEFUNCTION)
1305-
{
1306-
/*
1307-
* Doesn't seem worthwhile to have an inline implementation
1308-
* efficiency-wise.
1309-
*/
1310-
ExecEvalSQLValueFunction(state, op);
1311-
1312-
EEO_NEXT();
1313-
}
1314-
13151303
EEO_CASE(EEOP_CURRENTOFEXPR)
13161304
{
13171305
/* error invocation uses space, and shouldn't ever occur */
@@ -2489,40 +2477,6 @@ ExecEvalParamExtern(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
24892477
errmsg("no value found for parameter %d", paramId)));
24902478
}
24912479

2492-
/*
2493-
* Evaluate a SQLValueFunction expression.
2494-
*/
2495-
void
2496-
ExecEvalSQLValueFunction(ExprState *state, ExprEvalStep *op)
2497-
{
2498-
SQLValueFunction *svf = op->d.sqlvaluefunction.svf;
2499-
2500-
*op->resnull = false;
2501-
2502-
switch (svf->op)
2503-
{
2504-
case SVFOP_CURRENT_DATE:
2505-
*op->resvalue = DateADTGetDatum(GetSQLCurrentDate());
2506-
break;
2507-
case SVFOP_CURRENT_TIME:
2508-
case SVFOP_CURRENT_TIME_N:
2509-
*op->resvalue = TimeTzADTPGetDatum(GetSQLCurrentTime(svf->typmod));
2510-
break;
2511-
case SVFOP_CURRENT_TIMESTAMP:
2512-
case SVFOP_CURRENT_TIMESTAMP_N:
2513-
*op->resvalue = TimestampTzGetDatum(GetSQLCurrentTimestamp(svf->typmod));
2514-
break;
2515-
case SVFOP_LOCALTIME:
2516-
case SVFOP_LOCALTIME_N:
2517-
*op->resvalue = TimeADTGetDatum(GetSQLLocalTime(svf->typmod));
2518-
break;
2519-
case SVFOP_LOCALTIMESTAMP:
2520-
case SVFOP_LOCALTIMESTAMP_N:
2521-
*op->resvalue = TimestampGetDatum(GetSQLLocalTimestamp(svf->typmod));
2522-
break;
2523-
}
2524-
}
2525-
25262480
/*
25272481
* Raise error if a CURRENT OF expression is evaluated.
25282482
*

src/backend/jit/llvm/llvmjit_expr.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1549,12 +1549,6 @@ llvm_compile_expr(ExprState *state)
15491549
break;
15501550
}
15511551

1552-
case EEOP_SQLVALUEFUNCTION:
1553-
build_EvalXFunc(b, mod, "ExecEvalSQLValueFunction",
1554-
v_state, op);
1555-
LLVMBuildBr(b, opblocks[opno + 1]);
1556-
break;
1557-
15581552
case EEOP_CURRENTOFEXPR:
15591553
build_EvalXFunc(b, mod, "ExecEvalCurrentOfExpr",
15601554
v_state, op);

src/backend/jit/llvm/llvmjit_types.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ void *referenced_functions[] =
126126
ExecEvalRow,
127127
ExecEvalRowNotNull,
128128
ExecEvalRowNull,
129-
ExecEvalSQLValueFunction,
130129
ExecEvalScalarArrayOp,
131130
ExecEvalHashedScalarArrayOp,
132131
ExecEvalSubPlan,

src/backend/nodes/nodeFuncs.c

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -210,9 +210,6 @@ exprType(const Node *expr)
210210
case T_MinMaxExpr:
211211
type = ((const MinMaxExpr *) expr)->minmaxtype;
212212
break;
213-
case T_SQLValueFunction:
214-
type = ((const SQLValueFunction *) expr)->type;
215-
break;
216213
case T_XmlExpr:
217214
if (((const XmlExpr *) expr)->op == IS_DOCUMENT)
218215
type = BOOLOID;
@@ -474,8 +471,6 @@ exprTypmod(const Node *expr)
474471
return typmod;
475472
}
476473
break;
477-
case T_SQLValueFunction:
478-
return ((const SQLValueFunction *) expr)->typmod;
479474
case T_CoerceToDomain:
480475
return ((const CoerceToDomain *) expr)->resulttypmod;
481476
case T_CoerceToDomainValue:
@@ -916,10 +911,6 @@ exprCollation(const Node *expr)
916911
case T_MinMaxExpr:
917912
coll = ((const MinMaxExpr *) expr)->minmaxcollid;
918913
break;
919-
case T_SQLValueFunction:
920-
/* Returns a non-collatable type */
921-
coll = InvalidOid;
922-
break;
923914
case T_XmlExpr:
924915

925916
/*
@@ -1140,9 +1131,6 @@ exprSetCollation(Node *expr, Oid collation)
11401131
case T_MinMaxExpr:
11411132
((MinMaxExpr *) expr)->minmaxcollid = collation;
11421133
break;
1143-
case T_SQLValueFunction:
1144-
Assert(collation == InvalidOid);
1145-
break;
11461134
case T_XmlExpr:
11471135
Assert((((XmlExpr *) expr)->op == IS_XMLSERIALIZE) ?
11481136
(collation == DEFAULT_COLLATION_OID) :
@@ -1426,10 +1414,6 @@ exprLocation(const Node *expr)
14261414
/* GREATEST/LEAST keyword should always be the first thing */
14271415
loc = ((const MinMaxExpr *) expr)->location;
14281416
break;
1429-
case T_SQLValueFunction:
1430-
/* function keyword should always be the first thing */
1431-
loc = ((const SQLValueFunction *) expr)->location;
1432-
break;
14331417
case T_XmlExpr:
14341418
{
14351419
const XmlExpr *xexpr = (const XmlExpr *) expr;
@@ -1717,10 +1701,10 @@ set_sa_opfuncid(ScalarArrayOpExpr *opexpr)
17171701
* for themselves, in case additional checks should be made, or because they
17181702
* have special rules about which parts of the tree need to be visited.
17191703
*
1720-
* Note: we ignore MinMaxExpr, SQLValueFunction, XmlExpr, CoerceToDomain,
1721-
* and NextValueExpr nodes, because they do not contain SQL function OIDs.
1722-
* However, they can invoke SQL-visible functions, so callers should take
1723-
* thought about how to treat them.
1704+
* Note: we ignore MinMaxExpr, XmlExpr, CoerceToDomain, and NextValueExpr
1705+
* nodes, because they do not contain SQL function OIDs. However, they can
1706+
* invoke SQL-visible functions, so callers should take thought about how
1707+
* to treat them.
17241708
*/
17251709
bool
17261710
check_functions_in_node(Node *node, check_function_callback checker,
@@ -1936,7 +1920,6 @@ expression_tree_walker_impl(Node *node,
19361920
case T_Const:
19371921
case T_Param:
19381922
case T_CaseTestExpr:
1939-
case T_SQLValueFunction:
19401923
case T_CoerceToDomainValue:
19411924
case T_SetToDefault:
19421925
case T_CurrentOfExpr:
@@ -2673,7 +2656,6 @@ expression_tree_mutator_impl(Node *node,
26732656
break;
26742657
case T_Param:
26752658
case T_CaseTestExpr:
2676-
case T_SQLValueFunction:
26772659
case T_CoerceToDomainValue:
26782660
case T_SetToDefault:
26792661
case T_CurrentOfExpr:
@@ -3587,7 +3569,6 @@ raw_expression_tree_walker_impl(Node *node,
35873569
{
35883570
case T_SetToDefault:
35893571
case T_CurrentOfExpr:
3590-
case T_SQLValueFunction:
35913572
case T_Integer:
35923573
case T_Float:
35933574
case T_Boolean:

src/backend/optimizer/path/costsize.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4603,7 +4603,6 @@ cost_qual_eval_walker(Node *node, cost_qual_eval_context *context)
46034603
}
46044604
}
46054605
else if (IsA(node, MinMaxExpr) ||
4606-
IsA(node, SQLValueFunction) ||
46074606
IsA(node, XmlExpr) ||
46084607
IsA(node, CoerceToDomain) ||
46094608
IsA(node, NextValueExpr))

src/backend/optimizer/util/clauses.c

Lines changed: 7 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -383,12 +383,6 @@ contain_mutable_functions_walker(Node *node, void *context)
383383
context))
384384
return true;
385385

386-
if (IsA(node, SQLValueFunction))
387-
{
388-
/* all variants of SQLValueFunction are stable */
389-
return true;
390-
}
391-
392386
if (IsA(node, NextValueExpr))
393387
{
394388
/* NextValueExpr is volatile */
@@ -537,8 +531,8 @@ contain_volatile_functions_walker(Node *node, void *context)
537531

538532
/*
539533
* See notes in contain_mutable_functions_walker about why we treat
540-
* MinMaxExpr, XmlExpr, and CoerceToDomain as immutable, while
541-
* SQLValueFunction is stable. Hence, none of them are of interest here.
534+
* MinMaxExpr, XmlExpr, and CoerceToDomain as immutable. Hence, none of
535+
* them are of interest here.
542536
*/
543537

544538
/* Recurse to check arguments */
@@ -583,10 +577,9 @@ contain_volatile_functions_not_nextval_walker(Node *node, void *context)
583577

584578
/*
585579
* See notes in contain_mutable_functions_walker about why we treat
586-
* MinMaxExpr, XmlExpr, and CoerceToDomain as immutable, while
587-
* SQLValueFunction is stable. Hence, none of them are of interest here.
588-
* Also, since we're intentionally ignoring nextval(), presumably we
589-
* should ignore NextValueExpr.
580+
* MinMaxExpr, XmlExpr, and CoerceToDomain as immutable. Hence, none of
581+
* them are of interest here. Also, since we're intentionally ignoring
582+
* nextval(), presumably we should ignore NextValueExpr.
590583
*/
591584

592585
/* Recurse to check arguments */
@@ -732,8 +725,8 @@ max_parallel_hazard_walker(Node *node, max_parallel_hazard_context *context)
732725
* (Note: in principle that's wrong because a domain constraint could
733726
* contain a parallel-unsafe function; but useful constraints probably
734727
* never would have such, and assuming they do would cripple use of
735-
* parallel query in the presence of domain types.) SQLValueFunction
736-
* should be safe in all cases. NextValueExpr is parallel-unsafe.
728+
* parallel query in the presence of domain types.) NextValueExpr is
729+
* parallel-unsafe.
737730
*/
738731
if (IsA(node, CoerceToDomain))
739732
{
@@ -1180,7 +1173,6 @@ contain_leaked_vars_walker(Node *node, void *context)
11801173
case T_CaseExpr:
11811174
case T_CaseTestExpr:
11821175
case T_RowExpr:
1183-
case T_SQLValueFunction:
11841176
case T_NullTest:
11851177
case T_BooleanTest:
11861178
case T_NextValueExpr:
@@ -3194,23 +3186,6 @@ eval_const_expressions_mutator(Node *node,
31943186
newcoalesce->location = coalesceexpr->location;
31953187
return (Node *) newcoalesce;
31963188
}
3197-
case T_SQLValueFunction:
3198-
{
3199-
/*
3200-
* All variants of SQLValueFunction are stable, so if we are
3201-
* estimating the expression's value, we should evaluate the
3202-
* current function value. Otherwise just copy.
3203-
*/
3204-
SQLValueFunction *svf = (SQLValueFunction *) node;
3205-
3206-
if (context->estimate)
3207-
return (Node *) evaluate_expr((Expr *) svf,
3208-
svf->type,
3209-
svf->typmod,
3210-
InvalidOid);
3211-
else
3212-
return copyObject((Node *) svf);
3213-
}
32143189
case T_FieldSelect:
32153190
{
32163191
/*

0 commit comments

Comments
 (0)