Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 35ab52f

Browse files
committed
[PGPRO-9137] Fix for vanilla commits 178ee1d858, b1444a09dc
Tags: pg_pathman
1 parent 9e025db commit 35ab52f

File tree

3 files changed

+232
-1
lines changed

3 files changed

+232
-1
lines changed
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
\set VERBOSITY terse
2+
SET search_path = 'public';
3+
CREATE EXTENSION pg_pathman;
4+
CREATE SCHEMA test_update_triggers;
5+
create table test_update_triggers.test (val int not null);
6+
select create_hash_partitions('test_update_triggers.test', 'val', 2,
7+
partition_names := array[
8+
'test_update_triggers.test_1',
9+
'test_update_triggers.test_2']);
10+
create_hash_partitions
11+
------------------------
12+
2
13+
(1 row)
14+
15+
create or replace function test_update_triggers.test_trigger() returns trigger as $$
16+
begin
17+
raise notice '%', format('%s %s %s (%s)', TG_WHEN, TG_OP, TG_LEVEL, TG_TABLE_NAME);
18+
19+
if TG_OP::text = 'DELETE'::text then
20+
return old;
21+
else
22+
return new;
23+
end if; end;
24+
$$ language plpgsql;
25+
/* Enable our precious custom node */
26+
set pg_pathman.enable_partitionrouter = t;
27+
/*
28+
* Statement level triggers
29+
*/
30+
create trigger bus before update ON test_update_triggers.test
31+
execute procedure test_update_triggers.test_trigger ();
32+
create trigger bds before delete ON test_update_triggers.test
33+
execute procedure test_update_triggers.test_trigger ();
34+
create trigger bis before insert ON test_update_triggers.test
35+
execute procedure test_update_triggers.test_trigger ();
36+
create trigger aus after update ON test_update_triggers.test
37+
execute procedure test_update_triggers.test_trigger ();
38+
create trigger ads after delete ON test_update_triggers.test
39+
execute procedure test_update_triggers.test_trigger ();
40+
create trigger ais after insert ON test_update_triggers.test
41+
execute procedure test_update_triggers.test_trigger ();
42+
create trigger bus before update ON test_update_triggers.test_1
43+
execute procedure test_update_triggers.test_trigger ();
44+
create trigger bds before delete ON test_update_triggers.test_1
45+
execute procedure test_update_triggers.test_trigger ();
46+
create trigger bis before insert ON test_update_triggers.test_1
47+
execute procedure test_update_triggers.test_trigger ();
48+
create trigger aus after update ON test_update_triggers.test_1
49+
execute procedure test_update_triggers.test_trigger ();
50+
create trigger ads after delete ON test_update_triggers.test_1
51+
execute procedure test_update_triggers.test_trigger ();
52+
create trigger ais after insert ON test_update_triggers.test_1
53+
execute procedure test_update_triggers.test_trigger ();
54+
create trigger bus before update ON test_update_triggers.test_2
55+
execute procedure test_update_triggers.test_trigger ();
56+
create trigger bds before delete ON test_update_triggers.test_2
57+
execute procedure test_update_triggers.test_trigger ();
58+
create trigger bis before insert ON test_update_triggers.test_2
59+
execute procedure test_update_triggers.test_trigger ();
60+
create trigger aus after update ON test_update_triggers.test_2
61+
execute procedure test_update_triggers.test_trigger ();
62+
create trigger ads after delete ON test_update_triggers.test_2
63+
execute procedure test_update_triggers.test_trigger ();
64+
create trigger ais after insert ON test_update_triggers.test_2
65+
execute procedure test_update_triggers.test_trigger ();
66+
/* multiple values */
67+
insert into test_update_triggers.test select generate_series(1, 200);
68+
NOTICE: BEFORE INSERT STATEMENT (test)
69+
NOTICE: AFTER INSERT STATEMENT (test)
70+
update test_update_triggers.test set val = val + 1;
71+
NOTICE: BEFORE UPDATE STATEMENT (test)
72+
NOTICE: AFTER INSERT STATEMENT (test)
73+
NOTICE: AFTER UPDATE STATEMENT (test)
74+
update test_update_triggers.test set val = val + 1;
75+
NOTICE: BEFORE UPDATE STATEMENT (test)
76+
NOTICE: AFTER INSERT STATEMENT (test)
77+
NOTICE: AFTER UPDATE STATEMENT (test)
78+
update test_update_triggers.test set val = val + 1;
79+
NOTICE: BEFORE UPDATE STATEMENT (test)
80+
NOTICE: AFTER INSERT STATEMENT (test)
81+
NOTICE: AFTER UPDATE STATEMENT (test)
82+
update test_update_triggers.test set val = val + 1;
83+
NOTICE: BEFORE UPDATE STATEMENT (test)
84+
NOTICE: AFTER INSERT STATEMENT (test)
85+
NOTICE: AFTER UPDATE STATEMENT (test)
86+
update test_update_triggers.test set val = val + 1;
87+
NOTICE: BEFORE UPDATE STATEMENT (test)
88+
NOTICE: AFTER INSERT STATEMENT (test)
89+
NOTICE: AFTER UPDATE STATEMENT (test)
90+
select count(distinct val) from test_update_triggers.test;
91+
count
92+
-------
93+
200
94+
(1 row)
95+
96+
truncate test_update_triggers.test;
97+
/*
98+
* Row level triggers
99+
*/
100+
create trigger bu before update ON test_update_triggers.test_1
101+
for each row execute procedure test_update_triggers.test_trigger ();
102+
create trigger bd before delete ON test_update_triggers.test_1
103+
for each row execute procedure test_update_triggers.test_trigger ();
104+
create trigger bi before insert ON test_update_triggers.test_1
105+
for each row execute procedure test_update_triggers.test_trigger ();
106+
create trigger au after update ON test_update_triggers.test_1
107+
for each row execute procedure test_update_triggers.test_trigger ();
108+
create trigger ad after delete ON test_update_triggers.test_1
109+
for each row execute procedure test_update_triggers.test_trigger ();
110+
create trigger ai after insert ON test_update_triggers.test_1
111+
for each row execute procedure test_update_triggers.test_trigger ();
112+
create trigger bu before update ON test_update_triggers.test_2
113+
for each row execute procedure test_update_triggers.test_trigger ();
114+
create trigger bd before delete ON test_update_triggers.test_2
115+
for each row execute procedure test_update_triggers.test_trigger ();
116+
create trigger bi before insert ON test_update_triggers.test_2
117+
for each row execute procedure test_update_triggers.test_trigger ();
118+
create trigger au after update ON test_update_triggers.test_2
119+
for each row execute procedure test_update_triggers.test_trigger ();
120+
create trigger ad after delete ON test_update_triggers.test_2
121+
for each row execute procedure test_update_triggers.test_trigger ();
122+
create trigger ai after insert ON test_update_triggers.test_2
123+
for each row execute procedure test_update_triggers.test_trigger ();
124+
/* single value */
125+
insert into test_update_triggers.test values (1);
126+
NOTICE: BEFORE INSERT STATEMENT (test)
127+
NOTICE: BEFORE INSERT ROW (test_1)
128+
NOTICE: AFTER INSERT ROW (test_1)
129+
NOTICE: AFTER INSERT STATEMENT (test)
130+
update test_update_triggers.test set val = val + 1 returning *, tableoid::regclass;
131+
NOTICE: BEFORE UPDATE STATEMENT (test)
132+
NOTICE: BEFORE UPDATE ROW (test_1)
133+
NOTICE: AFTER UPDATE ROW (test_1)
134+
NOTICE: AFTER UPDATE STATEMENT (test)
135+
val | tableoid
136+
-----+-----------------------------
137+
2 | test_update_triggers.test_1
138+
(1 row)
139+
140+
update test_update_triggers.test set val = val + 1 returning *, tableoid::regclass;
141+
NOTICE: BEFORE UPDATE STATEMENT (test)
142+
NOTICE: BEFORE UPDATE ROW (test_1)
143+
NOTICE: BEFORE DELETE ROW (test_1)
144+
NOTICE: BEFORE INSERT ROW (test_2)
145+
NOTICE: AFTER DELETE ROW (test_1)
146+
NOTICE: AFTER INSERT STATEMENT (test)
147+
NOTICE: AFTER INSERT ROW (test_2)
148+
NOTICE: AFTER UPDATE STATEMENT (test)
149+
val | tableoid
150+
-----+-----------------------------
151+
3 | test_update_triggers.test_2
152+
(1 row)
153+
154+
update test_update_triggers.test set val = val + 1 returning *, tableoid::regclass;
155+
NOTICE: BEFORE UPDATE STATEMENT (test)
156+
NOTICE: BEFORE UPDATE ROW (test_2)
157+
NOTICE: AFTER UPDATE ROW (test_2)
158+
NOTICE: AFTER UPDATE STATEMENT (test)
159+
val | tableoid
160+
-----+-----------------------------
161+
4 | test_update_triggers.test_2
162+
(1 row)
163+
164+
update test_update_triggers.test set val = val + 1 returning *, tableoid::regclass;
165+
NOTICE: BEFORE UPDATE STATEMENT (test)
166+
NOTICE: BEFORE UPDATE ROW (test_2)
167+
NOTICE: BEFORE DELETE ROW (test_2)
168+
NOTICE: BEFORE INSERT ROW (test_1)
169+
NOTICE: AFTER DELETE ROW (test_2)
170+
NOTICE: AFTER INSERT STATEMENT (test)
171+
NOTICE: AFTER INSERT ROW (test_1)
172+
NOTICE: AFTER UPDATE STATEMENT (test)
173+
val | tableoid
174+
-----+-----------------------------
175+
5 | test_update_triggers.test_1
176+
(1 row)
177+
178+
update test_update_triggers.test set val = val + 1 returning *, tableoid::regclass;
179+
NOTICE: BEFORE UPDATE STATEMENT (test)
180+
NOTICE: BEFORE UPDATE ROW (test_1)
181+
NOTICE: AFTER UPDATE ROW (test_1)
182+
NOTICE: AFTER UPDATE STATEMENT (test)
183+
val | tableoid
184+
-----+-----------------------------
185+
6 | test_update_triggers.test_1
186+
(1 row)
187+
188+
select count(distinct val) from test_update_triggers.test;
189+
count
190+
-------
191+
1
192+
(1 row)
193+
194+
DROP TABLE test_update_triggers.test CASCADE;
195+
NOTICE: drop cascades to 2 other objects
196+
DROP FUNCTION test_update_triggers.test_trigger();
197+
DROP SCHEMA test_update_triggers;
198+
DROP EXTENSION pg_pathman CASCADE;

src/include/partition_filter.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,11 @@ typedef struct
119119
CmdType command_type;
120120

121121
TupleTableSlot *tup_convert_slot; /* slot for rebuilt tuples */
122+
123+
#if PG_VERSION_NUM >= 160000 /* for commit 178ee1d858 */
124+
Index parent_rti; /* Parent RT index for use of EXPLAIN,
125+
see "ModifyTable::nominalRelation" */
126+
#endif
122127
} PartitionFilterState;
123128

124129

src/partition_filter.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -815,10 +815,18 @@ make_partition_filter(Plan *subplan,
815815
cscan->scan.plan.targetlist = pfilter_build_tlist(subplan, parent_rti);
816816

817817
/* Pack partitioned table's Oid and conflict_action */
818+
#if PG_VERSION_NUM >= 160000 /* for commit 178ee1d858 */
819+
cscan->custom_private = list_make5(makeInteger(parent_relid),
820+
makeInteger(conflict_action),
821+
returning_list,
822+
makeInteger(command_type),
823+
makeInteger(parent_rti));
824+
#else
818825
cscan->custom_private = list_make4(makeInteger(parent_relid),
819826
makeInteger(conflict_action),
820827
returning_list,
821828
makeInteger(command_type));
829+
#endif
822830

823831
return &cscan->scan.plan;
824832
}
@@ -841,6 +849,9 @@ partition_filter_create_scan_state(CustomScan *node)
841849
state->on_conflict_action = intVal(lsecond(node->custom_private));
842850
state->returning_list = (List *) lthird(node->custom_private);
843851
state->command_type = (CmdType) intVal(lfourth(node->custom_private));
852+
#if PG_VERSION_NUM >= 160000 /* for commit 178ee1d858 */
853+
state->parent_rti = (Index) intVal(lfirst(list_nth_cell(node->custom_private, 4)));
854+
#endif
844855

845856
/* Check boundaries */
846857
Assert(state->on_conflict_action >= ONCONFLICT_NONE ||
@@ -875,7 +886,24 @@ partition_filter_begin(CustomScanState *node, EState *estate, int eflags)
875886
RPS_RRI_CB(NULL, NULL));
876887
#if PG_VERSION_NUM >= 160000 /* for commit a61b1f74823c */
877888
/* ResultRelInfo of partitioned table. */
878-
state->result_parts.init_rri = current_rri;
889+
{
890+
RangeTblEntry *rte = rt_fetch(current_rri->ri_RangeTableIndex, estate->es_range_table);
891+
892+
if (rte->perminfoindex > 0)
893+
state->result_parts.init_rri = current_rri;
894+
else
895+
{
896+
/*
897+
* Additional changes for 178ee1d858d: we cannot use current_rri
898+
* because RTE for this ResultRelInfo has perminfoindex = 0. Need
899+
* to use parent_rti (modify_table->nominalRelation) instead.
900+
*/
901+
Assert(state->parent_rti > 0);
902+
state->result_parts.init_rri = estate->es_result_relations[state->parent_rti - 1];
903+
if (!state->result_parts.init_rri)
904+
elog(ERROR, "cannot determine result info for partitioned table");
905+
}
906+
}
879907
#endif
880908
}
881909

0 commit comments

Comments
 (0)