Skip to content

Commit c4c0e34

Browse files
committed
[PGPRO-7928] Variable pg_pathman.enable must be called before any query
Tags: pg_pathman
1 parent f0c81f5 commit c4c0e34

File tree

6 files changed

+123
-18
lines changed

6 files changed

+123
-18
lines changed

expected/pathman_runtime_nodes.out

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ begin
5858
return 'ok';
5959
end;
6060
$$ language plpgsql
61-
set pg_pathman.enable = true
6261
set enable_mergejoin = off
6362
set enable_hashjoin = off;
6463
create or replace function test.pathman_test_2() returns text as $$
@@ -100,7 +99,6 @@ begin
10099
return 'ok';
101100
end;
102101
$$ language plpgsql
103-
set pg_pathman.enable = true
104102
set enable_mergejoin = off
105103
set enable_hashjoin = off;
106104
create or replace function test.pathman_test_3() returns text as $$
@@ -133,7 +131,6 @@ begin
133131
return 'ok';
134132
end;
135133
$$ language plpgsql
136-
set pg_pathman.enable = true
137134
set enable_mergejoin = off
138135
set enable_hashjoin = off;
139136
create or replace function test.pathman_test_4() returns text as $$
@@ -172,7 +169,6 @@ begin
172169
return 'ok';
173170
end;
174171
$$ language plpgsql
175-
set pg_pathman.enable = true
176172
set enable_mergejoin = off
177173
set enable_hashjoin = off;
178174
create or replace function test.pathman_test_5() returns text as $$
@@ -233,7 +229,6 @@ begin
233229
return 'ok';
234230
end;
235231
$$ language plpgsql
236-
set pg_pathman.enable = true
237232
set enable_hashjoin = off
238233
set enable_mergejoin = off;
239234
create table test.run_values as select generate_series(1, 10000) val;
@@ -464,5 +459,41 @@ DROP FUNCTION test.pathman_test_3();
464459
DROP FUNCTION test.pathman_test_4();
465460
DROP FUNCTION test.pathman_test_5();
466461
DROP SCHEMA test;
462+
--
463+
--
464+
-- PGPRO-7928
465+
-- Variable pg_pathman.enable must be called before any query.
466+
--
467+
CREATE TABLE part_test (val int NOT NULL);
468+
SELECT create_hash_partitions('part_test', 'val', 2, partition_names := array['part_test_1','pg_pathman']);
469+
ERROR: function create_hash_partitions(unknown, unknown, integer, partition_names => text[]) does not exist at character 8
470+
CREATE OR REPLACE FUNCTION part_test_trigger() RETURNS TRIGGER AS $$
471+
BEGIN
472+
RAISE NOTICE '%', format('%s %s %s (%s)', TG_WHEN, TG_OP, TG_LEVEL, TG_TABLE_NAME);
473+
IF TG_OP::text = 'DELETE'::text then
474+
SET pg_pathman.enable = f;
475+
RETURN new;
476+
END IF;
477+
END;
478+
$$ LANGUAGE PLPGSQL;
479+
SET pg_pathman.enable_partitionrouter = t;
480+
CREATE TRIGGER ad AFTER DELETE ON part_test_1 FOR EACH ROW EXECUTE PROCEDURE part_test_trigger ();
481+
ERROR: relation "part_test_1" does not exist
482+
INSERT INTO part_test VALUES (1);
483+
UPDATE part_test SET val = val + 1 RETURNING *, tableoid::regclass;
484+
val | tableoid
485+
-----+-----------
486+
2 | part_test
487+
(1 row)
488+
489+
UPDATE part_test SET val = val + 1 RETURNING *, tableoid::regclass;
490+
val | tableoid
491+
-----+-----------
492+
3 | part_test
493+
(1 row)
494+
495+
RESET pg_pathman.enable_partitionrouter;
496+
DROP TABLE part_test CASCADE;
497+
DROP FUNCTION part_test_trigger();
467498
DROP EXTENSION pg_pathman CASCADE;
468499
DROP SCHEMA pathman;

expected/pathman_runtime_nodes_1.out

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ begin
5858
return 'ok';
5959
end;
6060
$$ language plpgsql
61-
set pg_pathman.enable = true
6261
set enable_mergejoin = off
6362
set enable_hashjoin = off;
6463
create or replace function test.pathman_test_2() returns text as $$
@@ -100,7 +99,6 @@ begin
10099
return 'ok';
101100
end;
102101
$$ language plpgsql
103-
set pg_pathman.enable = true
104102
set enable_mergejoin = off
105103
set enable_hashjoin = off;
106104
create or replace function test.pathman_test_3() returns text as $$
@@ -133,7 +131,6 @@ begin
133131
return 'ok';
134132
end;
135133
$$ language plpgsql
136-
set pg_pathman.enable = true
137134
set enable_mergejoin = off
138135
set enable_hashjoin = off;
139136
create or replace function test.pathman_test_4() returns text as $$
@@ -172,7 +169,6 @@ begin
172169
return 'ok';
173170
end;
174171
$$ language plpgsql
175-
set pg_pathman.enable = true
176172
set enable_mergejoin = off
177173
set enable_hashjoin = off;
178174
create or replace function test.pathman_test_5() returns text as $$
@@ -233,7 +229,6 @@ begin
233229
return 'ok';
234230
end;
235231
$$ language plpgsql
236-
set pg_pathman.enable = true
237232
set enable_hashjoin = off
238233
set enable_mergejoin = off;
239234
create table test.run_values as select generate_series(1, 10000) val;
@@ -464,5 +459,41 @@ DROP FUNCTION test.pathman_test_3();
464459
DROP FUNCTION test.pathman_test_4();
465460
DROP FUNCTION test.pathman_test_5();
466461
DROP SCHEMA test;
462+
--
463+
--
464+
-- PGPRO-7928
465+
-- Variable pg_pathman.enable must be called before any query.
466+
--
467+
CREATE TABLE part_test (val int NOT NULL);
468+
SELECT create_hash_partitions('part_test', 'val', 2, partition_names := array['part_test_1','pg_pathman']);
469+
ERROR: function create_hash_partitions(unknown, unknown, integer, partition_names => text[]) does not exist at character 8
470+
CREATE OR REPLACE FUNCTION part_test_trigger() RETURNS TRIGGER AS $$
471+
BEGIN
472+
RAISE NOTICE '%', format('%s %s %s (%s)', TG_WHEN, TG_OP, TG_LEVEL, TG_TABLE_NAME);
473+
IF TG_OP::text = 'DELETE'::text then
474+
SET pg_pathman.enable = f;
475+
RETURN new;
476+
END IF;
477+
END;
478+
$$ LANGUAGE PLPGSQL;
479+
SET pg_pathman.enable_partitionrouter = t;
480+
CREATE TRIGGER ad AFTER DELETE ON part_test_1 FOR EACH ROW EXECUTE PROCEDURE part_test_trigger ();
481+
ERROR: relation "part_test_1" does not exist
482+
INSERT INTO part_test VALUES (1);
483+
UPDATE part_test SET val = val + 1 RETURNING *, tableoid::regclass;
484+
val | tableoid
485+
-----+-----------
486+
2 | part_test
487+
(1 row)
488+
489+
UPDATE part_test SET val = val + 1 RETURNING *, tableoid::regclass;
490+
val | tableoid
491+
-----+-----------
492+
3 | part_test
493+
(1 row)
494+
495+
RESET pg_pathman.enable_partitionrouter;
496+
DROP TABLE part_test CASCADE;
497+
DROP FUNCTION part_test_trigger();
467498
DROP EXTENSION pg_pathman CASCADE;
468499
DROP SCHEMA pathman;

sql/pathman_runtime_nodes.sql

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ begin
6363
return 'ok';
6464
end;
6565
$$ language plpgsql
66-
set pg_pathman.enable = true
6766
set enable_mergejoin = off
6867
set enable_hashjoin = off;
6968

@@ -106,7 +105,6 @@ begin
106105
return 'ok';
107106
end;
108107
$$ language plpgsql
109-
set pg_pathman.enable = true
110108
set enable_mergejoin = off
111109
set enable_hashjoin = off;
112110

@@ -140,7 +138,6 @@ begin
140138
return 'ok';
141139
end;
142140
$$ language plpgsql
143-
set pg_pathman.enable = true
144141
set enable_mergejoin = off
145142
set enable_hashjoin = off;
146143

@@ -180,7 +177,6 @@ begin
180177
return 'ok';
181178
end;
182179
$$ language plpgsql
183-
set pg_pathman.enable = true
184180
set enable_mergejoin = off
185181
set enable_hashjoin = off;
186182

@@ -242,7 +238,6 @@ begin
242238
return 'ok';
243239
end;
244240
$$ language plpgsql
245-
set pg_pathman.enable = true
246241
set enable_hashjoin = off
247242
set enable_mergejoin = off;
248243

@@ -347,6 +342,31 @@ DROP FUNCTION test.pathman_test_3();
347342
DROP FUNCTION test.pathman_test_4();
348343
DROP FUNCTION test.pathman_test_5();
349344
DROP SCHEMA test;
345+
--
346+
--
347+
-- PGPRO-7928
348+
-- Variable pg_pathman.enable must be called before any query.
349+
--
350+
CREATE TABLE part_test (val int NOT NULL);
351+
SELECT create_hash_partitions('part_test', 'val', 2, partition_names := array['part_test_1','pg_pathman']);
352+
CREATE OR REPLACE FUNCTION part_test_trigger() RETURNS TRIGGER AS $$
353+
BEGIN
354+
RAISE NOTICE '%', format('%s %s %s (%s)', TG_WHEN, TG_OP, TG_LEVEL, TG_TABLE_NAME);
355+
IF TG_OP::text = 'DELETE'::text then
356+
SET pg_pathman.enable = f;
357+
RETURN new;
358+
END IF;
359+
END;
360+
$$ LANGUAGE PLPGSQL;
361+
SET pg_pathman.enable_partitionrouter = t;
362+
CREATE TRIGGER ad AFTER DELETE ON part_test_1 FOR EACH ROW EXECUTE PROCEDURE part_test_trigger ();
363+
INSERT INTO part_test VALUES (1);
364+
UPDATE part_test SET val = val + 1 RETURNING *, tableoid::regclass;
365+
UPDATE part_test SET val = val + 1 RETURNING *, tableoid::regclass;
366+
367+
RESET pg_pathman.enable_partitionrouter;
368+
DROP TABLE part_test CASCADE;
369+
DROP FUNCTION part_test_trigger();
370+
350371
DROP EXTENSION pg_pathman CASCADE;
351372
DROP SCHEMA pathman;
352-

src/hooks.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,9 @@
3939
#include "optimizer/prep.h"
4040
#include "optimizer/restrictinfo.h"
4141
#include "rewrite/rewriteManip.h"
42-
#include "utils/typcache.h"
4342
#include "utils/lsyscache.h"
43+
#include "utils/typcache.h"
44+
#include "utils/snapmgr.h"
4445

4546

4647
#ifdef USE_ASSERT_CHECKING
@@ -614,6 +615,27 @@ pathman_rel_pathlist_hook(PlannerInfo *root,
614615
close_pathman_relation_info(prel);
615616
}
616617

618+
/*
619+
* 'pg_pathman.enable' GUC check.
620+
*/
621+
bool
622+
pathman_enable_check_hook(bool *newval, void **extra, GucSource source)
623+
{
624+
if (FirstSnapshotSet ||
625+
GetTopTransactionIdIfAny() != InvalidTransactionId ||
626+
#ifdef PGPRO_EE
627+
getNestLevelATX() > 0 ||
628+
#endif
629+
IsSubTransaction())
630+
{
631+
GUC_check_errcode(ERRCODE_ACTIVE_SQL_TRANSACTION);
632+
GUC_check_errmsg("\"pg_pathman.enable\" must be called before any query");
633+
return false;
634+
}
635+
636+
return true;
637+
}
638+
617639
/*
618640
* Intercept 'pg_pathman.enable' GUC assignments.
619641
*/

src/include/hooks.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ void pathman_rel_pathlist_hook(PlannerInfo *root,
4444
RangeTblEntry *rte);
4545

4646
void pathman_enable_assign_hook(bool newval, void *extra);
47+
bool pathman_enable_check_hook(bool *newval, void **extra, GucSource source);
4748

4849
PlannedStmt * pathman_planner_hook(Query *parse,
4950
#if PG_VERSION_NUM >= 130000

src/init.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ init_main_pathman_toggles(void)
166166
DEFAULT_PATHMAN_ENABLE,
167167
PGC_SUSET,
168168
0,
169-
NULL,
169+
pathman_enable_check_hook,
170170
pathman_enable_assign_hook,
171171
NULL);
172172

0 commit comments

Comments
 (0)