Re: "could not find pathkey item to sort" for TPC-DS queries 94-96 - Mailing list pgsql-hackers
| From | ilmari@ilmari.org (Dagfinn Ilmari Mannsåker) |
|---|---|
| Subject | Re: "could not find pathkey item to sort" for TPC-DS queries 94-96 |
| Date | |
| Msg-id | 87im4hnrbw.fsf@wibble.ilmari.org Whole thread Raw |
| In response to | Re: "could not find pathkey item to sort" for TPC-DS queries 94-96 (ilmari@ilmari.org (Dagfinn Ilmari Mannsåker)) |
| Responses |
Re: "could not find pathkey item to sort" for TPC-DS queries 94-96
Re: "could not find pathkey item to sort" for TPC-DS queries 94-96 |
| List | pgsql-hackers |
ilmari@ilmari.org (Dagfinn Ilmari Mannsåker) writes:
> Tom Lane <tgl@sss.pgh.pa.us> writes:
>
>> + /* We ignore binary-compatible relabeling on both ends */
>> + while (expr && IsA(expr, RelabelType))
>> + expr = ((RelabelType *) expr)->arg;
>
> There are 10 instances of this exact loop scattered around the codebase.
> Is it worth it turning it into a static inline function?
Something like the attached, maybe?
- ilmari
--
"A disappointingly low fraction of the human race is,
at any given time, on fire." - Stig Sandbeck Mathisen
From b481a41e494f169765ee204aa17ba60c16950455 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dagfinn=20Ilmari=20Manns=C3=A5ker?= <ilmari@ilmari.org>
Date: Tue, 20 Apr 2021 12:08:46 +0100
Subject: [PATCH] Create a function for stripping RelabelType nodes off an
expression
The exact same while loop was repeated 10 times across the codebase,
which makes it smell like time to refactor.
---
contrib/postgres_fdw/postgres_fdw.c | 7 ++-----
src/backend/nodes/nodeFuncs.c | 3 +--
src/backend/optimizer/path/equivclass.c | 4 +---
src/backend/optimizer/plan/createplan.c | 8 ++------
src/backend/optimizer/plan/initsplan.c | 12 +++++-------
src/backend/optimizer/util/tlist.c | 8 ++------
src/include/nodes/nodeFuncs.h | 9 +++++++++
7 files changed, 22 insertions(+), 29 deletions(-)
diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c
index c590f374c6..5c45b2b087 100644
--- a/contrib/postgres_fdw/postgres_fdw.c
+++ b/contrib/postgres_fdw/postgres_fdw.c
@@ -7203,8 +7203,7 @@ find_em_expr_for_input_target(PlannerInfo *root,
}
/* We ignore binary-compatible relabeling on both ends */
- while (expr && IsA(expr, RelabelType))
- expr = ((RelabelType *) expr)->arg;
+ expr = (Expr *) strip_relabeltype(expr);
/* Locate an EquivalenceClass member matching this expr, if any */
foreach(lc2, ec->ec_members)
@@ -7221,9 +7220,7 @@ find_em_expr_for_input_target(PlannerInfo *root,
continue;
/* Match if same expression (after stripping relabel) */
- em_expr = em->em_expr;
- while (em_expr && IsA(em_expr, RelabelType))
- em_expr = ((RelabelType *) em_expr)->arg;
+ em_expr = (Expr *) strip_relabeltype(em->em_expr);
if (equal(em_expr, expr))
return em->em_expr;
diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c
index ff3dcc7b18..9918a4c12e 100644
--- a/src/backend/nodes/nodeFuncs.c
+++ b/src/backend/nodes/nodeFuncs.c
@@ -587,8 +587,7 @@ applyRelabelType(Node *arg, Oid rtype, int32 rtypmod, Oid rcollid,
* all but the top one, and must do so to ensure that semantically
* equivalent expressions are equal().
*/
- while (arg && IsA(arg, RelabelType))
- arg = (Node *) ((RelabelType *) arg)->arg;
+ arg = strip_relabeltype(arg);
if (arg && IsA(arg, Const))
{
diff --git a/src/backend/optimizer/path/equivclass.c b/src/backend/optimizer/path/equivclass.c
index 0188c1e9a1..2f78998a82 100644
--- a/src/backend/optimizer/path/equivclass.c
+++ b/src/backend/optimizer/path/equivclass.c
@@ -2307,9 +2307,7 @@ match_eclasses_to_foreign_key_col(PlannerInfo *root,
continue; /* ignore children here */
/* EM must be a Var, possibly with RelabelType */
- var = (Var *) em->em_expr;
- while (var && IsA(var, RelabelType))
- var = (Var *) ((RelabelType *) var)->arg;
+ var = (Var *) strip_relabeltype(em->em_expr);
if (!(var && IsA(var, Var)))
continue;
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 22f10fa339..b13aa65244 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -6257,9 +6257,7 @@ find_ec_member_for_tle(EquivalenceClass *ec,
ListCell *lc;
/* We ignore binary-compatible relabeling on both ends */
- tlexpr = tle->expr;
- while (tlexpr && IsA(tlexpr, RelabelType))
- tlexpr = ((RelabelType *) tlexpr)->arg;
+ tlexpr = (Expr *) strip_relabeltype(tle->expr);
foreach(lc, ec->ec_members)
{
@@ -6281,9 +6279,7 @@ find_ec_member_for_tle(EquivalenceClass *ec,
continue;
/* Match if same expression (after stripping relabel) */
- emexpr = em->em_expr;
- while (emexpr && IsA(emexpr, RelabelType))
- emexpr = ((RelabelType *) emexpr)->arg;
+ emexpr = (Expr *) strip_relabeltype(em->em_expr);
if (equal(emexpr, tlexpr))
return em;
diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c
index 3ac853d9ef..84805906e4 100644
--- a/src/backend/optimizer/plan/initsplan.c
+++ b/src/backend/optimizer/plan/initsplan.c
@@ -2566,16 +2566,14 @@ match_foreign_keys_to_quals(PlannerInfo *root)
if (!IsA(clause, OpExpr) ||
list_length(clause->args) != 2)
continue;
- leftvar = (Var *) get_leftop((Expr *) clause);
- rightvar = (Var *) get_rightop((Expr *) clause);
- /* Operands must be Vars, possibly with RelabelType */
- while (leftvar && IsA(leftvar, RelabelType))
- leftvar = (Var *) ((RelabelType *) leftvar)->arg;
+ /* Type relabeling doesn't matter */
+ leftvar = (Var *) strip_relabeltype(get_leftop((Expr *) clause));
+ rightvar = (Var *) strip_relabeltype(get_rightop((Expr *) clause));
+
+ /* Operands must be Vars */
if (!(leftvar && IsA(leftvar, Var)))
continue;
- while (rightvar && IsA(rightvar, RelabelType))
- rightvar = (Var *) ((RelabelType *) rightvar)->arg;
if (!(rightvar && IsA(rightvar, Var)))
continue;
diff --git a/src/backend/optimizer/util/tlist.c b/src/backend/optimizer/util/tlist.c
index 8a26288070..6ea3e1da03 100644
--- a/src/backend/optimizer/util/tlist.c
+++ b/src/backend/optimizer/util/tlist.c
@@ -90,16 +90,12 @@ tlist_member_ignore_relabel(Expr *node, List *targetlist)
{
ListCell *temp;
- while (node && IsA(node, RelabelType))
- node = ((RelabelType *) node)->arg;
+ node = (Expr *) strip_relabeltype(node);
foreach(temp, targetlist)
{
TargetEntry *tlentry = (TargetEntry *) lfirst(temp);
- Expr *tlexpr = tlentry->expr;
-
- while (tlexpr && IsA(tlexpr, RelabelType))
- tlexpr = ((RelabelType *) tlexpr)->arg;
+ Expr *tlexpr = (Expr *) strip_relabeltype(tlentry->expr);
if (equal(node, tlexpr))
return tlentry;
diff --git a/src/include/nodes/nodeFuncs.h b/src/include/nodes/nodeFuncs.h
index 03a346c01d..b11649d283 100644
--- a/src/include/nodes/nodeFuncs.h
+++ b/src/include/nodes/nodeFuncs.h
@@ -126,6 +126,15 @@ get_notclausearg(const void *notclause)
return (Expr *) linitial(((const BoolExpr *) notclause)->args);
}
+/* Strip off any RelabelType nodes */
+static inline Node *
+strip_relabeltype(const void *node)
+{
+ while (node && IsA(node, RelabelType))
+ node = ((RelabelType *) node)->arg;
+ return (Node *) node;
+}
+
extern bool check_functions_in_node(Node *node, check_function_callback checker,
void *context);
--
2.29.2
pgsql-hackers by date: