Skip to content

Commit

Permalink
Add tableoid junk column to processed_tlist only for top-level parent.
Browse files Browse the repository at this point in the history
(Note that the column is added to RelOptInfo reltarget of all nodes in the
hierarchy anyway; but only tle with top-level varno must get to *main* tlist,
i.e. processed_tlist.)

Previously it was added for each parent in the tree, i.e. multiple times in case
of multi-level partitioning, leading to

ERROR: variable not found in subplan target lists

errors in setref.

As comments say, this code better be rewritten to actually let parent deal with
its isParent flag. And to recurce with toplever rc. Probably should be done if
adjacent bugs arise.
  • Loading branch information
arssher committed Jun 2, 2019
1 parent 2a13ed7 commit ba30201
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 4 deletions.
33 changes: 33 additions & 0 deletions expected/pathman_subpartitions.out
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,39 @@ UPDATE subpartitions.abc SET id1 = -1, id2 = -1 RETURNING tableoid::regclass, *;

DROP TABLE subpartitions.abc CASCADE;
NOTICE: drop cascades to 9 other objects
--- basic check how rowmark plays along with subparts; PGPRO-2755
CREATE TABLE subpartitions.a1(n1 integer);
CREATE TABLE subpartitions.a2(n1 integer not null, n2 integer not null);
SELECT create_range_partitions('subpartitions.a2', 'n1', 1, 2, 0);
create_range_partitions
-------------------------
0
(1 row)

SELECT add_range_partition('subpartitions.a2', 10, 20, 'subpartitions.a2_1020');
add_range_partition
-----------------------
subpartitions.a2_1020
(1 row)

SELECT create_range_partitions('subpartitions.a2_1020'::regclass, 'n2'::text, array[30,40], array['subpartitions.a2_1020_3040']);
create_range_partitions
-------------------------
1
(1 row)

INSERT INTO subpartitions.a2 VALUES (10, 30), (11, 31), (12, 32), (19, 39);
INSERT INTO subpartitions.a1 VALUES (12), (19), (20);
SELECT a2.* FROM subpartitions.a1 JOIN subpartitions.a2 ON a2.n1=a1.n1 FOR UPDATE;
n1 | n2
----+----
12 | 32
19 | 39
(2 rows)

DROP TABLE subpartitions.a2 CASCADE;
NOTICE: drop cascades to 4 other objects
DROP TABLE subpartitions.a1;
DROP SCHEMA subpartitions CASCADE;
NOTICE: drop cascades to function subpartitions.partitions_tree(regclass,text)
DROP EXTENSION pg_pathman;
18 changes: 17 additions & 1 deletion sql/pathman_subpartitions.sql
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,24 @@ SELECT tableoid::regclass, * FROM subpartitions.abc ORDER BY id1, id2, val;
SET pg_pathman.enable_partitionrouter = ON;
UPDATE subpartitions.abc SET id1 = -1, id2 = -1 RETURNING tableoid::regclass, *;

DROP TABLE subpartitions.abc CASCADE;


--- basic check how rowmark plays along with subparts; PGPRO-2755
CREATE TABLE subpartitions.a1(n1 integer);
CREATE TABLE subpartitions.a2(n1 integer not null, n2 integer not null);
SELECT create_range_partitions('subpartitions.a2', 'n1', 1, 2, 0);

SELECT add_range_partition('subpartitions.a2', 10, 20, 'subpartitions.a2_1020');
SELECT create_range_partitions('subpartitions.a2_1020'::regclass, 'n2'::text, array[30,40], array['subpartitions.a2_1020_3040']);
INSERT INTO subpartitions.a2 VALUES (10, 30), (11, 31), (12, 32), (19, 39);
INSERT INTO subpartitions.a1 VALUES (12), (19), (20);

SELECT a2.* FROM subpartitions.a1 JOIN subpartitions.a2 ON a2.n1=a1.n1 FOR UPDATE;

DROP TABLE subpartitions.a2 CASCADE;
DROP TABLE subpartitions.a1;


DROP TABLE subpartitions.abc CASCADE;
DROP SCHEMA subpartitions CASCADE;
DROP EXTENSION pg_pathman;
6 changes: 4 additions & 2 deletions src/include/rangeset.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/* ------------------------------------------------------------------------
*
* rangeset.h
* IndexRange functions
*
* Copyright (c) 2015-2016, Postgres Professional
*
Expand All @@ -17,7 +16,10 @@


/*
* IndexRange contains a set of selected partitions.
* IndexRange is essentially a segment [lower; upper]. This module provides
* functions for efficient working (intersection, union) with Lists of
* IndexRange's; this is used for quick selection of partitions. Numbers are
* indexes of partitions in PartRelationInfo's children.
*/
typedef struct {
/* lossy == should we use quals? */
Expand Down
17 changes: 16 additions & 1 deletion src/pg_pathman.c
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ append_child_relation(PlannerInfo *root,
Relation child_relation;
AppendRelInfo *appinfo;
Index child_rti;
PlanRowMark *child_rowmark;
PlanRowMark *child_rowmark = NULL;
Node *childqual;
List *childquals;
ListCell *lc1,
Expand Down Expand Up @@ -493,6 +493,10 @@ append_child_relation(PlannerInfo *root,


/* Create rowmarks required for child rels */
/*
* XXX: vanilla recurses down with *top* rowmark, not immediate parent one.
* Not sure about example where this matters though.
*/
if (parent_rowmark)
{
child_rowmark = makeNode(PlanRowMark);
Expand All @@ -511,6 +515,13 @@ append_child_relation(PlannerInfo *root,
root->rowMarks = lappend(root->rowMarks, child_rowmark);

/* Adjust tlist for RowMarks (see planner.c) */
/*
* XXX Saner approach seems to
* 1) Add tle to top parent and processed_tlist once in rel_pathlist_hook.
* 2) Mark isParent = true
* *parent* knows it is parent, after all; why should child bother?
* 3) Recursion (code executed in childs) starts at 2)
*/
if (!parent_rowmark->isParent && !root->parse->setOperations)
{
append_tle_for_rowmark(root, parent_rowmark);
Expand Down Expand Up @@ -636,6 +647,10 @@ append_child_relation(PlannerInfo *root,
if (parent_rte->relid != child_oid &&
child_relation->rd_rel->relhassubclass)
{
/* See XXX above */
if (child_rowmark)
child_rowmark->isParent = true;

pathman_rel_pathlist_hook(root,
child_rel,
child_rti,
Expand Down

0 comments on commit ba30201

Please sign in to comment.