Skip to content

Commit d18ff3e

Browse files
committed
fix PackDatumToByteArray() & UnpackDatumFromByteArray(), install pathman_relcache_hook() only once, introduce fini_local_cache()
1 parent 7d45123 commit d18ff3e

File tree

4 files changed

+100
-54
lines changed

4 files changed

+100
-54
lines changed

src/init.c

Lines changed: 47 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,17 @@
4444

4545

4646
/* Storage for PartRelationInfos */
47-
HTAB *partitioned_rels = NULL;
47+
HTAB *partitioned_rels = NULL;
4848

4949
/* Storage for PartParentInfos */
50-
HTAB *parent_cache = NULL;
50+
HTAB *parent_cache = NULL;
5151

52-
bool initialization_needed = true;
52+
bool initialization_needed = true;
53+
static bool relcache_callback_needed = true;
5354

5455

56+
static void init_local_cache(void);
57+
static void fini_local_cache(void);
5558
static void read_pathman_config(void);
5659

5760
static Expr *get_partition_constraint_expr(Oid partition, AttrNumber part_attno);
@@ -80,12 +83,20 @@ static int oid_cmp(const void *p1, const void *p2);
8083
void
8184
load_config(void)
8285
{
83-
/* cache PATHMAN_CONFIG relation Oid */
86+
/* Cache PATHMAN_CONFIG relation Oid */
8487
pathman_config_relid = get_relname_relid(PATHMAN_CONFIG, get_pathman_schema());
8588

86-
init_local_config(); /* create 'relations' hash table */
89+
init_local_cache(); /* create 'partitioned_rels' hash table */
8790
read_pathman_config(); /* read PATHMAN_CONFIG table & fill cache */
8891

92+
/* Register pathman_relcache_hook(), currently we can't unregister it */
93+
if (relcache_callback_needed)
94+
{
95+
CacheRegisterRelcacheCallback(pathman_relcache_hook, PointerGetDatum(NULL));
96+
relcache_callback_needed = false;
97+
}
98+
99+
/* Mark pg_pathman as initialized */
89100
initialization_needed = false;
90101

91102
elog(DEBUG2, "pg_pathman's config has been loaded successfully");
@@ -97,26 +108,12 @@ load_config(void)
97108
void
98109
unload_config(void)
99110
{
100-
HASH_SEQ_STATUS status;
101-
PartRelationInfo *prel;
102-
103-
hash_seq_init(&status, partitioned_rels);
104-
while((prel = (PartRelationInfo *) hash_seq_search(&status)) != NULL)
105-
{
106-
if (PrelIsValid(prel))
107-
{
108-
FreeChildrenArray(prel);
109-
FreeRangesArray(prel);
110-
}
111-
}
112-
113-
/* Now we can safely destroy hash tables */
114-
hash_destroy(partitioned_rels);
115-
hash_destroy(parent_cache);
116-
partitioned_rels = NULL;
117-
parent_cache = NULL;
111+
fini_local_cache(); /* destroy 'partitioned_rels' hash table */
118112

113+
/* Mark pg_pathman as uninitialized */
119114
initialization_needed = true;
115+
116+
elog(DEBUG2, "pg_pathman's config has been unloaded successfully");
120117
}
121118

122119
/*
@@ -131,8 +128,8 @@ estimate_pathman_shmem_size(void)
131128
/*
132129
* Initialize per-process resources.
133130
*/
134-
void
135-
init_local_config(void)
131+
static void
132+
init_local_cache(void)
136133
{
137134
HASHCTL ctl;
138135

@@ -152,8 +149,32 @@ init_local_config(void)
152149
parent_cache = hash_create("pg_pathman's partition parents cache",
153150
PART_RELS_SIZE * CHILD_FACTOR,
154151
&ctl, HASH_ELEM | HASH_BLOBS);
152+
}
153+
154+
/*
155+
* Safely free per-process resources.
156+
*/
157+
static void
158+
fini_local_cache(void)
159+
{
160+
HASH_SEQ_STATUS status;
161+
PartRelationInfo *prel;
155162

156-
CacheRegisterRelcacheCallback(pathman_relcache_hook, PointerGetDatum(NULL));
163+
hash_seq_init(&status, partitioned_rels);
164+
while((prel = (PartRelationInfo *) hash_seq_search(&status)) != NULL)
165+
{
166+
if (PrelIsValid(prel))
167+
{
168+
FreeChildrenArray(prel);
169+
FreeRangesArray(prel);
170+
}
171+
}
172+
173+
/* Now we can safely destroy hash tables */
174+
hash_destroy(partitioned_rels);
175+
hash_destroy(parent_cache);
176+
partitioned_rels = NULL;
177+
parent_cache = NULL;
157178
}
158179

159180
/*

src/init.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ extern bool initialization_needed;
2525

2626

2727
Size estimate_pathman_shmem_size(void);
28-
void init_local_config(void);
2928
void init_shmem_config(void);
3029
void load_config(void);
3130
void unload_config(void);

src/pg_pathman.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -860,7 +860,8 @@ create_partitions_internal(Oid relid, Datum value, Oid value_type)
860860
prel->atttype);
861861

862862
/* Convert interval from CSTRING to 'prel->atttype' */
863-
interval_binary = OidFunctionCall1(typein_proc, value);
863+
interval_binary = OidFunctionCall1(typein_proc,
864+
CStringGetDatum(interval_cstring));
864865
interval_type = prel->atttype;
865866
}
866867

src/worker.c

Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -51,32 +51,51 @@ typedef struct
5151
} PartitionArgs;
5252

5353

54-
#define PackDatumToByteArray(array, datum, datum_size, typbyval) \
55-
do { \
56-
memcpy((void *) (array), \
57-
(const void *) ((typbyval) ? \
58-
(Pointer) (&datum) : \
59-
DatumGetPointer(datum)), \
60-
datum_size); \
61-
} while (0)
6254

6355
/*
64-
* 'typid' is not necessary, but it is used by PrintUnpackedDatum().
56+
* Useful datum packing\unpacking functions for BGW.
6557
*/
66-
#define UnpackDatumFromByteArray(array, datum, datum_size, typbyval, typid) \
67-
do { \
68-
if (typbyval) \
69-
memcpy((void *) &datum, (const void *) array, datum_size); \
70-
else \
71-
{ \
72-
datum = PointerGetDatum(palloc(datum_size)); \
73-
memcpy((void *) DatumGetPointer(datum), \
74-
(const void *) array, \
75-
datum_size); \
76-
} \
77-
elog(LOG, "BGW: arg->value is '%s' [%u]", \
78-
DebugPrintDatum(datum, typid), MyProcPid); \
79-
} while (0)
58+
59+
static void
60+
PackDatumToByteArray(void *byte_array, Datum datum, Size datum_size, bool typbyval)
61+
{
62+
if (typbyval)
63+
/* We have to copy all Datum's bytes */
64+
datum_size = Max(sizeof(Datum), datum_size);
65+
66+
memcpy((void *) byte_array,
67+
(const void *) (typbyval ?
68+
(Pointer) &datum : /* treat Datum as byte array */
69+
DatumGetPointer(datum)), /* extract pointer to data */
70+
datum_size);
71+
}
72+
73+
static void
74+
UnpackDatumFromByteArray(Datum *datum, Size datum_size, bool typbyval,
75+
const void *byte_array)
76+
{
77+
void *dst;
78+
79+
if (typbyval)
80+
{
81+
/* Write Data to Datum directly */
82+
dst = datum;
83+
84+
/* We have to copy all Datum's bytes */
85+
datum_size = Max(sizeof(Datum), datum_size);
86+
}
87+
else
88+
{
89+
/* Allocate space for Datum's internals */
90+
dst = palloc(datum_size);
91+
92+
/* Save pointer to Datum */
93+
*datum = PointerGetDatum(dst);
94+
}
95+
96+
memcpy(dst, byte_array, datum_size);
97+
}
98+
8099

81100

82101
/*
@@ -121,7 +140,7 @@ create_partitions_bg_worker_segment(Oid relid, Datum value, Oid value_type)
121140
args->value_size = datum_size;
122141
args->value_byval = typcache->typbyval;
123142

124-
PackDatumToByteArray(&args->value, value,
143+
PackDatumToByteArray((void *) args->value, value,
125144
datum_size, args->value_byval);
126145

127146
return segment;
@@ -255,10 +274,16 @@ bg_worker_main(Datum main_arg)
255274
bg_worker_load_config(create_partitions_bgw);
256275

257276
/* Upack Datum from segment to 'value' */
258-
UnpackDatumFromByteArray(&args->value, value,
277+
UnpackDatumFromByteArray(&value,
259278
args->value_size,
260279
args->value_byval,
261-
args->value_type);
280+
(const void *) args->value);
281+
282+
#ifdef USE_ASSERT_CHECKING
283+
elog(LOG, "%s: arg->value is '%s' [%u]",
284+
create_partitions_bgw,
285+
DebugPrintDatum(value, args->value_type), MyProcPid);
286+
#endif
262287

263288
/* Create partitions */
264289
args->result = create_partitions_internal(args->partitioned_table,

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