fixes-for-enr-rte-review-v2.patch
application/octet-stream
Filename: fixes-for-enr-rte-review-v2.patch
Type: application/octet-stream
Part: 0
Patch
Format: unified
Series: patch v2
| File | + | − |
|---|---|---|
| src/backend/nodes/copyfuncs.c | 1 | 1 |
| src/backend/nodes/equalfuncs.c | 1 | 0 |
| src/backend/optimizer/path/costsize.c | 5 | 7 |
| src/backend/parser/parse_relation.c | 0 | 1 |
| src/include/nodes/parsenodes.h | 13 | 2 |
| src/test/regress/expected/plpgsql.out | 8 | 4 |
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 36bf1dc92bb..3b54e3d80ce 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -2303,10 +2303,10 @@ _copyRangeTblEntry(const RangeTblEntry *from)
COPY_STRING_FIELD(ctename);
COPY_SCALAR_FIELD(ctelevelsup);
COPY_SCALAR_FIELD(self_reference);
- COPY_STRING_FIELD(enrname);
COPY_NODE_FIELD(coltypes);
COPY_NODE_FIELD(coltypmods);
COPY_NODE_FIELD(colcollations);
+ COPY_STRING_FIELD(enrname);
COPY_NODE_FIELD(alias);
COPY_NODE_FIELD(eref);
COPY_SCALAR_FIELD(lateral);
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 5bcf0317dc8..696cd6e7e1b 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -2631,6 +2631,7 @@ _equalRangeTblEntry(const RangeTblEntry *a, const RangeTblEntry *b)
COMPARE_NODE_FIELD(coltypes);
COMPARE_NODE_FIELD(coltypmods);
COMPARE_NODE_FIELD(colcollations);
+ COMPARE_STRING_FIELD(enrname);
COMPARE_NODE_FIELD(alias);
COMPARE_NODE_FIELD(eref);
COMPARE_SCALAR_FIELD(lateral);
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index f062c6b9f1e..781cdf8ff99 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -4777,14 +4777,12 @@ set_namedtuplestore_size_estimates(PlannerInfo *root, RelOptInfo *rel)
Assert(rte->rtekind == RTE_NAMEDTUPLESTORE);
/*
- * Use the estimate provided by the code which is generating the named
- * tuplestore. In some cases, the actual number might be available; in
- * others the same plan will be re-used, so a "typical" value might be
- * estimated and used.
+ * XXX We could use the estimate provided by the code which is generating
+ * the named tuplestore in EphemeralNamedRelationMetadataData member
+ * 'enrtuples'. We don't have access to QueryEnvironment to look it up
+ * from here yet, so for now we'll use a bogus default estimate.
*/
- rel->tuples = rte->enrtuples;
- if (rel->tuples < 0)
- rel->tuples = 1000;
+ rel->tuples = 1000;
/* Now estimate number of output rows, etc */
set_baserel_size_estimates(root, rel);
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c
index e412d0f9d30..f99e547745c 100644
--- a/src/backend/parser/parse_relation.c
+++ b/src/backend/parser/parse_relation.c
@@ -2020,7 +2020,6 @@ addRangeTableEntryForENR(ParseState *pstate,
rte->eref = makeAlias(refname, NIL);
buildRelationAliases(tupdesc, alias, rte->eref);
rte->enrname = enrmd->name;
- rte->enrtuples = enrmd->enrtuples;
rte->coltypes = NIL;
rte->coltypmods = NIL;
rte->colcollations = NIL;
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 2d2e2c0fbc1..8be5c3a9c09 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -944,6 +944,11 @@ typedef struct RangeTblEntry
/*
* Fields valid for a plain relation RTE (else zero):
+ *
+ * As a special case, RTE_NAMEDTUPLESTORE can also set relid to indicate
+ * that the tuple format of the tuplestore is the same as the referenced
+ * relation. This allows plans referencing AFTER trigger transition
+ * tables to be invalidated if the underlying table is altered.
*/
Oid relid; /* OID of the relation */
char relkind; /* relation kind (see pg_class.relkind) */
@@ -1004,18 +1009,24 @@ typedef struct RangeTblEntry
bool self_reference; /* is this a recursive self-reference? */
/*
- * Fields valid for values and CTE RTEs (else NIL):
+ * Fields valid for table functions, values, CTE and ENR RTEs (else NIL):
*
* We need these for CTE RTEs so that the types of self-referential
* columns are well-defined. For VALUES RTEs, storing these explicitly
* saves having to re-determine the info by scanning the values_lists.
+ * For ENRs, we store the types explicitly here (we could get the
+ * information from the catalogs if 'relid' was supplied, but we'd still
+ * need these for TupleDesc-based ENRs, so we might as well always store
+ * the type info here).
*/
List *coltypes; /* OID list of column type OIDs */
List *coltypmods; /* integer list of column typmods */
List *colcollations; /* OID list of column collation OIDs */
+ /*
+ * Fields valid for ENR RTEs (else NULL/zero):
+ */
char *enrname; /* name of ephemeral named relation */
- double enrtuples; /* estimated or actual from caller */
/*
* Fields valid in all RTEs:
diff --git a/src/test/regress/expected/plpgsql.out b/src/test/regress/expected/plpgsql.out
index 7ebbde60d30..66a9c9fc0c8 100644
--- a/src/test/regress/expected/plpgsql.out
+++ b/src/test/regress/expected/plpgsql.out
@@ -5757,13 +5757,17 @@ CREATE TRIGGER transition_table_base_upd_trig
UPDATE transition_table_base
SET val = '*' || val || '*'
WHERE id BETWEEN 2 AND 3;
-INFO: Hash Full Join
+INFO: Merge Full Join
Output: COALESCE(ot.id, nt.id), ot.val, nt.val
- Hash Cond: (ot.id = nt.id)
- -> Named Tuplestore Scan
+ Merge Cond: (ot.id = nt.id)
+ -> Sort
Output: ot.id, ot.val
- -> Hash
+ Sort Key: ot.id
+ -> Named Tuplestore Scan
+ Output: ot.id, ot.val
+ -> Sort
Output: nt.id, nt.val
+ Sort Key: nt.id
-> Named Tuplestore Scan
Output: nt.id, nt.val