Skip to content

Commit aec8e37

Browse files
committed
pathman: rangeset added
1 parent 4c9a964 commit aec8e37

File tree

5 files changed

+215
-47
lines changed

5 files changed

+215
-47
lines changed

contrib/pathman/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# contrib/pathman/Makefile
22

33
MODULE_big = pathman
4-
OBJS = init.o pathman.o dsm_array.o $(WIN32RES)
4+
OBJS = init.o pathman.o dsm_array.o rangeset.o $(WIN32RES)
55

66
EXTENSION = pathman
77
EXTVERSION = 0.1

contrib/pathman/dsm_array.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ alloc_dsm_table()
1919

2020
void create_dsm_segment(size_t block_size)
2121
{
22-
bool foundPtr;
22+
// bool foundPtr;
2323
dsm_handle handle;
2424

2525
/* lock here */

contrib/pathman/pathman.c

Lines changed: 93 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ my_hook(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTblEntry *rte)
160160
if (prel != NULL)
161161
{
162162
List *children = NIL;
163+
List *ranges;
163164
ListCell *lc;
164165
int childOID = -1;
165166
int i;
@@ -168,22 +169,33 @@ my_hook(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTblEntry *rte)
168169
rte->inh = true;
169170

170171
dsm_arr = (Oid *) dsm_array_get_pointer(&prel->children);
171-
for (i=0; i<prel->children_count; i++)
172-
// children = lappend_int(children, prel->children[i]);
173-
children = lappend_int(children, dsm_arr[i]);
172+
// for (i=0; i<prel->children_count; i++)
173+
// // children = lappend_int(children, prel->children[i]);
174+
// children = lappend_int(children, dsm_arr[i]);
175+
176+
ranges = list_make1_int(make_range(0, prel->children_count-1));
174177

175178
/* Run over restrictions and collect children partitions */
176179
ereport(LOG, (errmsg("Checking restrictions")));
177180
foreach(lc, rel->baserestrictinfo)
178181
{
179182
RestrictInfo *rinfo = (RestrictInfo*) lfirst(lc);
180-
List *ret = walk_expr_tree(rinfo->clause, prel);
183+
List *ret = walk_expr_tree(rinfo->clause, prel, &all);
184+
ranges = intersect_ranges(ranges, ret);
185+
186+
// if (!all)
187+
// {
188+
// children = list_intersection_int(children, ret);
189+
// list_free(ret);
190+
// }
191+
}
181192

182-
if (ret != ALL)
183-
{
184-
children = list_intersection_int(children, ret);
185-
list_free(ret);
186-
}
193+
foreach(lc, ranges)
194+
{
195+
int i;
196+
IndexRange range = (IndexRange) lfirst(lc);
197+
for (i=range_min(range); i<=range_max(range); i++)
198+
children = lappend_int(children, dsm_arr[i]);
187199
}
188200

189201
// if (children == NIL)
@@ -339,6 +351,9 @@ append_child_relation(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTblEnt
339351

340352
childrel->baserestrictinfo = lappend(childrel->baserestrictinfo,
341353
new_rinfo);
354+
355+
/* TODO: temporarily commented out */
356+
// reconstruct_restrictinfo((Node *) new_rinfo, prel, childOID);
342357
}
343358

344359
/* Build an AppendRelInfo for this parent and child */
@@ -477,14 +492,20 @@ handle_binary_opexpr(const PartRelationInfo *prel, const OpExpr *expr,
477492
{
478493
int_value = DatumGetInt32(c->constvalue);
479494
key.hash = make_hash(prel, int_value);
480-
key.parent_oid = prel->oid;
481-
hashrel = (HashRelation *)
482-
hash_search(hash_restrictions, (const void *)&key, HASH_FIND, NULL);
483-
484-
if (hashrel != NULL)
485-
return list_make1_int(hashrel->child_oid);
486-
else
487-
return ALL;
495+
496+
return list_make1_int(make_range(key.hash, key.hash));
497+
498+
// key.parent_oid = prel->oid;
499+
// hashrel = (HashRelation *)
500+
// hash_search(hash_restrictions, (const void *)&key, HASH_FIND, NULL);
501+
502+
// if (hashrel != NULL)
503+
// return list_make1_int(hashrel->child_oid);
504+
// else
505+
// {
506+
// *all = true;
507+
// return NIL;
508+
// }
488509
}
489510
case PT_RANGE:
490511
value = c->constvalue;
@@ -493,7 +514,7 @@ handle_binary_opexpr(const PartRelationInfo *prel, const OpExpr *expr,
493514
if (rangerel != NULL)
494515
{
495516
RangeEntry *re;
496-
List *children = NIL;
517+
// List *children = NIL;
497518
bool found = false;
498519
startidx = 0;
499520
int counter = 0;
@@ -557,21 +578,24 @@ handle_binary_opexpr(const PartRelationInfo *prel, const OpExpr *expr,
557578
startidx = 0;
558579
endidx = i;
559580
break;
560-
case OP_STRATEGY_EQ:
561-
return list_make1_int(re->child_oid);
562-
case OP_STRATEGY_GE:
581+
case BTEqualStrategyNumber:
582+
// return list_make1_int(re->child_oid);
583+
// return list_make1_int(make_range(prel->oid, prel->oid));
584+
return list_make1_int(make_range(i, i));
585+
case BTGreaterEqualStrategyNumber:
563586
startidx = i;
564587
endidx = rangerel->nranges-1;
565588
break;
566589
case OP_STRATEGY_GT:
567590
startidx = (re->max == value) ? i+1 : i;
568591
endidx = rangerel->nranges-1;
569592
}
570-
for (j=startidx; j<=endidx; j++)
571-
children = lappend_int(children, ranges[j].child_oid);
572-
593+
// for (j=startidx; j<=endidx; j++)
594+
// children = lappend_int(children, ranges[j].child_oid);
573595
*all = false;
574-
return children;
596+
return list_make1_int(make_range(startidx, endidx));
597+
598+
// return children;
575599
}
576600
}
577601
}
@@ -630,22 +654,46 @@ handle_boolexpr(const BoolExpr *expr, const PartRelationInfo *prel)
630654
b = walk_expr_tree((Expr*)lfirst(lc), prel);
631655
switch(expr->boolop)
632656
{
657+
// case OR_EXPR:
658+
// if (sub_all)
659+
// {
660+
// list_free(ret);
661+
// ret = NIL;
662+
663+
// /*
664+
// * if at least one subexpr returns all partitions then
665+
// * the whole OR-expression does
666+
// */
667+
// *all = true;
668+
669+
// /* so we just could return here */
670+
// return ret;
671+
// }
672+
// else
673+
// {
674+
// ret = list_concat_unique_int(ret, b);
675+
// list_free(b);
676+
// }
677+
// break;
678+
// case AND_EXPR:
679+
// ret = list_intersection_int(ret, b);
680+
// list_free(b);
681+
682+
// /*
683+
// * if even one subexpr doesn't return all partitions then
684+
// * the whole AND-expression doesn't.
685+
// */
686+
// if (!sub_all)
687+
// all = false;
688+
// break;
689+
633690
case OR_EXPR:
634-
if (b == ALL)
635-
{
636-
list_free(ret);
637-
ret = ALL;
638-
}
639-
else
640-
{
641-
ret = list_concat_unique_int(ret, b);
642-
list_free(b);
643-
b = ALL;
644-
}
691+
ret = unite_ranges(ret, b);
692+
// list_free(b);
645693
break;
646694
case AND_EXPR:
647-
ret = list_intersection_int(ret, b);
648-
list_free(b);
695+
ret = intersect_ranges(ret, b);
696+
// list_free(b);
649697
break;
650698
default:
651699
break;
@@ -695,13 +743,14 @@ handle_arrexpr(const ScalarArrayOpExpr *expr, const PartRelationInfo *prel)
695743
for (i=0; i<num_elems; i++)
696744
{
697745
key.hash = make_hash(prel, elem_values[i]);
698-
key.parent_oid = prel->oid;
699-
hashrel = (HashRelation *)
700-
hash_search(hash_restrictions, (const void *)&key, HASH_FIND, NULL);
746+
// key.parent_oid = prel->oid;
747+
// hashrel = (HashRelation *)
748+
// hash_search(hash_restrictions, (const void *)&key, HASH_FIND, NULL);
701749

702-
if (hashrel != NULL)
703-
oids = list_append_unique_int(oids, hashrel->child_oid);
750+
// if (hashrel != NULL)
751+
// oids = list_append_unique_int(oids, hashrel->child_oid);
704752

753+
oids = list_append_unique_int(oids, make_range(key.hash, key.hash));
705754
}
706755

707756
/* free resources */
@@ -829,7 +878,7 @@ accumulate_append_subpath(List *subpaths, Path *path)
829878
*/
830879
Datum
831880
on_partitions_created(PG_FUNCTION_ARGS) {
832-
Oid relid;
881+
// Oid relid;
833882

834883
LWLockAcquire(load_config_lock, LW_EXCLUSIVE);
835884

@@ -866,7 +915,6 @@ on_partitions_updated(PG_FUNCTION_ARGS) {
866915
Datum
867916
on_partitions_removed(PG_FUNCTION_ARGS) {
868917
Oid relid;
869-
int i;
870918

871919
LWLockAcquire(load_config_lock, LW_EXCLUSIVE);
872920

contrib/pathman/pathman.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "postgres.h"
22
#include "utils/date.h"
33
#include "utils/hsearch.h"
4+
#include "nodes/pg_list.h"
45
#include "storage/dsm.h"
56
#include "storage/lwlock.h"
67

@@ -131,6 +132,25 @@ typedef struct RangeRelation
131132
} RangeRelation;
132133

133134

135+
typedef int IndexRange;
136+
#define RANGE_INFINITY 0xFFFF
137+
138+
#define make_range(min, max) \
139+
((min) << 16 | ((max) & 0x0000FFFF))
140+
141+
#define range_min(range) \
142+
((range) >> 16)
143+
144+
#define range_max(range) \
145+
((range) & 0x0000FFFF)
146+
147+
// Range make_range(int min, int max);
148+
// int range_min(Range range);
149+
// int range_max(Range range);
150+
List *append_range(List *a_lst, IndexRange b);
151+
List *intersect_ranges(List *a, List *b);
152+
List *unite_ranges(List *a, List *b);
153+
134154
LWLock *load_config_lock;
135155
LWLock *dsm_init_lock;
136156

contrib/pathman/rangeset.c

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#include "pathman.h"
2+
3+
4+
// Range
5+
// make_range(int min, int max)
6+
// {
7+
// return min << 16 | (max & 0x0000FFFF);
8+
// }
9+
10+
// int
11+
// range_min(IndexRange range)
12+
// {
13+
// return range >> 16;
14+
// }
15+
16+
// int
17+
// range_max(IndexRange range)
18+
// {
19+
// return range & 0x0000FFFF;
20+
// }
21+
22+
List *
23+
unite_ranges(List *a, List *b)
24+
{
25+
ListCell *lc;
26+
27+
foreach(lc, b)
28+
{
29+
IndexRange r = (IndexRange)lfirst_int(lc);
30+
a = append_range(a, r);
31+
}
32+
return a;
33+
}
34+
35+
List *
36+
append_range(List *a_lst, IndexRange b)
37+
{
38+
ListCell *lc;
39+
int low, high;
40+
bool merged = false;
41+
42+
foreach(lc, a_lst)
43+
{
44+
// IndexRange &ra = (IndexRange)lfirst_int(lc);
45+
IndexRange *a = &(lfirst_int(lc));
46+
47+
/* if ranges overlay then merge them */
48+
if (range_min(*a) <= range_max(b) && range_max(*a) >= range_min(b))
49+
{
50+
low = (range_min(*a) < range_min(b)) ? range_min(*a) : range_min(b);
51+
high = (range_max(*a) >= range_max(b)) ? range_max(*a) : range_max(b);
52+
*a = make_range(low, high);
53+
merged = true;
54+
break;
55+
}
56+
}
57+
58+
/* if ranges not merged then append range */
59+
if (!merged)
60+
a_lst = lappend_int(a_lst, b);
61+
62+
return a_lst;
63+
}
64+
65+
List *
66+
intersect_ranges(List *a, List *b)
67+
{
68+
ListCell *lca;
69+
ListCell *lcb;
70+
List *new_list = NIL;
71+
int low, high;
72+
73+
foreach(lcb, b)
74+
{
75+
IndexRange rb = (IndexRange)lfirst_int(lcb);
76+
77+
/* if "a" is empty then initialize it with infinite range */
78+
if (a == NIL)
79+
a = list_make1_int(make_range(0, RANGE_INFINITY));
80+
81+
/* intersect entry from "b" and every entry in "a" */
82+
foreach(lca, a)
83+
{
84+
IndexRange ra = (IndexRange)lfirst_int(lca);
85+
86+
/* if ranges doesn't overlay */
87+
if (range_min(ra) > range_max(rb) || range_max(ra) < range_min(rb))
88+
continue;
89+
90+
low = (range_min(ra) < range_min(rb)) ? range_min(rb) : range_min(ra);
91+
high = (range_max(ra) >= range_max(rb)) ? range_max(rb) : range_max(ra);
92+
93+
new_list = lappend_int(new_list, make_range(low, high));
94+
}
95+
}
96+
pfree(a);
97+
pfree(b);
98+
99+
return new_list;
100+
}

0 commit comments

Comments
 (0)