Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 85fc5cc

Browse filesBrowse files
committed
Blow out cached bounds of all children when parent is invalidated.
A concrete example where leaving them is not ok is - Range partition table - Delete entry from pathman_config (psin was blown, but bounds not) - Now hash partition table; bounds cache with uninitialized hash_idx is used. While here, also spawn relcache inval message on delete from pathman_config, not only from pathman_config_params.
1 parent 10e6c71 commit 85fc5cc
Copy full SHA for 85fc5cc

File tree

6 files changed

+62
-9
lines changed
Filter options

6 files changed

+62
-9
lines changed

‎init.sql

Copy file name to clipboardExpand all lines: init.sql
+5-1Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ ALTER TABLE @extschema@.pathman_config ENABLE ROW LEVEL SECURITY;
111111
ALTER TABLE @extschema@.pathman_config_params ENABLE ROW LEVEL SECURITY;
112112

113113
/*
114-
* Invalidate relcache every time someone changes parameters config.
114+
* Invalidate relcache every time someone changes parameters config or pathman_config
115115
*/
116116
CREATE OR REPLACE FUNCTION @extschema@.pathman_config_params_trigger_func()
117117
RETURNS TRIGGER AS 'pg_pathman', 'pathman_config_params_trigger_func'
@@ -121,6 +121,10 @@ CREATE TRIGGER pathman_config_params_trigger
121121
AFTER INSERT OR UPDATE OR DELETE ON @extschema@.pathman_config_params
122122
FOR EACH ROW EXECUTE PROCEDURE @extschema@.pathman_config_params_trigger_func();
123123

124+
CREATE TRIGGER pathman_config_trigger
125+
AFTER INSERT OR UPDATE OR DELETE ON @extschema@.pathman_config
126+
FOR EACH ROW EXECUTE PROCEDURE @extschema@.pathman_config_params_trigger_func();
127+
124128
/*
125129
* Enable dump of config tables with pg_dump.
126130
*/

‎pg_pathman--1.4--1.5.sql

Copy file name to clipboardExpand all lines: pg_pathman--1.4--1.5.sql
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ ALTER TABLE @extschema@.pathman_config ADD CONSTRAINT pathman_config_interval_ch
5252
parttype,
5353
range_interval));
5454

55+
CREATE TRIGGER pathman_config_trigger
56+
AFTER INSERT OR UPDATE OR DELETE ON @extschema@.pathman_config
57+
FOR EACH ROW EXECUTE PROCEDURE @extschema@.pathman_config_params_trigger_func();
58+
5559
/*
5660
* Get parsed and analyzed expression.
5761
*/

‎src/hooks.c

Copy file name to clipboardExpand all lines: src/hooks.c
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -874,7 +874,7 @@ pathman_relcache_hook(Datum arg, Oid relid)
874874
else if (relid >= FirstNormalObjectId)
875875
{
876876
/* Invalidate PartBoundInfo entry if needed */
877-
forget_bounds_of_partition(relid);
877+
forget_bounds_of_rel(relid);
878878

879879
/* Invalidate PartParentInfo entry if needed */
880880
forget_parent_of_partition(relid);

‎src/include/relation_info.h

Copy file name to clipboardExpand all lines: src/include/relation_info.h
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ void shout_if_prel_is_invalid(const Oid parent_oid,
367367
const PartType expected_part_type);
368368

369369
/* Bounds cache */
370-
void forget_bounds_of_partition(Oid partition);
370+
void forget_bounds_of_rel(Oid partition);
371371
PartBoundInfo *get_bounds_of_partition(Oid partition, const PartRelationInfo *prel);
372372
Expr *get_partition_constraint_expr(Oid partition, bool raise_error);
373373
void invalidate_bounds_cache(void);

‎src/pl_funcs.c

Copy file name to clipboardExpand all lines: src/pl_funcs.c
+12-5Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -904,14 +904,16 @@ pathman_config_params_trigger_func(PG_FUNCTION_ARGS)
904904
{
905905
TriggerData *trigdata = (TriggerData *) fcinfo->context;
906906
Oid pathman_config_params;
907+
Oid pathman_config;
907908
Oid partrel;
908909
Datum partrel_datum;
909910
bool partrel_isnull;
910911

911912
/* Fetch Oid of PATHMAN_CONFIG_PARAMS */
912913
pathman_config_params = get_pathman_config_params_relid(true);
914+
pathman_config = get_pathman_config_relid(true);
913915

914-
/* Handle "pg_pathman.enabled = t" case */
916+
/* Handle "pg_pathman.enabled = f" case */
915917
if (!OidIsValid(pathman_config_params))
916918
goto pathman_config_params_trigger_func_return;
917919

@@ -925,12 +927,17 @@ pathman_config_params_trigger_func(PG_FUNCTION_ARGS)
925927
trigdata->tg_trigger->tgname);
926928

927929
/* Handle wrong relation */
928-
if (RelationGetRelid(trigdata->tg_relation) != pathman_config_params)
929-
elog(ERROR, "%s: must be fired for relation \"%s\"",
930+
if (RelationGetRelid(trigdata->tg_relation) != pathman_config_params &&
931+
RelationGetRelid(trigdata->tg_relation) != pathman_config)
932+
elog(ERROR, "%s: must be fired for relation \"%s\" or \"%s\"",
930933
trigdata->tg_trigger->tgname,
931-
get_rel_name(pathman_config_params));
934+
get_rel_name(pathman_config_params),
935+
get_rel_name(pathman_config));
932936

933-
/* Extract partitioned relation's Oid */
937+
/*
938+
* Extract partitioned relation's Oid.
939+
* Hacky: 1 is attrnum of relid for both pathman_config and pathman_config_params
940+
*/
934941
partrel_datum = heap_getattr(trigdata->tg_trigtuple,
935942
Anum_pathman_config_params_partrel,
936943
RelationGetDescr(trigdata->tg_relation),

‎src/relation_info.c

Copy file name to clipboardExpand all lines: src/relation_info.c
+39-1Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ static void fill_pbin_with_bounds(PartBoundInfo *pbin,
160160

161161
static int cmp_range_entries(const void *p1, const void *p2, void *arg);
162162

163+
static void forget_bounds_of_partition(Oid partition);
164+
163165
static bool query_contains_subqueries(Node *node, void *context);
164166

165167

@@ -929,7 +931,7 @@ PrelExpressionAttributesMap(const PartRelationInfo *prel,
929931
*/
930932

931933
/* Remove partition's constraint from cache */
932-
void
934+
static void
933935
forget_bounds_of_partition(Oid partition)
934936
{
935937
PartBoundInfo *pbin;
@@ -953,6 +955,42 @@ forget_bounds_of_partition(Oid partition)
953955
HASH_REMOVE,
954956
NULL);
955957
}
958+
959+
}
960+
961+
/*
962+
* Remove rel's constraint from cache, if relid is partition;
963+
* Remove all children constraints, if it is parent.
964+
*/
965+
void
966+
forget_bounds_of_rel(Oid relid)
967+
{
968+
PartStatusInfo *psin;
969+
970+
forget_bounds_of_partition(relid);
971+
972+
/*
973+
* If it was the parent who got invalidated, purge children's bounds.
974+
* We assume here that if bounds_cache has something, parent must be also
975+
* in status_cache. Fragile, but seems better then blowing out full bounds
976+
* cache or digging pathman_config on each relcache invalidation.
977+
*/
978+
979+
/* Find status cache entry for this relation */
980+
psin = pathman_cache_search_relid(status_cache,
981+
relid, HASH_FIND,
982+
NULL);
983+
if (psin != NULL && psin->prel != NULL)
984+
{
985+
uint32 i;
986+
PartRelationInfo *prel = psin->prel;
987+
Oid *children = PrelGetChildrenArray(prel);
988+
989+
for (i = 0; i < PrelChildrenCount(prel); i++)
990+
{
991+
forget_bounds_of_partition(children[i]);
992+
}
993+
}
956994
}
957995

958996
/* Return partition's constraint as expression tree */

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.