Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Paquier2023-05-17 01:19:17 +0000
committerMichael Paquier2023-05-17 01:19:17 +0000
commitd8c3106bb60e4f87be595f241e173ba3c2b7aa2c (patch)
tree48ebeb093661e58b99c7d5645b40e4a5336524ab /src/backend/optimizer
parent1d369c9e90f311ec98b07a259cac48c404c773d5 (diff)
Add back SQLValueFunction for SQL keywords
This is equivalent to a revert of f193883 and fb32748, with the addition that the declaration of the SQLValueFunction node needs to gain a couple of node_attr for query jumbling. The performance impact of removing the function call inlining is proving to be too huge for some workloads where these are used. A worst-case test case of involving only simple SELECT queries with a SQL keyword is proving to lead to a reduction of 10% in TPS via pgbench and prepared queries on a high-end machine. None of the tests I ran back for this set of changes saw such a huge gap, but Alexander Lakhin and Andres Freund have found that this can be noticeable. Keeping the older performance would mean to do more inlining in the executor when using COERCE_SQL_SYNTAX for a function expression, similarly to what SQLValueFunction does. This requires more redesign work and there is little time until 16beta1 is released, so for now reverting the change is the best way forward, bringing back the previous performance. Bump catalog version. Reported-by: Alexander Lakhin Discussion: https://postgr.es/m/b32bed1b-0746-9b20-1472-4bdc9ca66d52@gmail.com
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r--src/backend/optimizer/path/costsize.c1
-rw-r--r--src/backend/optimizer/util/clauses.c39
2 files changed, 33 insertions, 7 deletions
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index 0a2562c149a..e60603df814 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -4606,6 +4606,7 @@ cost_qual_eval_walker(Node *node, cost_qual_eval_context *context)
}
}
else if (IsA(node, MinMaxExpr) ||
+ IsA(node, SQLValueFunction) ||
IsA(node, XmlExpr) ||
IsA(node, CoerceToDomain) ||
IsA(node, NextValueExpr))
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 11269fee3ed..7f453b04f8b 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -412,6 +412,12 @@ contain_mutable_functions_walker(Node *node, void *context)
/* Check all subnodes */
}
+ if (IsA(node, SQLValueFunction))
+ {
+ /* all variants of SQLValueFunction are stable */
+ return true;
+ }
+
if (IsA(node, NextValueExpr))
{
/* NextValueExpr is volatile */
@@ -560,8 +566,8 @@ contain_volatile_functions_walker(Node *node, void *context)
/*
* See notes in contain_mutable_functions_walker about why we treat
- * MinMaxExpr, XmlExpr, and CoerceToDomain as immutable. Hence, none of
- * them are of interest here.
+ * MinMaxExpr, XmlExpr, and CoerceToDomain as immutable, while
+ * SQLValueFunction is stable. Hence, none of them are of interest here.
*/
/* Recurse to check arguments */
@@ -606,9 +612,10 @@ contain_volatile_functions_not_nextval_walker(Node *node, void *context)
/*
* See notes in contain_mutable_functions_walker about why we treat
- * MinMaxExpr, XmlExpr, and CoerceToDomain as immutable. Hence, none of
- * them are of interest here. Also, since we're intentionally ignoring
- * nextval(), presumably we should ignore NextValueExpr.
+ * MinMaxExpr, XmlExpr, and CoerceToDomain as immutable, while
+ * SQLValueFunction is stable. Hence, none of them are of interest here.
+ * Also, since we're intentionally ignoring nextval(), presumably we
+ * should ignore NextValueExpr.
*/
/* Recurse to check arguments */
@@ -754,8 +761,8 @@ max_parallel_hazard_walker(Node *node, max_parallel_hazard_context *context)
* (Note: in principle that's wrong because a domain constraint could
* contain a parallel-unsafe function; but useful constraints probably
* never would have such, and assuming they do would cripple use of
- * parallel query in the presence of domain types.) NextValueExpr is
- * parallel-unsafe.
+ * parallel query in the presence of domain types.) SQLValueFunction
+ * should be safe in all cases. NextValueExpr is parallel-unsafe.
*/
if (IsA(node, CoerceToDomain))
{
@@ -1202,6 +1209,7 @@ contain_leaked_vars_walker(Node *node, void *context)
case T_CaseExpr:
case T_CaseTestExpr:
case T_RowExpr:
+ case T_SQLValueFunction:
case T_NullTest:
case T_BooleanTest:
case T_NextValueExpr:
@@ -3243,6 +3251,23 @@ eval_const_expressions_mutator(Node *node,
newcoalesce->location = coalesceexpr->location;
return (Node *) newcoalesce;
}
+ case T_SQLValueFunction:
+ {
+ /*
+ * All variants of SQLValueFunction are stable, so if we are
+ * estimating the expression's value, we should evaluate the
+ * current function value. Otherwise just copy.
+ */
+ SQLValueFunction *svf = (SQLValueFunction *) node;
+
+ if (context->estimate)
+ return (Node *) evaluate_expr((Expr *) svf,
+ svf->type,
+ svf->typmod,
+ InvalidOid);
+ else
+ return copyObject((Node *) svf);
+ }
case T_FieldSelect:
{
/*