Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita682742

Browse files
committed
half open ranges
1 parentfc9d807 commita682742

File tree

9 files changed

+126
-67
lines changed

9 files changed

+126
-67
lines changed

‎expected/pathman_calamity.out‎

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -238,22 +238,6 @@ EXPLAIN (COSTS OFF) SELECT * FROM calamity.part_ok; /* check that pathman is ena
238238
-> Seq Scan on part_ok_3
239239
(5 rows)
240240

241-
ALTER TABLE calamity.wrong_partition
242-
ADD CONSTRAINT pathman_wrong_partition_1_check
243-
CHECK (val < 10); /* wrong constraint */
244-
SELECT add_to_pathman_config('calamity.part_test', 'val', '10');
245-
ERROR: Wrong constraint format for RANGE partition "wrong_partition"
246-
EXPLAIN (COSTS OFF) SELECT * FROM calamity.part_ok; /* check that pathman is enabled */
247-
QUERY PLAN
248-
-----------------------------
249-
Append
250-
-> Seq Scan on part_ok_0
251-
-> Seq Scan on part_ok_1
252-
-> Seq Scan on part_ok_2
253-
-> Seq Scan on part_ok_3
254-
(5 rows)
255-
256-
ALTER TABLE calamity.wrong_partition DROP CONSTRAINT pathman_wrong_partition_1_check;
257241
ALTER TABLE calamity.wrong_partition
258242
ADD CONSTRAINT pathman_wrong_partition_1_check
259243
CHECK (val = 1 OR val = 2); /* wrong constraint */

‎sql/pathman_calamity.sql‎

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,6 @@ EXPLAIN (COSTS OFF) SELECT * FROM calamity.part_ok; /* check that pathman is ena
8585
SELECT add_to_pathman_config('calamity.part_test','val','10');
8686
EXPLAIN (COSTS OFF)SELECT*FROMcalamity.part_ok;/* check that pathman is enabled*/
8787

88-
ALTERTABLEcalamity.wrong_partition
89-
ADDCONSTRAINT pathman_wrong_partition_1_check
90-
CHECK (val<10);/* wrong constraint*/
91-
SELECT add_to_pathman_config('calamity.part_test','val','10');
92-
EXPLAIN (COSTS OFF)SELECT*FROMcalamity.part_ok;/* check that pathman is enabled*/
93-
ALTERTABLEcalamity.wrong_partition DROPCONSTRAINT pathman_wrong_partition_1_check;
94-
9588
ALTERTABLEcalamity.wrong_partition
9689
ADDCONSTRAINT pathman_wrong_partition_1_check
9790
CHECK (val=1OR val=2);/* wrong constraint*/

‎src/init.c‎

Lines changed: 70 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ static int cmp_range_entries(const void *p1, const void *p2, void *arg);
7575

7676
staticboolvalidate_range_constraint(constExpr*expr,
7777
constPartRelationInfo*prel,
78-
Datum*min,
79-
Datum*max);
78+
Datum*lower,Datum*upper,
79+
bool*lower_null,bool*upper_null);
8080

8181
staticboolvalidate_hash_constraint(constExpr*expr,
8282
constPartRelationInfo*prel,
@@ -375,14 +375,18 @@ fill_prel_with_partitions(const Oid *partitions,
375375

376376
casePT_RANGE:
377377
{
378-
Datumrange_min,range_max;
378+
Datumlower,upper;
379+
boollower_null,upper_null;
379380

380381
if (validate_range_constraint(con_expr,prel,
381-
&range_min,&range_max))
382+
&lower,&upper,
383+
&lower_null,&upper_null))
382384
{
383-
prel->ranges[i].child_oid=partitions[i];
384-
prel->ranges[i].min=range_min;
385-
prel->ranges[i].max=range_max;
385+
prel->ranges[i].child_oid=partitions[i];
386+
prel->ranges[i].min=lower;
387+
prel->ranges[i].max=upper;
388+
prel->ranges[i].infinite_min=lower_null;
389+
prel->ranges[i].infinite_max=upper_null;
386390
}
387391
else
388392
{
@@ -864,61 +868,91 @@ cmp_range_entries(const void *p1, const void *p2, void *arg)
864868

865869
Oidcmp_proc_oid=*(Oid*)arg;
866870

871+
/* If range is half open */
872+
if (v1->infinite_min)
873+
if (v2->infinite_min)
874+
returnInt32GetDatum(0);
875+
returnInt32GetDatum(-1);
876+
877+
/* Else if range is closed */
867878
returnOidFunctionCall2(cmp_proc_oid,v1->min,v2->min);
868879
}
869880

870881
/*
871-
* Validates range constraint. It MUST havethis exact format:
882+
* Validates range constraint. It MUST haveone of the following formats:
872883
*
873884
*VARIABLE >= CONST AND VARIABLE < CONST
885+
*VARIABLE >= CONST
886+
*VARIABLE < CONST
874887
*
875-
* Writes 'min' & 'max' values on success.
888+
* Writes 'lower' & 'upper' and 'lower_null' & 'upper_null' values on success.
876889
*/
877890
staticbool
878891
validate_range_constraint(constExpr*expr,
879892
constPartRelationInfo*prel,
880-
Datum*min,
881-
Datum*max)
893+
Datum*lower,Datum*upper,
894+
bool*lower_null,bool*upper_null)
882895
{
883896
constTypeCacheEntry*tce;
884-
constBoolExpr*boolexpr= (constBoolExpr*)expr;
885897
constOpExpr*opexpr;
886898
intstrategy;
887899

888-
if (!expr)
889-
return false;
900+
/* Validates a single expression of kind VAR >= CONST or VAR < CONST */
901+
#definevalidate_range_expr(expr)\
902+
{\
903+
Datum val;\
904+
opexpr = (OpExpr *) (expr);\
905+
strategy = get_op_opfamily_strategy(opexpr->opno, tce->btree_opf);\
906+
\
907+
/* Get const value */\
908+
if (!read_opexpr_const(opexpr,prel,&val))\
909+
return false;\
910+
\
911+
/* Set min or max depending on operator */\
912+
switch (strategy)\
913+
{\
914+
caseBTGreaterEqualStrategyNumber:\
915+
*lower_null= false;\
916+
*lower=val;\
917+
break;\
918+
caseBTLessStrategyNumber:\
919+
*upper_null= false;\
920+
*upper=val;\
921+
break;\
922+
default:\
923+
return false;\
924+
}\
925+
}
890926

891-
/* it should be an AND operator on top */
892-
if (!and_clause((Node*)expr))
927+
if (!expr)
893928
return false;
894-
929+
*lower_null=*upper_null= false;
895930
tce=lookup_type_cache(prel->atttype,TYPECACHE_BTREE_OPFAMILY);
896931

897-
/* check that left operand is >= operator */
898-
opexpr= (OpExpr*)linitial(boolexpr->args);
899-
strategy=get_op_opfamily_strategy(opexpr->opno,tce->btree_opf);
900-
901-
if (strategy==BTGreaterEqualStrategyNumber)
932+
/* It could be either AND operator on top or just an OpExpr */
933+
if (and_clause((Node*)expr))
902934
{
903-
if (!read_opexpr_const(opexpr,prel,min))
904-
return false;
905-
}
906-
else
907-
return false;
935+
constBoolExpr*boolexpr= (constBoolExpr*)expr;
936+
ListCell*lc;
937+
938+
foreach (lc,boolexpr->args)
939+
{
940+
Node*arg=lfirst(lc);
908941

909-
/* check that right operand is < operator */
910-
opexpr= (OpExpr*)lsecond(boolexpr->args);
911-
strategy=get_op_opfamily_strategy(opexpr->opno,tce->btree_opf);
942+
if(!IsA(arg,OpExpr))
943+
return false;
912944

913-
if (strategy==BTLessStrategyNumber)
945+
validate_range_expr(arg);
946+
}
947+
return true;
948+
}
949+
elseif(IsA(expr,OpExpr))
914950
{
915-
if (!read_opexpr_const(opexpr,prel,max))
916-
returnfalse;
951+
validate_range_expr(expr);
952+
returntrue;
917953
}
918-
else
919-
return false;
920954

921-
returntrue;
955+
returnfalse;
922956
}
923957

924958
/*

‎src/partition_creation.c‎

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -834,11 +834,29 @@ build_range_check_constraint(Oid child_relid,
834834
returnrange_constr;
835835
}
836836

837+
// static int16_t
838+
// cmp_boundaries(FmgrInfo cmp_func, Datum s1, Datum s2, bool s1_infinite, bool s2_infinite)
839+
// {
840+
// if (s1_infinite && s2_infinite)
841+
// elog(ERROR,
842+
// "two half open ranges are overlap");
843+
844+
// if (s1_infinite)
845+
// return -1;
846+
847+
// if (s2_infinite)
848+
// return 1;
849+
850+
// return DatumGetInt16(FunctionCall2(&cmp_func, start_value, ranges[i].max));
851+
// }
852+
837853
/* Check if range overlaps with any partitions */
838854
bool
839855
check_range_available(Oidparent_relid,
840856
Datumstart_value,
841857
Datumend_value,
858+
boolinfinite_start,
859+
boolinfinite_end,
842860
Oidvalue_type,
843861
boolraise_error)
844862
{
@@ -864,8 +882,32 @@ check_range_available(Oid parent_relid,
864882
ranges=PrelGetRangesArray(prel);
865883
for (i=0;i<PrelChildrenCount(prel);i++)
866884
{
867-
intc1=FunctionCall2(&cmp_func,start_value,ranges[i].max),
868-
c2=FunctionCall2(&cmp_func,end_value,ranges[i].min);
885+
// int c1 = cmp_boundaries(cmp_func, start_value, ranges[i].max, infinite_start, ranges[i].infinite_max);
886+
// int c2 = cmp_boundaries(cmp_func, end_value, ranges[i].min, infinite_end, ranges[i].infinite_min);
887+
888+
/* If both ranges are half open then they are obviously overlap */
889+
// if (infinite_start && ranges[i].infinite_max)
890+
// return false;
891+
// if (infinite_end && ranges[i].infinite_min)
892+
// return false;
893+
894+
// intc1 = FunctionCall2(&cmp_func, start_value, ranges[i].max),
895+
// c2 = FunctionCall2(&cmp_func, end_value, ranges[i].min);
896+
intc1,c2;
897+
898+
/*
899+
* If the range we're checking starts with minus infinity or current
900+
* range is ends in plus infinity then the left boundary of the first
901+
* one is on the left
902+
*/
903+
c1= (infinite_start||ranges[i].infinite_max) ?
904+
-1 :FunctionCall2(&cmp_func,start_value,ranges[i].max);
905+
/*
906+
* Similary check the right boundary of first range is on the right
907+
* of the beginning of second one
908+
*/
909+
c2= (infinite_end||ranges[i].infinite_min) ?
910+
-1 :FunctionCall2(&cmp_func,end_value,ranges[i].max);
869911

870912
/* There's someone! */
871913
if (c1<0&&c2>0)

‎src/partition_creation.h‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,11 @@ Node * build_raw_range_check_tree(char *attname,
3535
Datumend_value,
3636
Oidvalue_type);
3737

38-
boolcheck_range_available(Oidpartition_relid,
38+
boolcheck_range_available(Oidparent_relid,
3939
Datumstart_value,
4040
Datumend_value,
41+
boolinfinite_start,
42+
boolinfinite_end,
4143
Oidvalue_type,
4244
boolraise_error);
4345

‎src/pg_pathman.c‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -446,8 +446,10 @@ select_range_partitions(const Datum value,
446446
Assert(cmp_func);
447447

448448
/* Corner cases */
449-
cmp_min=FunctionCall2(cmp_func,value,ranges[startidx].min),
450-
cmp_max=FunctionCall2(cmp_func,value,ranges[endidx].max);
449+
cmp_min=ranges[startidx].infinite_min ?
450+
1 :DatumGetInt32(FunctionCall2(cmp_func,value,ranges[startidx].min));
451+
cmp_max=ranges[endidx].infinite_max ?
452+
-1 :DatumGetInt32(FunctionCall2(cmp_func,value,ranges[endidx].max));
451453

452454
if ((cmp_min <=0&&strategy==BTLessStrategyNumber)||
453455
(cmp_min<0&& (strategy==BTLessEqualStrategyNumber||

‎src/pl_range_funcs.c‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,12 +166,15 @@ check_range_available_pl(PG_FUNCTION_ARGS)
166166

167167
Datumstart_value=PG_GETARG_DATUM(1),
168168
end_value=PG_GETARG_DATUM(2);
169+
boolstart_null=PG_ARGISNULL(1),
170+
end_null=PG_ARGISNULL(2);
169171
Oidvalue_type=get_fn_expr_argtype(fcinfo->flinfo,1);
170172

171173
/* Raise ERROR if range overlaps with any partition */
172174
check_range_available(parent_relid,
173175
start_value,
174176
end_value,
177+
start_null,end_null,
175178
value_type,
176179
true);
177180

‎src/rangeset.h‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ typedef struct {
2828
uint32upper;/* lossy + upper_bound */
2929
}IndexRange;
3030

31-
3231
/* Convenience macros for make_irange(...) */
3332
#defineIR_LOSSYtrue
3433
#defineIR_COMPLETEfalse
@@ -43,7 +42,6 @@ typedef struct {
4342
#defineirange_lower(irange)( (uint32) (irange.lower & IRANGE_BONDARY_MASK) )
4443
#defineirange_upper(irange)( (uint32) (irange.upper & IRANGE_BONDARY_MASK) )
4544

46-
4745
#definelfirst_irange(lc)( *(IndexRange *) lfirst(lc) )
4846
#definelappend_irange(list,irange)( lappend((list), alloc_irange(irange)) )
4947
#definelcons_irange(irange,list)( lcons(alloc_irange(irange), (list)) )

‎src/relation_info.h‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,10 @@ typedef enum
3333
typedefstruct
3434
{
3535
Oidchild_oid;
36-
3736
Datummin,
3837
max;
38+
boolinfinite_min,
39+
infinite_max;
3940
}RangeEntry;
4041

4142
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp