Skip to content

Commit a6e4260

Browse files
committed
introduce function add_to_pathman_config(), remove useless column 'id' from pathman_config, replace pg_pathman_enable & initialization_needed with struct PathmanInitState, small fixes & refactoring
1 parent 1f9cc96 commit a6e4260

File tree

8 files changed

+263
-95
lines changed

8 files changed

+263
-95
lines changed

expected/pg_pathman.out

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,8 +1141,8 @@ SELECT * FROM test.range_rel WHERE dt = '2015-03-15';
11411141
DROP TABLE test.range_rel CASCADE;
11421142
NOTICE: drop cascades to 16 other objects
11431143
SELECT * FROM pathman.pathman_config;
1144-
id | partrel | attname | parttype | range_interval
1145-
----+---------+---------+----------+----------------
1144+
partrel | attname | parttype | range_interval
1145+
---------+---------+----------+----------------
11461146
(0 rows)
11471147

11481148
/* Check overlaps */
@@ -1325,9 +1325,9 @@ SELECT pathman.create_partitions_from_range('test."RangeRel"', 'dt', '2015-01-01
13251325
DROP TABLE test."RangeRel" CASCADE;
13261326
NOTICE: drop cascades to 5 other objects
13271327
SELECT * FROM pathman.pathman_config;
1328-
id | partrel | attname | parttype | range_interval
1329-
----+--------------------+---------+----------+----------------
1330-
9 | test.num_range_rel | id | 2 | 1000
1328+
partrel | attname | parttype | range_interval
1329+
--------------------+---------+----------+----------------
1330+
test.num_range_rel | id | 2 | 1000
13311331
(1 row)
13321332

13331333
CREATE TABLE test."RangeRel" (

init.sql

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@
1818
* range_interval - base interval for RANGE partitioning as string
1919
*/
2020
CREATE TABLE IF NOT EXISTS @extschema@.pathman_config (
21-
id SERIAL PRIMARY KEY,
22-
partrel REGCLASS NOT NULL,
21+
partrel REGCLASS NOT NULL PRIMARY KEY,
2322
attname TEXT NOT NULL,
2423
parttype INTEGER NOT NULL,
2524
range_interval TEXT,
@@ -100,7 +99,7 @@ BEGIN
10099
RAISE EXCEPTION 'Partitioning key ''%'' must be NOT NULL', p_attribute;
101100
END IF;
102101

103-
/* Check if there are foreign keys reference to the relation */
102+
/* Check if there are foreign keys that reference the relation */
104103
FOR v_rec IN (SELECT *
105104
FROM pg_constraint WHERE confrelid = p_relation::regclass::oid)
106105
LOOP
@@ -243,12 +242,9 @@ CREATE OR REPLACE FUNCTION @extschema@.drop_triggers(
243242
parent_relid REGCLASS)
244243
RETURNS VOID AS
245244
$$
246-
DECLARE
247-
funcname TEXT;
248-
249245
BEGIN
250-
funcname := @extschema@.build_update_trigger_func_name(parent_relid);
251-
EXECUTE format('DROP FUNCTION IF EXISTS %s() CASCADE', funcname);
246+
EXECUTE format('DROP FUNCTION IF EXISTS %s() CASCADE',
247+
@extschema@.build_update_trigger_func_name(parent_relid));
252248
END
253249
$$ LANGUAGE plpgsql;
254250

@@ -317,12 +313,14 @@ EXECUTE PROCEDURE @extschema@.pathman_ddl_trigger_func();
317313

318314

319315
/*
320-
* Check if regclass is date or timestamp
316+
* Attach partitioned table
321317
*/
322-
CREATE OR REPLACE FUNCTION @extschema@.is_date_type(
323-
typid REGTYPE)
324-
RETURNS BOOLEAN AS 'pg_pathman', 'is_date_type'
325-
LANGUAGE C STRICT;
318+
CREATE OR REPLACE FUNCTION @extschema@.add_to_pathman_config(
319+
parent_relid REGCLASS,
320+
attname TEXT,
321+
range_interval TEXT DEFAULT NULL)
322+
RETURNS BOOLEAN AS 'pg_pathman', 'add_to_pathman_config'
323+
LANGUAGE C;
326324

327325

328326
CREATE OR REPLACE FUNCTION @extschema@.on_create_partitions(
@@ -341,6 +339,21 @@ RETURNS VOID AS 'pg_pathman', 'on_partitions_removed'
341339
LANGUAGE C STRICT;
342340

343341

342+
/*
343+
* Get parent of pg_pathman's partition.
344+
*/
345+
CREATE OR REPLACE FUNCTION @extschema@.get_parent_of_partition(REGCLASS)
346+
RETURNS REGCLASS AS 'pg_pathman', 'get_parent_of_partition_pl'
347+
LANGUAGE C STRICT;
348+
349+
/*
350+
* Check if regclass is date or timestamp
351+
*/
352+
CREATE OR REPLACE FUNCTION @extschema@.is_date_type(
353+
typid REGTYPE)
354+
RETURNS BOOLEAN AS 'pg_pathman', 'is_date_type'
355+
LANGUAGE C STRICT;
356+
344357
/*
345358
* Checks if attribute is nullable
346359
*/
@@ -389,10 +402,3 @@ LANGUAGE C STRICT;
389402
CREATE OR REPLACE FUNCTION @extschema@.debug_capture()
390403
RETURNS VOID AS 'pg_pathman', 'debug_capture'
391404
LANGUAGE C STRICT;
392-
393-
/*
394-
* Get parent of pg_pathman's partition.
395-
*/
396-
CREATE OR REPLACE FUNCTION @extschema@.get_parent_of_partition(REGCLASS)
397-
RETURNS REGCLASS AS 'pg_pathman', 'get_parent_of_partition_pl'
398-
LANGUAGE C STRICT;

src/hooks.c

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -356,15 +356,8 @@ pg_pathman_enable_assign_hook(bool newval, void *extra)
356356
elog(DEBUG2, "pg_pathman_enable_assign_hook() [newval = %s] triggered",
357357
newval ? "true" : "false");
358358

359-
if (initialization_needed)
360-
{
361-
elog(DEBUG2, "pg_pathman is not yet initialized, "
362-
"pg_pathman.enable is set to false");
363-
return;
364-
}
365-
366359
/* Return quickly if nothing has changed */
367-
if (newval == (pg_pathman_enable &&
360+
if (newval == (pg_pathman_init_state.pg_pathman_enable &&
368361
pg_pathman_enable_runtimeappend &&
369362
pg_pathman_enable_runtime_merge_append &&
370363
pg_pathman_enable_partition_filter))
@@ -459,7 +452,7 @@ pathman_post_parse_analysis_hook(ParseState *pstate, Query *query)
459452

460453
/* Load config if pg_pathman exists & it's still necessary */
461454
if (IsPathmanEnabled() &&
462-
initialization_needed &&
455+
!IsPathmanInitialized() &&
463456
/* Now evaluate the most expensive clause */
464457
get_pathman_schema() != InvalidOid)
465458
{

src/init.c

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,23 +38,27 @@
3838
#include "utils/snapmgr.h"
3939

4040

41+
/* Help user in case of emergency */
42+
#define INIT_ERROR_HINT "pg_pathman will be disabled to allow you to resolve this issue"
43+
4144
/* Initial size of 'partitioned_rels' table */
4245
#define PART_RELS_SIZE 10
4346
#define CHILD_FACTOR 500
4447

48+
4549
/* Storage for PartRelationInfos */
46-
HTAB *partitioned_rels = NULL;
50+
HTAB *partitioned_rels = NULL;
4751

4852
/* Storage for PartParentInfos */
49-
HTAB *parent_cache = NULL;
53+
HTAB *parent_cache = NULL;
5054

51-
bool initialization_needed = true;
52-
static bool relcache_callback_needed = true;
53-
54-
/* Help user in case of emergency */
55-
#define INIT_ERROR_HINT "pg_pathman will be disabled to allow you fix this"
55+
/* pg_pathman's init status */
56+
PathmanInitState pg_pathman_init_state;
5657

58+
/* Shall we install new relcache callback? */
59+
static bool relcache_callback_needed = true;
5760

61+
/* Functions for various local caches */
5862
static bool init_pathman_relation_oids(void);
5963
static void fini_pathman_relation_oids(void);
6064
static void init_local_cache(void);
@@ -81,6 +85,41 @@ static bool read_opexpr_const(const OpExpr *opexpr,
8185
static int oid_cmp(const void *p1, const void *p2);
8286

8387

88+
/*
89+
* Save and restore main init state.
90+
*/
91+
92+
void
93+
save_pathman_init_state(PathmanInitState *temp_init_state)
94+
{
95+
*temp_init_state = pg_pathman_init_state;
96+
}
97+
98+
void
99+
restore_pathman_init_state(const PathmanInitState *temp_init_state)
100+
{
101+
pg_pathman_init_state = *temp_init_state;
102+
}
103+
104+
/*
105+
* Create main GUC.
106+
*/
107+
void
108+
init_main_pathman_toggle(void)
109+
{
110+
/* Main toggle, load_config() will enable it */
111+
DefineCustomBoolVariable("pg_pathman.enable",
112+
"Enables pg_pathman's optimizations during the planner stage",
113+
NULL,
114+
&pg_pathman_init_state.pg_pathman_enable,
115+
true,
116+
PGC_USERSET,
117+
0,
118+
NULL,
119+
pg_pathman_enable_assign_hook,
120+
NULL);
121+
}
122+
84123
/*
85124
* Create local PartRelationInfo cache & load pg_pathman's config.
86125
* Return true on success. May occasionally emit ERROR.
@@ -111,7 +150,7 @@ load_config(void)
111150
}
112151

113152
/* Mark pg_pathman as initialized */
114-
initialization_needed = false;
153+
pg_pathman_init_state.initialization_needed = false;
115154

116155
elog(DEBUG2, "pg_pathman's config has been loaded successfully [%u]", MyProcPid);
117156

@@ -131,7 +170,7 @@ unload_config(void)
131170
fini_local_cache();
132171

133172
/* Mark pg_pathman as uninitialized */
134-
initialization_needed = true;
173+
pg_pathman_init_state.initialization_needed = true;
135174

136175
elog(DEBUG2, "pg_pathman's config has been unloaded successfully [%u]", MyProcPid);
137176
}
@@ -539,7 +578,6 @@ pathman_config_contains_relation(Oid relid, Datum *values, bool *isnull,
539578
heap_deform_tuple(htup, RelationGetDescr(rel), values, isnull);
540579

541580
/* Perform checks for non-NULL columns */
542-
Assert(!isnull[Anum_pathman_config_id - 1]);
543581
Assert(!isnull[Anum_pathman_config_partrel - 1]);
544582
Assert(!isnull[Anum_pathman_config_attname - 1]);
545583
Assert(!isnull[Anum_pathman_config_parttype - 1]);

src/init.h

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,63 @@
1515

1616
#include "postgres.h"
1717
#include "storage/lmgr.h"
18-
#include "utils/snapshot.h"
18+
#include "utils/guc.h"
1919
#include "utils/hsearch.h"
20+
#include "utils/snapshot.h"
21+
22+
23+
/*
24+
* pg_pathman's initialization state structure.
25+
*/
26+
typedef struct
27+
{
28+
bool pg_pathman_enable; /* GUC variable implementation */
29+
bool initialization_needed; /* do we need to perform init? */
30+
} PathmanInitState;
2031

2132

22-
extern HTAB *partitioned_rels;
23-
extern HTAB *parent_cache;
24-
extern bool initialization_needed;
33+
extern HTAB *partitioned_rels;
34+
extern HTAB *parent_cache;
2535

36+
/* pg_pathman's initialization state */
37+
extern PathmanInitState pg_pathman_init_state;
38+
39+
40+
/*
41+
* Check if pg_pathman is initialized.
42+
*/
43+
#define IsPathmanInitialized() ( !pg_pathman_init_state.initialization_needed )
44+
45+
/*
46+
* Check if pg_pathman is enabled.
47+
*/
48+
#define IsPathmanEnabled() ( pg_pathman_init_state.pg_pathman_enable )
49+
50+
/*
51+
* Check if pg_pathman is initialized & enabled.
52+
*/
53+
#define IsPathmanReady() ( IsPathmanInitialized() && IsPathmanEnabled() )
54+
55+
/*
56+
* Emergency disable mechanism.
57+
*/
58+
#define DisablePathman() \
59+
do { \
60+
pg_pathman_init_state.pg_pathman_enable = false; \
61+
pg_pathman_init_state.initialization_needed = true; \
62+
} while (0)
63+
64+
65+
/*
66+
* Save and restore PathmanInitState.
67+
*/
68+
void save_pathman_init_state(PathmanInitState *temp_init_state);
69+
void restore_pathman_init_state(const PathmanInitState *temp_init_state);
70+
71+
/*
72+
* Create main GUC variable.
73+
*/
74+
void init_main_pathman_toggle(void);
2675

2776
Size estimate_pathman_shmem_size(void);
2877
void init_shmem_config(void);

src/pathman.h

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
#ifndef PATHMAN_H
1212
#define PATHMAN_H
1313

14-
#include "init.h"
1514
#include "relation_info.h"
1615
#include "rangeset.h"
1716

@@ -43,16 +42,17 @@
4342
* Definitions for the "pathman_config" table.
4443
*/
4544
#define PATHMAN_CONFIG "pathman_config"
46-
#define Natts_pathman_config 5
47-
#define Anum_pathman_config_id 1 /* primary key */
48-
#define Anum_pathman_config_partrel 2 /* partitioned relation (regclass) */
49-
#define Anum_pathman_config_attname 3 /* partitioned column (text) */
50-
#define Anum_pathman_config_parttype 4 /* partitioning type (1|2) */
51-
#define Anum_pathman_config_range_interval 5 /* interval for RANGE pt. (text) */
45+
#define Natts_pathman_config 4
46+
#define Anum_pathman_config_partrel 1 /* partitioned relation (regclass) */
47+
#define Anum_pathman_config_attname 2 /* partitioned column (text) */
48+
#define Anum_pathman_config_parttype 3 /* partitioning type (1|2) */
49+
#define Anum_pathman_config_range_interval 4 /* interval for RANGE pt. (text) */
5250

5351
/* type modifier (typmod) for 'range_interval' */
5452
#define PATHMAN_CONFIG_interval_typmod -1
5553

54+
#define PATHMAN_CONFIG_ID_SEQ "pathman_config_id_seq"
55+
5656
/*
5757
* Cache current PATHMAN_CONFIG relid (set during load_config()).
5858
*/
@@ -96,27 +96,9 @@ extern List *inheritance_enabled_relids;
9696
*/
9797
extern List *inheritance_disabled_relids;
9898

99-
extern bool pg_pathman_enable;
10099
extern PathmanState *pmstate;
101100

102101

103-
#define PATHMAN_GET_DATUM(value, by_val) \
104-
( (by_val) ? (Datum) (value) : PointerGetDatum(&value) )
105-
106-
/*
107-
* Check if pg_pathman is initialized & enabled.
108-
*/
109-
#define IsPathmanReady() ( !initialization_needed && pg_pathman_enable )
110-
111-
#define IsPathmanEnabled() ( pg_pathman_enable )
112-
113-
#define DisablePathman() \
114-
do { \
115-
pg_pathman_enable = false; \
116-
initialization_needed = true; \
117-
} while (0)
118-
119-
120102
int append_child_relation(PlannerInfo *root, RelOptInfo *rel, Index rti,
121103
RangeTblEntry *rte, int index, Oid childOID, List *wrappers);
122104

0 commit comments

Comments
 (0)