Skip to content

Commit 073cf4c

Browse files
committed
small fixes, refactoring (move all remaining hooks to 'hooks.c', move some other funcs to 'utils.c', merge all binary searches into select_range_partitions()), remove useless triggers
1 parent e32f4c6 commit 073cf4c

18 files changed

+668
-679
lines changed

hash.sql

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ BEGIN
5353
VALUES (v_relname, attribute, 1);
5454

5555
/* Create triggers */
56-
PERFORM @extschema@.create_hash_insert_trigger(v_relname, attribute, partitions_count);
5756
/* Do not create update trigger by default */
5857
-- PERFORM @extschema@.create_hash_update_trigger(relation, attribute, partitions_count);
5958

@@ -67,59 +66,6 @@ BEGIN
6766
END
6867
$$ LANGUAGE plpgsql;
6968

70-
/*
71-
* Creates hash trigger for specified relation
72-
*/
73-
CREATE OR REPLACE FUNCTION @extschema@.create_hash_insert_trigger(
74-
IN relation REGCLASS
75-
, IN attr TEXT
76-
, IN partitions_count INTEGER)
77-
RETURNS VOID AS
78-
$$
79-
DECLARE
80-
func TEXT := '
81-
CREATE OR REPLACE FUNCTION %s()
82-
RETURNS TRIGGER AS $body$
83-
DECLARE
84-
hash INTEGER;
85-
BEGIN
86-
hash := NEW.%s %% %s;
87-
%s
88-
RETURN NULL;
89-
END $body$ LANGUAGE plpgsql;';
90-
funcname TEXT;
91-
trigger TEXT := '
92-
CREATE TRIGGER %s
93-
BEFORE INSERT ON %s
94-
FOR EACH ROW EXECUTE PROCEDURE %s();';
95-
triggername TEXT;
96-
-- fields TEXT;
97-
-- fields_format TEXT;
98-
insert_stmt TEXT;
99-
relname TEXT;
100-
schema TEXT;
101-
BEGIN
102-
/* drop trigger and corresponding function */
103-
PERFORM @extschema@.drop_hash_triggers(relation);
104-
105-
SELECT * INTO schema, relname
106-
FROM @extschema@.get_plain_schema_and_relname(relation);
107-
108-
/* generate INSERT statement for trigger */
109-
insert_stmt = format('EXECUTE format(''INSERT INTO %s.%s SELECT $1.*'', hash) USING NEW;'
110-
, schema, quote_ident(relname || '_%s'));
111-
112-
/* format and create new trigger for relation */
113-
funcname := schema || '.' || quote_ident(format('%s_insert_trigger_func', relname));
114-
triggername := quote_ident(format('%s_%s_insert_trigger', schema, relname));
115-
116-
func := format(func, funcname, attr, partitions_count, insert_stmt);
117-
trigger := format(trigger, triggername, relation, funcname);
118-
EXECUTE func;
119-
EXECUTE trigger;
120-
END
121-
$$ LANGUAGE plpgsql;
122-
12369
/*
12470
* Drops all partitions for specified relation
12571
*/

range.sql

Lines changed: 3 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ BEGIN
9696
END LOOP;
9797

9898
/* Create triggers */
99-
PERFORM @extschema@.create_range_insert_trigger(v_relname, p_attribute);
10099
-- PERFORM create_hash_update_trigger(relation, attribute, partitions_count);
101100
/* Notify backend about changes */
102101
PERFORM @extschema@.on_create_partitions(p_relation::oid);
@@ -186,7 +185,6 @@ BEGIN
186185
END LOOP;
187186

188187
/* Create triggers */
189-
PERFORM @extschema@.create_range_insert_trigger(p_relation, p_attribute);
190188
-- PERFORM create_hash_update_trigger(relation, attribute, partitions_count);
191189
/* Notify backend about changes */
192190
PERFORM @extschema@.on_create_partitions(p_relation::regclass::oid);
@@ -251,7 +249,6 @@ BEGIN
251249
END LOOP;
252250

253251
/* Create triggers */
254-
PERFORM @extschema@.create_range_insert_trigger(p_relation, p_attribute);
255252

256253
/* Notify backend about changes */
257254
PERFORM @extschema@.on_create_partitions(p_relation::regclass::oid);
@@ -310,9 +307,6 @@ BEGIN
310307
i := i + 1;
311308
END LOOP;
312309

313-
/* Create triggers */
314-
PERFORM @extschema@.create_range_insert_trigger(p_relation, p_attribute);
315-
316310
/* Notify backend about changes */
317311
PERFORM @extschema@.on_create_partitions(p_relation::regclass::oid);
318312

@@ -328,7 +322,7 @@ END
328322
$$ LANGUAGE plpgsql;
329323

330324
/*
331-
*
325+
*
332326
*/
333327
CREATE OR REPLACE FUNCTION @extschema@.check_boundaries(
334328
p_relation REGCLASS
@@ -706,7 +700,7 @@ BEGIN
706700

707701
/* Prevent concurrent partition creation */
708702
PERFORM @extschema@.acquire_partitions_lock();
709-
703+
710704
EXECUTE format('SELECT @extschema@.append_partition_internal($1, $2, $3, ARRAY[]::%s[])', v_atttype)
711705
INTO v_part_name
712706
USING p_relation, v_atttype, v_interval;
@@ -1010,62 +1004,6 @@ $$
10101004
LANGUAGE plpgsql;
10111005

10121006

1013-
/*
1014-
* Creates range partitioning insert trigger
1015-
*/
1016-
CREATE OR REPLACE FUNCTION @extschema@.create_range_insert_trigger(
1017-
v_relation REGCLASS
1018-
, v_attname TEXT)
1019-
RETURNS VOID AS
1020-
$$
1021-
DECLARE
1022-
v_func TEXT := '
1023-
CREATE OR REPLACE FUNCTION %s()
1024-
RETURNS TRIGGER
1025-
AS $body$
1026-
DECLARE
1027-
v_part_relid OID;
1028-
BEGIN
1029-
IF TG_OP = ''INSERT'' THEN
1030-
IF NEW.%2$s IS NULL THEN
1031-
RAISE EXCEPTION ''ERROR: NULL value in partitioning key'';
1032-
END IF;
1033-
v_part_relid := @extschema@.find_or_create_range_partition(TG_RELID, NEW.%2$s);
1034-
IF NOT v_part_relid IS NULL THEN
1035-
EXECUTE format(''INSERT INTO %%s SELECT $1.*'', v_part_relid::regclass)
1036-
USING NEW;
1037-
ELSE
1038-
RAISE EXCEPTION ''ERROR: Cannot find partition'';
1039-
END IF;
1040-
END IF;
1041-
RETURN NULL;
1042-
END
1043-
$body$ LANGUAGE plpgsql;';
1044-
v_funcname TEXT;
1045-
v_trigger TEXT := '
1046-
CREATE TRIGGER %s
1047-
BEFORE INSERT ON %s
1048-
FOR EACH ROW EXECUTE PROCEDURE %s();';
1049-
v_triggername TEXT;
1050-
v_plain_relname TEXT;
1051-
v_plain_schema TEXT;
1052-
BEGIN
1053-
SELECT * INTO v_plain_schema, v_plain_relname
1054-
FROM @extschema@.get_plain_schema_and_relname(v_relation);
1055-
1056-
v_funcname := format(quote_ident('%s_insert_trigger_func'), v_plain_relname);
1057-
v_triggername := format('"%s_%s_insert_trigger"', v_plain_schema, v_plain_relname);
1058-
1059-
v_func := format(v_func, v_funcname, v_attname);
1060-
v_trigger := format(v_trigger, v_triggername, v_relation, v_funcname);
1061-
1062-
EXECUTE v_func;
1063-
EXECUTE v_trigger;
1064-
RETURN;
1065-
END
1066-
$$ LANGUAGE plpgsql;
1067-
1068-
10691007
/*
10701008
* Creates an update trigger
10711009
*/
@@ -1092,7 +1030,7 @@ DECLARE
10921030
EXECUTE q USING %7$s;
10931031
RETURN NULL;
10941032
END $body$ LANGUAGE plpgsql';
1095-
trigger TEXT := 'CREATE TRIGGER %s_update_trigger ' ||
1033+
trigger TEXT := 'CREATE TRIGGER %s_update_trigger ' ||
10961034
'BEFORE UPDATE ON %s ' ||
10971035
'FOR EACH ROW EXECUTE PROCEDURE %s_update_trigger_func()';
10981036
att_names TEXT;

src/hooks.c

Lines changed: 88 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,20 @@
1111
#include "optimizer/cost.h"
1212
#include "optimizer/restrictinfo.h"
1313
#include "utils/guc.h"
14-
#include "hooks.h"
1514
#include "pathman.h"
15+
#include "hooks.h"
16+
#include "partition_filter.h"
1617
#include "runtimeappend.h"
1718
#include "runtime_merge_append.h"
18-
#include "partition_filter.h"
1919
#include "utils.h"
2020

2121

2222
set_join_pathlist_hook_type set_join_pathlist_next = NULL;
2323
set_rel_pathlist_hook_type set_rel_pathlist_hook_next = NULL;
24+
planner_hook_type planner_hook_next = NULL;
25+
post_parse_analyze_hook_type post_parse_analyze_hook_next = NULL;
26+
shmem_startup_hook_type shmem_startup_hook_next = NULL;
27+
2428

2529
/* Take care of joins */
2630
void
@@ -255,11 +259,11 @@ pathman_rel_pathlist_hook(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTb
255259
palloc0((root->simple_rel_array_size + len) * sizeof(RangeTblEntry *));
256260

257261
/* Copy relations to the new arrays */
258-
for (i = 0; i < root->simple_rel_array_size; i++)
259-
{
260-
new_rel_array[i] = root->simple_rel_array[i];
261-
new_rte_array[i] = root->simple_rte_array[i];
262-
}
262+
for (i = 0; i < root->simple_rel_array_size; i++)
263+
{
264+
new_rel_array[i] = root->simple_rel_array[i];
265+
new_rte_array[i] = root->simple_rte_array[i];
266+
}
263267

264268
/* Free old arrays */
265269
pfree(root->simple_rel_array);
@@ -360,3 +364,80 @@ void pg_pathman_enable_assign_hook(bool newval, void *extra)
360364
newval ? "enabled" : "disabled");
361365
}
362366

367+
/*
368+
* Planner hook. It disables inheritance for tables that have been partitioned
369+
* by pathman to prevent standart PostgreSQL partitioning mechanism from
370+
* handling that tables.
371+
*/
372+
PlannedStmt *
373+
pathman_planner_hook(Query *parse, int cursorOptions, ParamListInfo boundParams)
374+
{
375+
PlannedStmt *result;
376+
377+
if (pg_pathman_enable)
378+
{
379+
inheritance_disabled = false;
380+
switch(parse->commandType)
381+
{
382+
case CMD_SELECT:
383+
disable_inheritance(parse);
384+
break;
385+
case CMD_UPDATE:
386+
case CMD_DELETE:
387+
disable_inheritance_cte(parse);
388+
disable_inheritance_subselect(parse);
389+
handle_modification_query(parse);
390+
break;
391+
case CMD_INSERT:
392+
{
393+
ListCell *lc;
394+
395+
result = standard_planner(parse, cursorOptions, boundParams);
396+
397+
add_partition_filters(result->rtable, result->planTree);
398+
foreach (lc, result->subplans)
399+
add_partition_filters(result->rtable, (Plan *) lfirst(lc));
400+
401+
return result;
402+
}
403+
default:
404+
break;
405+
}
406+
}
407+
408+
/* Invoke original hook */
409+
if (planner_hook_next)
410+
result = planner_hook_next(parse, cursorOptions, boundParams);
411+
else
412+
result = standard_planner(parse, cursorOptions, boundParams);
413+
414+
return result;
415+
}
416+
417+
/*
418+
* Post parse analysis hook. It makes sure the config is loaded before executing
419+
* any statement, including utility commands
420+
*/
421+
void
422+
pathman_post_parse_analysis_hook(ParseState *pstate, Query *query)
423+
{
424+
if (initialization_needed)
425+
load_config();
426+
427+
if (post_parse_analyze_hook_next)
428+
post_parse_analyze_hook_next(pstate, query);
429+
}
430+
431+
void
432+
pathman_shmem_startup_hook(void)
433+
{
434+
/* Allocate shared memory objects */
435+
LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE);
436+
init_dsm_config();
437+
init_shmem_config();
438+
LWLockRelease(AddinShmemInitLock);
439+
440+
/* Invoke original hook if needed */
441+
if (shmem_startup_hook_next != NULL)
442+
shmem_startup_hook_next();
443+
}

src/hooks.h

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,40 @@
1111
#define JOIN_HOOK_H
1212

1313
#include "postgres.h"
14+
#include "optimizer/planner.h"
1415
#include "optimizer/paths.h"
16+
#include "parser/analyze.h"
17+
#include "storage/ipc.h"
18+
1519

1620
extern set_join_pathlist_hook_type set_join_pathlist_next;
1721
extern set_rel_pathlist_hook_type set_rel_pathlist_hook_next;
22+
extern planner_hook_type planner_hook_next;
23+
extern post_parse_analyze_hook_type post_parse_analyze_hook_next;
24+
extern shmem_startup_hook_type shmem_startup_hook_next;
25+
1826

19-
void pathman_join_pathlist_hook(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *outerrel,
20-
RelOptInfo *innerrel, JoinType jointype, JoinPathExtraData *extra);
27+
void pathman_join_pathlist_hook(PlannerInfo *root,
28+
RelOptInfo *joinrel,
29+
RelOptInfo *outerrel,
30+
RelOptInfo *innerrel,
31+
JoinType jointype,
32+
JoinPathExtraData *extra);
2133

22-
void pathman_rel_pathlist_hook(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTblEntry *rte);
34+
void pathman_rel_pathlist_hook(PlannerInfo *root,
35+
RelOptInfo *rel,
36+
Index rti,
37+
RangeTblEntry *rte);
2338

2439
void pg_pathman_enable_assign_hook(char newval, void *extra);
2540

41+
PlannedStmt * pathman_planner_hook(Query *parse,
42+
int cursorOptions,
43+
ParamListInfo boundParams);
44+
45+
void pathman_post_parse_analysis_hook(ParseState *pstate,
46+
Query *query);
47+
48+
void pathman_shmem_startup_hook(void);
49+
2650
#endif

src/init.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ init_shmem_config()
6060
if (!IsUnderPostmaster)
6161
{
6262
/* Initialize locks */
63-
pmstate->load_config_lock = LWLockAssign();
64-
pmstate->dsm_init_lock = LWLockAssign();
65-
pmstate->edit_partitions_lock = LWLockAssign();
63+
pmstate->load_config_lock = LWLockAssign();
64+
pmstate->dsm_init_lock = LWLockAssign();
65+
pmstate->edit_partitions_lock = LWLockAssign();
6666
}
6767
#ifdef WIN32
6868
else
@@ -114,7 +114,7 @@ load_config(void)
114114

115115
/* Check if we already cached config for current database */
116116
databases = (Oid *) dsm_array_get_pointer(&pmstate->databases);
117-
for(i=0; i<databases_count; i++)
117+
for(i = 0; i < databases_count; i++)
118118
if (databases[i] == MyDatabaseId)
119119
{
120120
LWLockRelease(pmstate->dsm_init_lock);
@@ -331,7 +331,7 @@ load_check_constraints(Oid parent_oid, Snapshot snapshot)
331331
rangerel->by_val = tce->typbyval;
332332
}
333333

334-
for (i=0; i<proc; i++)
334+
for (i = 0; i < proc; i++)
335335
{
336336
RangeEntry re;
337337
HeapTuple tuple = tuptable->vals[i];
@@ -575,7 +575,7 @@ remove_relation_info(Oid relid)
575575
{
576576
PartRelationInfo *prel;
577577
RangeRelation *rangerel;
578-
RelationKey key;
578+
RelationKey key;
579579

580580
key.dbid = MyDatabaseId;
581581
key.relid = relid;

0 commit comments

Comments
 (0)