0001-Examine-simple-variable-for-Var-in-CTE.patch
text/x-patch
Filename: 0001-Examine-simple-variable-for-Var-in-CTE.patch
Type: text/x-patch
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch 0001
Subject: Examine simple variable for Var in CTE.
| File | + | − |
|---|---|---|
| src/backend/utils/adt/selfuncs.c | 34 | 3 |
From 0ade8f4e9a0741fa4f1a6998abf2488c5b846aa7 Mon Sep 17 00:00:00 2001
From: Jian Guo <gjian@vmware.com>
Date: Mon, 21 Aug 2023 16:07:41 +0800
Subject: [PATCH] Examine simple variable for Var in CTE.
Signed-off-by: Jian Guo <gjian@vmware.com>
---
src/backend/utils/adt/selfuncs.c | 37 +++++++++++++++++++++++++++++---
1 file changed, 34 insertions(+), 3 deletions(-)
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index c4fcd0076e..bcf0fb4e16 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -5598,13 +5598,43 @@ examine_simple_variable(PlannerInfo *root, Var *var,
examine_simple_variable(rel->subroot, var, vardata);
}
}
+ else if (rte->rtekind == RTE_CTE && !rte->inh)
+ {
+ /*
+ * Punt if it's a whole-row var rather than a plain column reference.
+ */
+ if (var->varattno == InvalidAttrNumber)
+ return;
+ /*
+ * OK, fetch RelOptInfo for subquery.
+ */
+ RelOptInfo *rel = find_base_rel(root, var->varno);
+ /* Can only handle a simple Var of subquery's query level */
+ if (var && IsA(var, Var) &&
+ var->varlevelsup == 0)
+ {
+ /*
+ * OK, recurse into the subquery. Note that the original setting
+ * of vardata->isunique (which will surely be false) is left
+ * unchanged in this situation. That's what we want, since even
+ * if the underlying column is unique, the subquery may have
+ * joined to other tables in a way that creates duplicates.
+ */
+ Index varnoSaved = var->varno;
+ /* Mock a fake index for CTE */
+ var->varno = 1;
+ if (rel->subroot)
+ examine_simple_variable(rel->subroot, var, vardata);
+ var->varno = varnoSaved;
+ }
+ }
else
{
/*
- * Otherwise, the Var comes from a FUNCTION, VALUES, or CTE RTE. (We
+ * Otherwise, the Var comes from a FUNCTION, VALUES. (We
* won't see RTE_JOIN here because join alias Vars have already been
* flattened.) There's not much we can do with function outputs, but
- * maybe someday try to be smarter about VALUES and/or CTEs.
+ * maybe someday try to be smarter about VALUES.
*/
}
}
@@ -5866,7 +5896,8 @@ get_variable_range(PlannerInfo *root, VariableStatData *vardata,
* data. Proceed only if the MCVs represent the whole table (to within
* roundoff error).
*/
- if (get_attstatsslot(&sslot, vardata->statsTuple,
+ bool has_mcv = (!vardata->rel || vardata->rel->rtekind != RTE_CTE);
+ if (has_mcv && get_attstatsslot(&sslot, vardata->statsTuple,
STATISTIC_KIND_MCV, InvalidOid,
have_data ? ATTSTATSSLOT_VALUES :
(ATTSTATSSLOT_VALUES | ATTSTATSSLOT_NUMBERS)))
--
2.41.0