Skip to content

Commit ee432b0

Browse files
committed
Merge branch 'picky_nodes' into merge_concurrent
2 parents cf4c9d5 + 4efb205 commit ee432b0

File tree

11 files changed

+124
-89
lines changed

11 files changed

+124
-89
lines changed

src/hooks.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@
1212
#include "init.h"
1313
#include "runtimeappend.h"
1414
#include "runtime_merge_append.h"
15+
#include "partition_filter.h"
1516
#include "utils.h"
1617

1718
#include "miscadmin.h"
1819
#include "optimizer/cost.h"
1920
#include "optimizer/restrictinfo.h"
20-
#include "partition_filter.h"
21+
#include "utils/typcache.h"
2122

2223

2324
set_join_pathlist_hook_type set_join_pathlist_next = NULL;

src/init.c

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020
#include "access/htup_details.h"
2121
#include "access/sysattr.h"
2222
#include "catalog/indexing.h"
23+
#include "catalog/pg_constraint.h"
24+
#include "catalog/pg_inherits.h"
2325
#include "catalog/pg_inherits_fn.h"
2426
#include "catalog/pg_type.h"
25-
#include "catalog/pg_inherits.h"
26-
#include "catalog/pg_constraint.h"
2727
#include "executor/spi.h"
2828
#include "miscadmin.h"
2929
#include "optimizer/clauses.h"
@@ -81,22 +81,22 @@ static int oid_cmp(const void *p1, const void *p2);
8181

8282
/*
8383
* Create local PartRelationInfo cache & load pg_pathman's config.
84+
* Return true on success. May occasionally emit ERROR.
8485
*/
85-
void
86+
bool
8687
load_config(void)
8788
{
88-
elog(DEBUG2, "pg_pathman's config!!! [%u]", MyProcPid);
89-
90-
/*
89+
/*
9190
* Try to cache important relids.
92-
*
91+
*
9392
* Once CREATE EXTENSION stmt is processed, get_pathman_schema()
94-
* function starts to return perfectly valid schema Oid, which
95-
* means we have to check that ALL pg_pathman's relations' Oids
96-
* have been cached properly.
93+
* function starts returning perfectly valid schema Oid, which
94+
* means we have to check that *ALL* pg_pathman's relations' Oids
95+
* have been cached properly. Only then can we assume that
96+
* initialization is not needed anymore.
9797
*/
9898
if (!init_pathman_relation_oids())
99-
return; /* remain 'uninitialized', exit */
99+
return false; /* remain 'uninitialized', exit before creating main caches */
100100

101101
init_local_cache(); /* create 'partitioned_rels' hash table */
102102
read_pathman_config(); /* read PATHMAN_CONFIG table & fill cache */
@@ -112,6 +112,8 @@ load_config(void)
112112
initialization_needed = false;
113113

114114
elog(DEBUG2, "pg_pathman's config has been loaded successfully [%u]", MyProcPid);
115+
116+
return true;
115117
}
116118

117119
/*
@@ -123,7 +125,8 @@ unload_config(void)
123125
/* Don't forget to reset pg_pathman's cached relids */
124126
fini_pathman_relation_oids();
125127

126-
fini_local_cache(); /* destroy 'partitioned_rels' hash table */
128+
/* Destroy 'partitioned_rels' & 'parent_cache' hash tables */
129+
fini_local_cache();
127130

128131
/* Mark pg_pathman as uninitialized */
129132
initialization_needed = true;
@@ -143,36 +146,42 @@ estimate_pathman_shmem_size(void)
143146
}
144147

145148
/*
146-
* TODO: write some comment;
149+
* Cache *all* important pg_pathman's relids at once.
150+
* We should NOT rely on any previously cached values.
147151
*/
148152
static bool
149153
init_pathman_relation_oids(void)
150154
{
151155
Oid schema = get_pathman_schema();
156+
Assert(schema != InvalidOid);
152157

153158
/* Cache PATHMAN_CONFIG relation's Oid */
154-
pathman_config_params_relid = get_relname_relid(PATHMAN_CONFIG_PARAMS,
155-
schema);
156159
pathman_config_relid = get_relname_relid(PATHMAN_CONFIG, schema);
160+
if (pathman_config_relid == InvalidOid)
161+
return false;
157162

158-
/* Return false if any relation doesn't exist yet */
159-
if (pathman_config_params_relid == InvalidOid ||
160-
pathman_config_relid == InvalidOid)
161-
{
163+
/* Cache PATHMAN_CONFIG_PARAMS relation's Oid */
164+
pathman_config_params_relid = get_relname_relid(PATHMAN_CONFIG_PARAMS,
165+
schema);
166+
if (pathman_config_params_relid == InvalidOid)
162167
return false;
163-
}
164168

169+
/* NOTE: add more relations to be cached right here ^^^ */
170+
171+
/* Everything is fine, proceed */
165172
return true;
166173
}
167174

168175
/*
169-
* TODO: write some comment;
176+
* Forget *all* pg_pathman's cached relids.
170177
*/
171178
static void
172179
fini_pathman_relation_oids(void)
173180
{
174181
pathman_config_relid = InvalidOid;
175182
pathman_config_params_relid = InvalidOid;
183+
184+
/* NOTE: add more relations to be forgotten right here ^^^ */
176185
}
177186

178187
/*

src/init.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ extern bool initialization_needed;
2626

2727
Size estimate_pathman_shmem_size(void);
2828
void init_shmem_config(void);
29-
void load_config(void);
29+
bool load_config(void);
3030
void unload_config(void);
3131
Size get_worker_slots_size(void);
3232
void create_worker_slots(void);

src/pathman.h

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,11 @@
1111
#ifndef PATHMAN_H
1212
#define PATHMAN_H
1313

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

1918
#include "postgres.h"
20-
#include "utils/date.h"
21-
#include "utils/snapshot.h"
22-
#include "utils/typcache.h"
2319
#include "nodes/makefuncs.h"
2420
#include "nodes/primnodes.h"
2521
#include "nodes/execnodes.h"
@@ -28,16 +24,18 @@
2824

2925

3026
/* Check PostgreSQL version (9.5.4 contains an important fix for BGW) */
31-
// #if PG_VERSION_NUM < 90504
32-
// #error "Cannot build pg_pathman with PostgreSQL version lower than 9.5.4"
33-
// #endif
27+
#if PG_VERSION_NUM < 90503
28+
#error "Cannot build pg_pathman with PostgreSQL version lower than 9.5.3"
29+
#elif PG_VERSION_NUM < 90504
30+
#warning "It is STRONGLY recommended to use pg_pathman with PostgreSQL 9.5.4 since it contains important fixes"
31+
#endif
3432

3533
/* Get CString representation of Datum (simple wrapper) */
3634
#ifdef USE_ASSERT_CHECKING
37-
#include "utils.h"
38-
#define DebugPrintDatum(datum, typid) ( datum_to_cstring((datum), (typid)) )
35+
#include "utils.h"
36+
#define DebugPrintDatum(datum, typid) ( datum_to_cstring((datum), (typid)) )
3937
#else
40-
#define DebugPrintDatum(datum, typid) ( "[use --enable-cassert]" )
38+
#define DebugPrintDatum(datum, typid) ( "[use --enable-cassert]" )
4139
#endif
4240

4341

src/pg_pathman.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "utils/syscache.h"
4242
#include "utils/selfuncs.h"
4343
#include "utils/snapmgr.h"
44+
#include "utils/typcache.h"
4445

4546

4647
PG_MODULE_MAGIC;
@@ -814,9 +815,11 @@ create_partitions_internal(Oid relid, Datum value, Oid value_type)
814815
Datum values[Natts_pathman_config];
815816
bool isnull[Natts_pathman_config];
816817

818+
prel = get_pathman_relation_info(relid);
819+
shout_if_prel_is_invalid(relid, prel, PT_RANGE);
820+
817821
/* Get both PartRelationInfo & PATHMAN_CONFIG contents for this relation */
818-
if ((prel = get_pathman_relation_info(relid)) != NULL &&
819-
pathman_config_contains_relation(relid, values, isnull, NULL))
822+
if (pathman_config_contains_relation(relid, values, isnull, NULL))
820823
{
821824
Datum min_rvalue,
822825
max_rvalue;
@@ -828,10 +831,6 @@ create_partitions_internal(Oid relid, Datum value, Oid value_type)
828831

829832
FmgrInfo interval_type_cmp;
830833

831-
if (prel->parttype != PT_RANGE)
832-
elog(ERROR, "Relation \"%s\" is not partitioned by RANGE",
833-
get_rel_name_or_relid(relid));
834-
835834
/* Fill the FmgrInfo struct with a cmp(value, part_attribute) function */
836835
fill_type_cmp_fmgr_info(&interval_type_cmp, value_type, prel->atttype);
837836

@@ -893,7 +892,7 @@ create_partitions_internal(Oid relid, Datum value, Oid value_type)
893892
SPI_finish(); /* close SPI connection */
894893
}
895894
else
896-
elog(ERROR, "Relation \"%s\" is not partitioned by pg_pathman",
895+
elog(ERROR, "pg_pathman's config does not contain relation \"%s\"",
897896
get_rel_name_or_relid(relid));
898897
}
899898
PG_CATCH();
@@ -932,7 +931,8 @@ create_partitions(Oid relid, Datum value, Oid value_type)
932931
if (pathman_config_contains_relation(relid, NULL, NULL, &rel_xmin))
933932
{
934933
/* If table was partitioned in some previous xact, run BGWorker */
935-
if (TransactionIdPrecedes(rel_xmin, GetCurrentTransactionId()))
934+
if (TransactionIdPrecedes(rel_xmin, GetCurrentTransactionId()) ||
935+
TransactionIdEquals(rel_xmin, FrozenTransactionId))
936936
{
937937
elog(DEBUG2, "create_partitions(): chose BGW [%u]", MyProcPid);
938938
last_partition = create_partitions_bg_worker(relid, value, value_type);
@@ -1179,6 +1179,9 @@ handle_binary_opexpr(WalkerContext *context, WrapperNode *result,
11791179
result);
11801180
return;
11811181
}
1182+
1183+
default:
1184+
elog(ERROR, "Unknown partitioning type %u", prel->parttype);
11821185
}
11831186

11841187
result->rangeset = list_make1_irange(make_irange(0,

src/pl_funcs.c

Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -220,14 +220,12 @@ find_or_create_range_partition(PG_FUNCTION_ARGS)
220220
search_rangerel_result search_state;
221221

222222
prel = get_pathman_relation_info(parent_oid);
223-
224-
if (!prel)
225-
PG_RETURN_NULL();
223+
shout_if_prel_is_invalid(parent_oid, prel, PT_RANGE);
226224

227225
fill_type_cmp_fmgr_info(&cmp_func, value_type, prel->atttype);
228226

229-
/* FIXME: does this function even work? */
230-
search_state = search_range_partition_eq(value, &cmp_func,prel,
227+
/* Use available PartRelationInfo to find partition */
228+
search_state = search_range_partition_eq(value, &cmp_func, prel,
231229
&found_rentry);
232230

233231
/*
@@ -286,9 +284,7 @@ get_range_by_part_oid(PG_FUNCTION_ARGS)
286284
const PartRelationInfo *prel;
287285

288286
prel = get_pathman_relation_info(parent_oid);
289-
if (!prel)
290-
elog(ERROR, "Relation \"%s\" is not partitioned by pg_pathman",
291-
get_rel_name_or_relid(parent_oid));
287+
shout_if_prel_is_invalid(parent_oid, prel, PT_RANGE);
292288

293289
ranges = PrelGetRangesArray(prel);
294290

@@ -306,6 +302,7 @@ get_range_by_part_oid(PG_FUNCTION_ARGS)
306302
PG_RETURN_ARRAYTYPE_P(arr);
307303
}
308304

305+
/* No partition found, report error */
309306
elog(ERROR, "Relation \"%s\" has no partition \"%s\"",
310307
get_rel_name_or_relid(parent_oid),
311308
get_rel_name_or_relid(child_oid));
@@ -330,9 +327,7 @@ get_range_by_idx(PG_FUNCTION_ARGS)
330327
const PartRelationInfo *prel;
331328

332329
prel = get_pathman_relation_info(parent_oid);
333-
if (!prel)
334-
elog(ERROR, "Relation \"%s\" is not partitioned by pg_pathman",
335-
get_rel_name_or_relid(parent_oid));
330+
shout_if_prel_is_invalid(parent_oid, prel, PT_RANGE);
336331

337332
if (((uint32) abs(idx)) >= PrelChildrenCount(prel))
338333
elog(ERROR, "Partition #%d does not exist (total amount is %u)",
@@ -366,14 +361,7 @@ get_min_range_value(PG_FUNCTION_ARGS)
366361
const PartRelationInfo *prel;
367362

368363
prel = get_pathman_relation_info(parent_oid);
369-
if (!prel)
370-
elog(ERROR, "Relation \"%s\" is not partitioned by pg_pathman",
371-
get_rel_name_or_relid(parent_oid));
372-
373-
if (prel->parttype != PT_RANGE)
374-
if (!prel)
375-
elog(ERROR, "Relation \"%s\" is not partitioned by RANGE",
376-
get_rel_name_or_relid(parent_oid));
364+
shout_if_prel_is_invalid(parent_oid, prel, PT_RANGE);
377365

378366
ranges = PrelGetRangesArray(prel);
379367

@@ -391,14 +379,7 @@ get_max_range_value(PG_FUNCTION_ARGS)
391379
const PartRelationInfo *prel;
392380

393381
prel = get_pathman_relation_info(parent_oid);
394-
if (!prel)
395-
elog(ERROR, "Relation \"%s\" is not partitioned by pg_pathman",
396-
get_rel_name_or_relid(parent_oid));
397-
398-
if (prel->parttype != PT_RANGE)
399-
if (!prel)
400-
elog(ERROR, "Relation \"%s\" is not partitioned by RANGE",
401-
get_rel_name_or_relid(parent_oid));
382+
shout_if_prel_is_invalid(parent_oid, prel, PT_RANGE);
402383

403384
ranges = PrelGetRangesArray(prel);
404385

@@ -428,14 +409,7 @@ check_overlap(PG_FUNCTION_ARGS)
428409
const PartRelationInfo *prel;
429410

430411
prel = get_pathman_relation_info(parent_oid);
431-
if (!prel)
432-
elog(ERROR, "Relation \"%s\" is not partitioned by pg_pathman",
433-
get_rel_name_or_relid(parent_oid));
434-
435-
if (prel->parttype != PT_RANGE)
436-
if (!prel)
437-
elog(ERROR, "Relation \"%s\" is not partitioned by RANGE",
438-
get_rel_name_or_relid(parent_oid));
412+
shout_if_prel_is_invalid(parent_oid, prel, PT_RANGE);
439413

440414
/* comparison functions */
441415
fill_type_cmp_fmgr_info(&cmp_func_1, p1_type, prel->atttype);

src/relation_info.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "utils/lsyscache.h"
2525
#include "utils/memutils.h"
2626
#include "utils/snapmgr.h"
27+
#include "utils/typcache.h"
2728

2829

2930
/*

src/relation_info.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@
1919

2020

2121
/*
22-
* Partitioning type
22+
* Partitioning type.
2323
*/
2424
typedef enum
2525
{
26-
PT_HASH = 1,
26+
PT_INDIFFERENT = 0, /* for part type traits (virtual type) */
27+
PT_HASH,
2728
PT_RANGE
2829
} PartType;
2930

0 commit comments

Comments
 (0)