Skip to content

Commit b94b2c1

Browse files
committed
resolve conflict in relation_info.c
2 parents cc320fc + 1eec8ca commit b94b2c1

File tree

5 files changed

+124
-39
lines changed

5 files changed

+124
-39
lines changed

src/init.c

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -466,8 +466,12 @@ fill_prel_with_partitions(const Oid *partitions,
466466
*
467467
* borrowed from pg_inherits.c
468468
*/
469-
Oid *
470-
find_inheritance_children_array(Oid parentrelId, LOCKMODE lockmode, uint32 *size)
469+
find_children_status
470+
find_inheritance_children_array(Oid parentrelId,
471+
LOCKMODE lockmode,
472+
bool nowait,
473+
uint32 *children_size, /* ret value #1 */
474+
Oid **children) /* ret value #2 */
471475
{
472476
Relation relation;
473477
SysScanDesc scan;
@@ -485,8 +489,12 @@ find_inheritance_children_array(Oid parentrelId, LOCKMODE lockmode, uint32 *size
485489
*/
486490
if (!has_subclass(parentrelId))
487491
{
488-
*size = 0;
489-
return NULL;
492+
/* Init return values */
493+
*children_size = 0;
494+
children = NULL;
495+
496+
/* Ok, could not find any children */
497+
return FCS_NO_CHILDREN;
490498
}
491499

492500
/*
@@ -540,7 +548,25 @@ find_inheritance_children_array(Oid parentrelId, LOCKMODE lockmode, uint32 *size
540548
if (lockmode != NoLock)
541549
{
542550
/* Get the lock to synchronize against concurrent drop */
543-
LockRelationOid(inhrelid, lockmode);
551+
if (nowait)
552+
{
553+
if (!ConditionalLockRelationOid(inhrelid, lockmode))
554+
{
555+
uint32 j;
556+
557+
/* Unlock all previously locked children */
558+
for (j = 0; j < i; j++)
559+
UnlockRelationOid(oidarr[j], lockmode);
560+
561+
/* Init return values */
562+
*children_size = numoids;
563+
*children = oidarr;
564+
565+
/* We couldn't lock this child, retreat! */
566+
return FCS_COULD_NOT_LOCK;
567+
}
568+
}
569+
else LockRelationOid(inhrelid, lockmode);
544570

545571
/*
546572
* Now that we have the lock, double-check to see if the relation
@@ -557,8 +583,12 @@ find_inheritance_children_array(Oid parentrelId, LOCKMODE lockmode, uint32 *size
557583
}
558584
}
559585

560-
*size = numoids;
561-
return oidarr;
586+
/* Init return values */
587+
*children_size = numoids;
588+
*children = oidarr;
589+
590+
/* Ok, we have children */
591+
return FCS_FOUND;
562592
}
563593

564594
/*
@@ -752,7 +782,9 @@ read_pathman_config(void)
752782
}
753783

754784
/* Create or update PartRelationInfo for this partitioned table */
755-
refresh_pathman_relation_info(relid, parttype, text_to_cstring(attname));
785+
refresh_pathman_relation_info(relid, parttype,
786+
text_to_cstring(attname),
787+
true); /* allow lazy prel loading */
756788
}
757789

758790
/* Clean resources */

src/init.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,19 @@ void fill_prel_with_partitions(const Oid *partitions,
109109
const uint32 parts_count,
110110
PartRelationInfo *prel);
111111

112-
Oid *find_inheritance_children_array(Oid parentrelId,
113-
LOCKMODE lockmode,
114-
uint32 *size);
112+
/* Result of find_inheritance_children_array() */
113+
typedef enum
114+
{
115+
FCS_NO_CHILDREN = 0, /* could not find any children (GOOD) */
116+
FCS_COULD_NOT_LOCK, /* could not lock one of the children */
117+
FCS_FOUND /* found some children (GOOD) */
118+
} find_children_status;
119+
120+
find_children_status find_inheritance_children_array(Oid parentrelId,
121+
LOCKMODE lockmode,
122+
bool nowait,
123+
uint32 *children_size,
124+
Oid **children);
115125

116126
char *build_check_constraint_name_internal(Oid relid,
117127
AttrNumber attno);

src/pl_funcs.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,9 @@ add_to_pathman_config(PG_FUNCTION_ARGS)
623623
/* Some flags might change during refresh attempt */
624624
save_pathman_init_state(&init_state);
625625

626-
refresh_pathman_relation_info(relid, parttype, text_to_cstring(attname));
626+
refresh_pathman_relation_info(relid, parttype,
627+
text_to_cstring(attname),
628+
false); /* initialize immediately */
627629
}
628630
PG_CATCH();
629631
{

src/relation_info.c

Lines changed: 66 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@
2323
#include "utils/builtins.h"
2424
#include "utils/fmgroids.h"
2525
#include "utils/hsearch.h"
26-
#include "utils/lsyscache.h"
2726
#include "utils/memutils.h"
2827
#include "utils/snapmgr.h"
28+
#include "utils/syscache.h"
29+
#include "utils/lsyscache.h"
2930
#include "utils/typcache.h"
3031

3132

@@ -67,23 +68,24 @@ static Oid get_parent_of_partition_internal(Oid partition,
6768
const PartRelationInfo *
6869
refresh_pathman_relation_info(Oid relid,
6970
PartType partitioning_type,
70-
const char *part_column_name)
71+
const char *part_column_name,
72+
bool allow_incomplete)
7173
{
7274
const LOCKMODE lockmode = AccessShareLock;
7375
const TypeCacheEntry *typcache;
7476
Oid *prel_children;
7577
uint32 prel_children_count = 0,
7678
i;
77-
bool found;
79+
bool found_entry;
7880
PartRelationInfo *prel;
7981
Datum param_values[Natts_pathman_config_params];
8082
bool param_isnull[Natts_pathman_config_params];
8183

8284
prel = (PartRelationInfo *) hash_search(partitioned_rels,
8385
(const void *) &relid,
84-
HASH_ENTER, &found);
86+
HASH_ENTER, &found_entry);
8587
elog(DEBUG2,
86-
found ?
88+
found_entry ?
8789
"Refreshing record for relation %u in pg_pathman's cache [%u]" :
8890
"Creating new record for relation %u in pg_pathman's cache [%u]",
8991
relid, MyProcPid);
@@ -92,25 +94,42 @@ refresh_pathman_relation_info(Oid relid,
9294
* NOTE: Trick clang analyzer (first access without NULL pointer check).
9395
* Access to field 'valid' results in a dereference of a null pointer.
9496
*/
95-
prel->cmp_proc = InvalidOid;
97+
prel->cmp_proc = InvalidOid;
9698

9799
/* Clear outdated resources */
98-
if (found && PrelIsValid(prel))
100+
if (found_entry && PrelIsValid(prel))
99101
{
100102
/* Free these arrays iff they're not NULL */
101103
FreeChildrenArray(prel);
102104
FreeRangesArray(prel);
103105
}
104106

105107
/* First we assume that this entry is invalid */
106-
prel->valid = false;
108+
prel->valid = false;
109+
110+
/* Try locking parent, exit fast if 'allow_incomplete' */
111+
if (allow_incomplete)
112+
{
113+
if (!ConditionalLockRelationOid(relid, lockmode))
114+
return NULL; /* leave an invalid entry */
115+
}
116+
else LockRelationOid(relid, lockmode);
117+
118+
/* Check if parent exists */
119+
if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(relid)))
120+
{
121+
/* Nope, it doesn't, remove this entry and exit */
122+
UnlockRelationOid(relid, lockmode);
123+
remove_pathman_relation_info(relid);
124+
return NULL; /* exit */
125+
}
107126

108127
/* Make both arrays point to NULL */
109-
prel->children = NULL;
110-
prel->ranges = NULL;
128+
prel->children = NULL;
129+
prel->ranges = NULL;
111130

112131
/* Set partitioning type */
113-
prel->parttype = partitioning_type;
132+
prel->parttype = partitioning_type;
114133

115134
/* Initialize PartRelationInfo using syscache & typcache */
116135
prel->attnum = get_attnum(relid, part_column_name);
@@ -135,16 +154,31 @@ refresh_pathman_relation_info(Oid relid,
135154
prel->cmp_proc = typcache->cmp_proc;
136155
prel->hash_proc = typcache->hash_proc;
137156

138-
LockRelationOid(relid, lockmode);
139-
prel_children = find_inheritance_children_array(relid, lockmode,
140-
&prel_children_count);
141-
UnlockRelationOid(relid, lockmode);
142-
143-
/* If there's no children at all, remove this entry */
144-
if (prel_children_count == 0)
157+
/* Try searching for children (don't wait if we can't lock) */
158+
switch (find_inheritance_children_array(relid, lockmode,
159+
allow_incomplete,
160+
&prel_children_count,
161+
&prel_children))
145162
{
146-
remove_pathman_relation_info(relid);
147-
return NULL;
163+
/* If there's no children at all, remove this entry */
164+
case FCS_NO_CHILDREN:
165+
UnlockRelationOid(relid, lockmode);
166+
remove_pathman_relation_info(relid);
167+
return NULL; /* exit */
168+
169+
/* If can't lock children, leave an invalid entry */
170+
case FCS_COULD_NOT_LOCK:
171+
UnlockRelationOid(relid, lockmode);
172+
return NULL; /* exit */
173+
174+
/* Found some children, just unlock parent */
175+
case FCS_FOUND:
176+
UnlockRelationOid(relid, lockmode);
177+
break; /* continue */
178+
179+
/* Error: unknown result code */
180+
default:
181+
elog(ERROR, "error in " CppAsString(find_inheritance_children_array));
148182
}
149183

150184
/*
@@ -155,10 +189,16 @@ refresh_pathman_relation_info(Oid relid,
155189
*/
156190
fill_prel_with_partitions(prel_children, prel_children_count, prel);
157191

158-
/* Add "partition+parent" tuple to cache */
192+
/* Peform some actions for each child */
159193
for (i = 0; i < prel_children_count; i++)
194+
{
195+
/* Add "partition+parent" pair to cache */
160196
cache_parent_of_partition(prel_children[i], relid);
161197

198+
/* Now it's time to unlock this child */
199+
UnlockRelationOid(prel_children[i], lockmode);
200+
}
201+
162202
pfree(prel_children);
163203

164204
/* Read additional parameters ('enable_parent' and 'auto' at the moment) */
@@ -245,7 +285,7 @@ get_pathman_relation_info(Oid relid)
245285

246286
/* Refresh partitioned table cache entry (might turn NULL) */
247287
/* TODO: possible refactoring, pass found 'prel' instead of searching */
248-
prel = refresh_pathman_relation_info(relid, part_type, attname);
288+
prel = refresh_pathman_relation_info(relid, part_type, attname, false);
249289
}
250290
/* Else clear remaining cache entry */
251291
else remove_pathman_relation_info(relid);
@@ -609,10 +649,10 @@ try_perform_parent_refresh(Oid parent)
609649
parttype = DatumGetPartType(values[Anum_pathman_config_parttype - 1]);
610650
attname = DatumGetTextP(values[Anum_pathman_config_attname - 1]);
611651

612-
/* If anything went wrong, return false (actually, it might throw ERROR) */
613-
if (!PrelIsValid(refresh_pathman_relation_info(parent, parttype,
614-
text_to_cstring(attname))))
615-
return false;
652+
/* If anything went wrong, return false (actually, it might emit ERROR) */
653+
refresh_pathman_relation_info(parent, parttype,
654+
text_to_cstring(attname),
655+
true); /* allow lazy */
616656
}
617657
/* Not a partitioned relation */
618658
else return false;

src/relation_info.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ PrelLastChild(const PartRelationInfo *prel)
120120

121121
const PartRelationInfo *refresh_pathman_relation_info(Oid relid,
122122
PartType partitioning_type,
123-
const char *part_column_name);
123+
const char *part_column_name,
124+
bool allow_incomplete);
124125
void invalidate_pathman_relation_info(Oid relid, bool *found);
125126
void remove_pathman_relation_info(Oid relid);
126127
const PartRelationInfo *get_pathman_relation_info(Oid relid);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy