Skip to content

Commit 45b88a5

Browse files
committed
:Merge branch 'pathman_pgpro9_5' of gitlab.postgrespro.ru:pgpro-dev/postgrespro into pathman_pgpro9_5
2 parents 0a927e5 + 4c22dec commit 45b88a5

File tree

8 files changed

+86
-71
lines changed

8 files changed

+86
-71
lines changed

contrib/pg_pathman/expected/pg_pathman.out

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -750,27 +750,8 @@ EXPLAIN (COSTS OFF) SELECT * FROM range_rel WHERE dt > '2010-12-15';
750750
Filter: (dt > 'Wed Dec 15 00:00:00 2010'::timestamp without time zone)
751751
(3 rows)
752752

753-
/* Manual partitions creation */
754-
CREATE TABLE range_rel_archive (CHECK (dt >= '2000-01-01' AND dt < '2005-01-01')) INHERITS (range_rel);
755-
SELECT on_update_partitions('range_rel'::regclass::oid);
756-
on_update_partitions
757-
----------------------
758-
759-
(1 row)
760-
761-
EXPLAIN (COSTS OFF) SELECT * FROM range_rel WHERE dt < '2010-03-01';
762-
QUERY PLAN
763-
-------------------------------------
764-
Append
765-
-> Seq Scan on range_rel_archive
766-
-> Seq Scan on range_rel_15
767-
-> Seq Scan on range_rel_1
768-
-> Seq Scan on range_rel_13
769-
(5 rows)
770-
771753
/* Create range partitions from whole range */
772754
SELECT drop_range_partitions('range_rel');
773-
NOTICE: 0 rows copied from range_rel_archive
774755
NOTICE: 0 rows copied from range_rel_15
775756
NOTICE: 0 rows copied from range_rel_14
776757
NOTICE: 14 rows copied from range_rel_13
@@ -787,7 +768,7 @@ NOTICE: 31 rows copied from range_rel_3
787768
NOTICE: 45 rows copied from range_rel_1
788769
drop_range_partitions
789770
-----------------------
790-
15
771+
14
791772
(1 row)
792773

793774
SELECT create_partitions_from_range('range_rel', 'id', 1, 1000, 100);

contrib/pg_pathman/init.c

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
HTAB *relations = NULL;
1818
HTAB *range_restrictions = NULL;
19-
// bool *config_loaded = NULL;
2019
bool initialization_needed = true;
2120

2221
typedef struct ShmemConfig
@@ -26,6 +25,7 @@ typedef struct ShmemConfig
2625
ShmemConfig *shmem_cfg;
2726

2827
static FmgrInfo *qsort_type_cmp_func;
28+
static bool globalByVal;
2929

3030
static bool validate_range_constraint(Expr *, PartRelationInfo *, Datum *, Datum *);
3131
static bool validate_hash_constraint(Expr *expr, PartRelationInfo *prel, int *hash);
@@ -40,7 +40,6 @@ init_shmem_config()
4040
shmem_cfg = (ShmemConfig *)
4141
ShmemInitStruct("pathman shmem config", sizeof(ShmemConfig), &found);
4242
shmem_cfg->config_loaded = false;
43-
// *config_loaded = false;
4443
}
4544

4645
/*
@@ -60,7 +59,6 @@ load_config(void)
6059
LWLockAcquire(load_config_lock, LW_EXCLUSIVE);
6160
load_relations_hashtable(new_segment_created);
6261
LWLockRelease(load_config_lock);
63-
// *config_loaded = true;
6462
shmem_cfg->config_loaded = true;
6563
}
6664
}
@@ -247,6 +245,7 @@ load_check_constraints(Oid parent_oid, Snapshot snapshot)
247245

248246
if (prel->parttype == PT_RANGE)
249247
{
248+
TypeCacheEntry *tce;
250249
RelationKey key;
251250
key.dbid = MyDatabaseId;
252251
key.relid = parent_oid;
@@ -256,6 +255,9 @@ load_check_constraints(Oid parent_oid, Snapshot snapshot)
256255

257256
alloc_dsm_array(&rangerel->ranges, sizeof(RangeEntry), proc);
258257
ranges = (RangeEntry *) dsm_array_get_pointer(&rangerel->ranges);
258+
259+
tce = lookup_type_cache(prel->atttype, 0);
260+
rangerel->by_val = tce->typbyval;
259261
}
260262

261263
for (i=0; i<proc; i++)
@@ -290,10 +292,19 @@ load_check_constraints(Oid parent_oid, Snapshot snapshot)
290292
continue;
291293
}
292294

295+
/* If datum is referenced by val then just assign */
296+
if (rangerel->by_val)
297+
{
298+
re.min = min;
299+
re.max = max;
300+
}
301+
/* else copy the memory by pointer */
302+
else
303+
{
304+
memcpy(&re.min, DatumGetPointer(min), sizeof(re.min));
305+
memcpy(&re.max, DatumGetPointer(max), sizeof(re.max));
306+
}
293307
re.child_oid = con->conrelid;
294-
re.min = min;
295-
re.max = max;
296-
297308
ranges[i] = re;
298309
break;
299310

@@ -313,11 +324,13 @@ load_check_constraints(Oid parent_oid, Snapshot snapshot)
313324
if (prel->parttype == PT_RANGE)
314325
{
315326
TypeCacheEntry *tce;
327+
bool byVal = rangerel->by_val;
316328

317329
/* Sort ascending */
318330
tce = lookup_type_cache(prel->atttype,
319331
TYPECACHE_CMP_PROC | TYPECACHE_CMP_PROC_FINFO);
320332
qsort_type_cmp_func = &tce->cmp_proc_finfo;
333+
globalByVal = byVal;
321334
qsort(ranges, proc, sizeof(RangeEntry), cmp_range_entries);
322335

323336
/* Copy oids to prel */
@@ -327,7 +340,12 @@ load_check_constraints(Oid parent_oid, Snapshot snapshot)
327340
/* Check if some ranges overlap */
328341
for(i=0; i < proc-1; i++)
329342
{
330-
if (ranges[i].max > ranges[i+1].min)
343+
Datum cur_upper = PATHMAN_GET_DATUM(ranges[i].max, byVal);
344+
Datum next_lower = PATHMAN_GET_DATUM(ranges[i+1].min, byVal);
345+
bool overlap = FunctionCall2(qsort_type_cmp_func, next_lower, cur_upper) > 0;
346+
347+
if (overlap)
348+
// if (ranges[i].max > ranges[i+1].min)
331349
{
332350
RelationKey key;
333351
key.dbid = MyDatabaseId;
@@ -350,7 +368,9 @@ cmp_range_entries(const void *p1, const void *p2)
350368
const RangeEntry *v1 = (const RangeEntry *) p1;
351369
const RangeEntry *v2 = (const RangeEntry *) p2;
352370

353-
return FunctionCall2(qsort_type_cmp_func, v1->min, v2->min);
371+
return FunctionCall2(qsort_type_cmp_func,
372+
PATHMAN_GET_DATUM(v1->min, globalByVal),
373+
PATHMAN_GET_DATUM(v2->min, globalByVal));
354374
}
355375

356376
/*

contrib/pg_pathman/pathman.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,25 @@ typedef struct HashRelation
8282
typedef struct RangeEntry
8383
{
8484
Oid child_oid;
85-
Datum min;
86-
Datum max;
85+
// Datum min;
86+
// Datum max;
87+
#ifdef HAVE_INT64_TIMESTAMP
88+
int64 min;
89+
int64 max;
90+
#else
91+
double min;
92+
double max;
93+
#endif
8794
} RangeEntry;
8895

8996
typedef struct RangeRelation
9097
{
9198
RelationKey key;
99+
bool by_val;
92100
DsmArray ranges;
93101
} RangeRelation;
94102

103+
#define PATHMAN_GET_DATUM(value, by_val) ( (by_val) ? (value) : PointerGetDatum(&value) )
95104

96105
typedef int IndexRange;
97106
#define RANGE_INFINITY 0x7FFF

contrib/pg_pathman/pg_pathman.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,7 @@ handle_binary_opexpr(const PartRelationInfo *prel, WrapperNode *result,
702702
cmp_max,
703703
endidx = rangerel->ranges.length - 1;
704704
RangeEntry *ranges = dsm_array_get_pointer(&rangerel->ranges);
705+
bool byVal = rangerel->by_val;
705706

706707
/* Check boundaries */
707708
if (rangerel->ranges.length == 0)
@@ -712,8 +713,10 @@ handle_binary_opexpr(const PartRelationInfo *prel, WrapperNode *result,
712713
else
713714
{
714715
/* Corner cases */
715-
cmp_min = FunctionCall2(&cmp_func, value, ranges[0].min),
716-
cmp_max = FunctionCall2(&cmp_func, value, ranges[rangerel->ranges.length - 1].max);
716+
cmp_min = FunctionCall2(&cmp_func, value,
717+
PATHMAN_GET_DATUM(ranges[0].min, byVal)),
718+
cmp_max = FunctionCall2(&cmp_func, value,
719+
PATHMAN_GET_DATUM(ranges[rangerel->ranges.length - 1].max, byVal));
717720

718721
if ((cmp_min < 0 &&
719722
(strategy == BTLessEqualStrategyNumber ||
@@ -753,8 +756,9 @@ handle_binary_opexpr(const PartRelationInfo *prel, WrapperNode *result,
753756
i = startidx + (endidx - startidx) / 2;
754757
Assert(i >= 0 && i < rangerel->ranges.length);
755758
re = &ranges[i];
756-
cmp_min = FunctionCall2(&cmp_func, value, re->min);
757-
cmp_max = FunctionCall2(&cmp_func, value, re->max);
759+
cmp_min = FunctionCall2(&cmp_func, value, PATHMAN_GET_DATUM(re->min, byVal));
760+
cmp_max = FunctionCall2(&cmp_func, value, PATHMAN_GET_DATUM(re->max, byVal));
761+
758762
is_less = (cmp_min < 0 || (cmp_min == 0 && strategy == BTLessStrategyNumber));
759763
is_greater = (cmp_max > 0 || (cmp_max >= 0 && strategy != BTLessStrategyNumber));
760764

@@ -854,6 +858,7 @@ range_binary_search(const RangeRelation *rangerel, FmgrInfo *cmp_func, Datum val
854858
{
855859
RangeEntry *ranges = dsm_array_get_pointer(&rangerel->ranges);
856860
RangeEntry *re;
861+
bool byVal = rangerel->by_val;
857862
int cmp_min,
858863
cmp_max,
859864
i = 0,
@@ -866,8 +871,9 @@ range_binary_search(const RangeRelation *rangerel, FmgrInfo *cmp_func, Datum val
866871
*foundPtr = false;
867872

868873
/* Check boundaries */
869-
cmp_min = FunctionCall2(cmp_func, value, ranges[0].min),
870-
cmp_max = FunctionCall2(cmp_func, value, ranges[rangerel->ranges.length - 1].max);
874+
cmp_min = FunctionCall2(cmp_func, value, PATHMAN_GET_DATUM(ranges[0].min, byVal)),
875+
cmp_max = FunctionCall2(cmp_func, value, PATHMAN_GET_DATUM(ranges[rangerel->ranges.length - 1].max, byVal));
876+
871877
if (cmp_min < 0 || cmp_max >0)
872878
{
873879
return i;
@@ -878,8 +884,8 @@ range_binary_search(const RangeRelation *rangerel, FmgrInfo *cmp_func, Datum val
878884
i = startidx + (endidx - startidx) / 2;
879885
Assert(i >= 0 && i < rangerel->ranges.length);
880886
re = &ranges[i];
881-
cmp_min = FunctionCall2(cmp_func, value, re->min);
882-
cmp_max = FunctionCall2(cmp_func, value, re->max);
887+
cmp_min = FunctionCall2(cmp_func, value, PATHMAN_GET_DATUM(re->min, byVal));
888+
cmp_max = FunctionCall2(cmp_func, value, PATHMAN_GET_DATUM(re->max, byVal));
883889

884890
if (cmp_min >= 0 && cmp_max < 0)
885891
{

contrib/pg_pathman/pl_funcs.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,11 @@ get_partition_range(PG_FUNCTION_ARGS)
204204

205205
if (found)
206206
{
207+
bool byVal = rangerel->by_val;
208+
207209
elems = palloc(nelems * sizeof(Datum));
208-
elems[0] = ranges[i].min;
209-
elems[1] = ranges[i].max;
210+
elems[0] = PATHMAN_GET_DATUM(ranges[i].min, byVal);
211+
elems[1] = PATHMAN_GET_DATUM(ranges[i].max, byVal);
210212

211213
arr = construct_array(elems, nelems, prel->atttype,
212214
tce->typlen, tce->typbyval, tce->typalign);
@@ -251,8 +253,8 @@ get_range_by_idx(PG_FUNCTION_ARGS)
251253
re = &ranges[rangerel->ranges.length - 1];
252254

253255
elems = palloc(2 * sizeof(Datum));
254-
elems[0] = re->min;
255-
elems[1] = re->max;
256+
elems[0] = PATHMAN_GET_DATUM(re->min, rangerel->by_val);
257+
elems[1] = PATHMAN_GET_DATUM(re->max, rangerel->by_val);
256258

257259
PG_RETURN_ARRAYTYPE_P(
258260
construct_array(elems, 2, prel->atttype,
@@ -277,7 +279,7 @@ get_min_range_value(PG_FUNCTION_ARGS)
277279
PG_RETURN_NULL();
278280

279281
ranges = dsm_array_get_pointer(&rangerel->ranges);
280-
PG_RETURN_DATUM(ranges[0].min);
282+
PG_RETURN_DATUM(PATHMAN_GET_DATUM(ranges[0].min, rangerel->by_val));
281283
}
282284

283285
/*
@@ -298,7 +300,7 @@ get_max_range_value(PG_FUNCTION_ARGS)
298300
PG_RETURN_NULL();
299301

300302
ranges = dsm_array_get_pointer(&rangerel->ranges);
301-
PG_RETURN_DATUM(ranges[rangerel->ranges.length-1].max);
303+
PG_RETURN_DATUM(PATHMAN_GET_DATUM(ranges[rangerel->ranges.length-1].max, rangerel->by_val));
302304
}
303305

304306
/*

contrib/pg_pathman/range.sql

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,6 @@ BEGIN
4747
END LOOP;
4848
END IF;
4949

50-
/* TODO: think about reusing code */
51-
-- EXECUTE format('SELECT @extschema@.create_partitions_from_range(''%s'', ''%s'', ''%s'', ''%s''::%s, ''%s''::interval)'
52-
-- , p_relation
53-
-- , p_attribute
54-
-- , p_start_value
55-
-- , p_start_value + p_interval*p_count
56-
-- , pg_typeof(p_start_value)
57-
-- , p_interval);
58-
59-
-- RETURN p_count;
60-
6150
/* Check boundaries */
6251
EXECUTE format('SELECT @extschema@.check_boundaries(''%s'', ''%s'', ''%s'', ''%s''::%s)'
6352
, p_relation
@@ -778,8 +767,8 @@ BEGIN
778767

779768
IF @extschema@.is_date(p_atttype::regtype) THEN
780769
v_part_name := @extschema@.create_single_range_partition(p_relation
781-
, p_range[1]
782-
, p_range[1] - p_interval::interval);
770+
, p_range[1] - p_interval::interval
771+
, p_range[1]);
783772
ELSE
784773
EXECUTE format('SELECT @extschema@.create_single_range_partition($1, $2, $2 - $3::%s)', p_atttype)
785774
USING p_relation, p_range[1], p_interval

contrib/pg_pathman/sql/pg_pathman.sql

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,6 @@ SELECT prepend_range_partition('range_rel');
182182
EXPLAIN (COSTS OFF) SELECT * FROM range_rel WHERE dt < '2010-03-01';
183183
EXPLAIN (COSTS OFF) SELECT * FROM range_rel WHERE dt > '2010-12-15';
184184

185-
/* Manual partitions creation */
186-
CREATE TABLE range_rel_archive (CHECK (dt >= '2000-01-01' AND dt < '2005-01-01')) INHERITS (range_rel);
187-
SELECT on_update_partitions('range_rel'::regclass::oid);
188-
EXPLAIN (COSTS OFF) SELECT * FROM range_rel WHERE dt < '2010-03-01';
189-
190185
/* Create range partitions from whole range */
191186
SELECT drop_range_partitions('range_rel');
192187
SELECT create_partitions_from_range('range_rel', 'id', 1, 1000, 100);

contrib/pg_pathman/worker.c

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "storage/dsm.h"
77
#include "access/xact.h"
88
#include "utils/snapmgr.h"
9+
#include "utils/typcache.h"
910

1011
/*-------------------------------------------------------------------------
1112
*
@@ -22,15 +23,19 @@
2223
static dsm_segment *segment;
2324

2425
static void bg_worker_main(Datum main_arg);
25-
// static Oid create_partitions(Oid relid, Datum value, Oid value_type);
2626

2727
typedef struct PartitionArgs
2828
{
29-
Oid dbid;
30-
Oid relid;
31-
Datum value;
32-
Oid value_type;
33-
Oid result;
29+
Oid dbid;
30+
Oid relid;
31+
#ifdef HAVE_INT64_TIMESTAMP
32+
int64 value;
33+
#else
34+
double value;
35+
#endif
36+
Oid value_type;
37+
bool by_val;
38+
Oid result;
3439
} PartitionArgs;
3540

3641
/*
@@ -46,17 +51,25 @@ create_partitions_bg_worker(Oid relid, Datum value, Oid value_type)
4651
dsm_segment *segment;
4752
dsm_handle segment_handle;
4853
pid_t pid;
49-
PartitionArgs *args;
54+
PartitionArgs *args;
5055
Oid child_oid;
56+
TypeCacheEntry *tce;
5157

5258
/* Create a dsm segment for the worker to pass arguments */
5359
segment = dsm_create(sizeof(PartitionArgs), 0);
5460
segment_handle = dsm_segment_handle(segment);
5561

62+
tce = lookup_type_cache(value_type, 0);
63+
64+
/* Fill arguments structure */
5665
args = (PartitionArgs *) dsm_segment_address(segment);
5766
args->dbid = MyDatabaseId;
5867
args->relid = relid;
59-
args->value = value;
68+
if (tce->typbyval)
69+
args->value = value;
70+
else
71+
memcpy(&args->value, DatumGetPointer(value), sizeof(args->value));
72+
args->by_val = tce->typbyval;
6073
args->value_type = value_type;
6174
args->result = 0;
6275

@@ -121,7 +134,7 @@ bg_worker_main(Datum main_arg)
121134
PushActiveSnapshot(GetTransactionSnapshot());
122135

123136
/* Create partitions */
124-
args->result = create_partitions(args->relid, args->value, args->value_type);
137+
args->result = create_partitions(args->relid, PATHMAN_GET_DATUM(args->value, args->by_val), args->value_type);
125138

126139
/* Cleanup */
127140
SPI_finish();

0 commit comments

Comments
 (0)