diff --git a/src/backend/optimizer/util/appendinfo.c b/src/backend/optimizer/util/appendinfo.c index 38f51b6607..5c3d5a736b 100644 --- a/src/backend/optimizer/util/appendinfo.c +++ b/src/backend/optimizer/util/appendinfo.c @@ -21,6 +21,7 @@ #include "nodes/nodeFuncs.h" #include "optimizer/appendinfo.h" #include "optimizer/pathnode.h" +#include "optimizer/planmain.h" #include "parser/parsetree.h" #include "utils/lsyscache.h" #include "utils/rel.h" @@ -968,9 +969,10 @@ distribute_row_identity_vars(PlannerInfo *root) * certainly process no rows. Handle this edge case by re-opening the top * result relation and adding the row identity columns it would have used, * as preprocess_targetlist() would have done if it weren't marked "inh". - * (This is a bit ugly, but it seems better to confine the ugliness and - * extra cycles to this unusual corner case.) We needn't worry about - * fixing the rel's reltarget, as that won't affect the finished plan. + * Then re-run build_base_rel_tlists() to ensure that the added columns + * get propagated to the relation's reltarget. (This is a bit ugly, but + * it seems better to confine the ugliness and extra cycles to this + * unusual corner case.) */ if (root->row_identity_vars == NIL) { @@ -980,6 +982,8 @@ distribute_row_identity_vars(PlannerInfo *root) add_row_identity_columns(root, result_relation, target_rte, target_relation); table_close(target_relation, NoLock); + build_base_rel_tlists(root, root->processed_tlist); + /* There are no ROWID_VAR Vars in this case, so we're done. */ return; } diff --git a/src/test/regress/expected/merge.out b/src/test/regress/expected/merge.out index 81c6d97d75..4da7b7845a 100644 --- a/src/test/regress/expected/merge.out +++ b/src/test/regress/expected/merge.out @@ -1846,6 +1846,31 @@ TABLE pa_target; 2 (2 rows) +-- Partition-less partitioned table +-- (the bug we are checking for appeared only if table had partitions before) +DROP TABLE pa_targetp; +EXPLAIN (VERBOSE, COSTS OFF) +MERGE INTO pa_target t USING pa_source s ON t.tid = s.sid + WHEN NOT MATCHED THEN INSERT VALUES (s.sid); + QUERY PLAN +-------------------------------------------- + Merge on public.pa_target t + -> Hash Left Join + Output: s.sid, t.ctid + Hash Cond: (s.sid = t.tid) + -> Seq Scan on public.pa_source s + Output: s.sid + -> Hash + Output: t.tid, t.ctid + -> Result + Output: t.tid, t.ctid + One-Time Filter: false +(11 rows) + +MERGE INTO pa_target t USING pa_source s ON t.tid = s.sid + WHEN NOT MATCHED THEN INSERT VALUES (s.sid); +ERROR: no partition of relation "pa_target" found for row +DETAIL: Partition key of the failing row contains (tid) = (1). DROP TABLE pa_source; DROP TABLE pa_target CASCADE; -- some complex joins on the source side diff --git a/src/test/regress/sql/merge.sql b/src/test/regress/sql/merge.sql index 29a35486d0..4cf6db908b 100644 --- a/src/test/regress/sql/merge.sql +++ b/src/test/regress/sql/merge.sql @@ -1169,6 +1169,18 @@ MERGE INTO pa_target t USING pa_source s ON t.tid = s.sid TABLE pa_target; +-- Partition-less partitioned table +-- (the bug we are checking for appeared only if table had partitions before) + +DROP TABLE pa_targetp; + +EXPLAIN (VERBOSE, COSTS OFF) +MERGE INTO pa_target t USING pa_source s ON t.tid = s.sid + WHEN NOT MATCHED THEN INSERT VALUES (s.sid); + +MERGE INTO pa_target t USING pa_source s ON t.tid = s.sid + WHEN NOT MATCHED THEN INSERT VALUES (s.sid); + DROP TABLE pa_source; DROP TABLE pa_target CASCADE;