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

Commit17d7029

Browse files
committed
refactoring & fixes in function handle_arrexpr(), moved static inline functions to rangeset.h
1 parent48afabd commit17d7029

File tree

3 files changed

+233
-103
lines changed

3 files changed

+233
-103
lines changed

‎src/include/rangeset.h

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,30 @@ irange_cmp_lossiness(IndexRange a, IndexRange b)
129129
}
130130

131131

132-
/* Various traits */
133-
booliranges_intersect(IndexRangea,IndexRangeb);
134-
booliranges_adjoin(IndexRangea,IndexRangeb);
135-
boolirange_eq_bounds(IndexRangea,IndexRangeb);
132+
/* Check if two ranges intersect */
133+
staticinlinebool
134+
iranges_intersect(IndexRangea,IndexRangeb)
135+
{
136+
return (irange_lower(a) <=irange_upper(b))&&
137+
(irange_lower(b) <=irange_upper(a));
138+
}
139+
140+
/* Check if two ranges adjoin */
141+
staticinlinebool
142+
iranges_adjoin(IndexRangea,IndexRangeb)
143+
{
144+
return (irange_upper(a)==irb_pred(irange_lower(b)))||
145+
(irange_upper(b)==irb_pred(irange_lower(a)));
146+
}
147+
148+
/* Check if two ranges cover the same area */
149+
staticinlinebool
150+
irange_eq_bounds(IndexRangea,IndexRangeb)
151+
{
152+
return (irange_lower(a)==irange_lower(b))&&
153+
(irange_upper(a)==irange_upper(b));
154+
}
155+
136156

137157
/* Basic operations on IndexRanges */
138158
IndexRangeirange_union_simple(IndexRangea,IndexRangeb);
@@ -141,6 +161,7 @@ IndexRange irange_intersection_simple(IndexRange a, IndexRange b);
141161
/* Operations on Lists of IndexRanges */
142162
List*irange_list_union(List*a,List*b);
143163
List*irange_list_intersection(List*a,List*b);
164+
List*irange_list_set_lossiness(List*ranges,boollossy);
144165

145166
/* Utility functions */
146167
intirange_list_length(List*rangeset);

‎src/pg_pathman.c

Lines changed: 185 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,7 @@ static void
720720
handle_const(constConst*c,
721721
constintstrategy,
722722
constWalkerContext*context,
723-
WrapperNode*result)/* ret value #1 */
723+
WrapperNode*result)/* ret value #1 */
724724
{
725725
constPartRelationInfo*prel=context->prel;
726726

@@ -838,16 +838,103 @@ handle_const(const Const *c,
838838
result->paramsel=estimate_paramsel_using_prel(prel,strategy);
839839
}
840840

841+
/* Array handler */
842+
staticvoid
843+
handle_array(ArrayType*array,
844+
constintstrategy,
845+
constbooluse_or,
846+
constWalkerContext*context,
847+
WrapperNode*result)/* ret value #1 */
848+
{
849+
constPartRelationInfo*prel=context->prel;
850+
851+
/* Elements of the array */
852+
Datum*elem_values;
853+
bool*elem_isnull;
854+
intelem_count;
855+
856+
/* Element's properties */
857+
Oidelem_type;
858+
int16elem_len;
859+
boolelem_byval;
860+
charelem_align;
861+
862+
/* Check if we can work with this strategy */
863+
if (strategy==0)
864+
gotohandle_array_return;
865+
866+
/* Get element's properties */
867+
elem_type=ARR_ELEMTYPE(array);
868+
get_typlenbyvalalign(elem_type,&elem_len,&elem_byval,&elem_align);
869+
870+
/* Extract values from the array */
871+
deconstruct_array(array,elem_type,elem_len,elem_byval,elem_align,
872+
&elem_values,&elem_isnull,&elem_count);
873+
874+
/* Handle non-null Const arrays */
875+
if (elem_count>0)
876+
{
877+
List*ranges;
878+
inti;
879+
880+
/* Set default ranges for OR | AND */
881+
ranges=use_or ?NIL :list_make1_irange_full(prel,IR_COMPLETE);
882+
883+
/* Select partitions using values */
884+
for (i=0;i<elem_count;i++)
885+
{
886+
WrapperNodewrap;
887+
Constc;
888+
889+
NodeSetTag(&c,T_Const);
890+
c.consttype=elem_type;
891+
c.consttypmod=-1;
892+
c.constcollid=InvalidOid;
893+
c.constlen=datumGetSize(elem_values[i],
894+
elem_byval,
895+
elem_len);
896+
c.constvalue=elem_values[i];
897+
c.constisnull=elem_isnull[i];
898+
c.constbyval=elem_byval;
899+
c.location=-1;
900+
901+
handle_const(&c,strategy,context,&wrap);
902+
903+
/* Should we use OR | AND? */
904+
ranges=use_or ?
905+
irange_list_union(ranges,wrap.rangeset) :
906+
irange_list_intersection(ranges,wrap.rangeset);
907+
908+
result->paramsel=Max(result->paramsel,wrap.paramsel);
909+
}
910+
911+
/* Free resources */
912+
pfree(elem_values);
913+
pfree(elem_isnull);
914+
915+
/* Save rangeset */
916+
result->rangeset=ranges;
917+
918+
return;/* done, exit */
919+
}
920+
921+
handle_array_return:
922+
result->rangeset=list_make1_irange_full(prel,IR_LOSSY);
923+
result->paramsel=estimate_paramsel_using_prel(prel,strategy);
924+
}
925+
841926
/* Boolean expression handler */
842927
staticvoid
843928
handle_boolexpr(constBoolExpr*expr,
844929
constWalkerContext*context,
845-
WrapperNode*result)
930+
WrapperNode*result)/* ret value #1 */
846931
{
847-
ListCell*lc;
848-
constPartRelationInfo*prel=context->prel;
932+
constPartRelationInfo*prel=context->prel;
933+
ListCell*lc;
849934

935+
/* Save expression */
850936
result->orig= (constNode*)expr;
937+
851938
result->args=NIL;
852939
result->paramsel=1.0;
853940

@@ -858,22 +945,22 @@ handle_boolexpr(const BoolExpr *expr,
858945

859946
foreach (lc,expr->args)
860947
{
861-
WrapperNode*arg_result;
948+
WrapperNode*wrap;
862949

863-
arg_result=walk_expr_tree((Expr*)lfirst(lc),context);
864-
result->args=lappend(result->args,arg_result);
950+
wrap=walk_expr_tree((Expr*)lfirst(lc),context);
951+
result->args=lappend(result->args,wrap);
865952

866953
switch (expr->boolop)
867954
{
868955
caseOR_EXPR:
869956
result->rangeset=irange_list_union(result->rangeset,
870-
arg_result->rangeset);
957+
wrap->rangeset);
871958
break;
872959

873960
caseAND_EXPR:
874961
result->rangeset=irange_list_intersection(result->rangeset,
875-
arg_result->rangeset);
876-
result->paramsel *=arg_result->paramsel;
962+
wrap->rangeset);
963+
result->paramsel *=wrap->paramsel;
877964
break;
878965

879966
default:
@@ -901,107 +988,131 @@ handle_boolexpr(const BoolExpr *expr,
901988
staticvoid
902989
handle_arrexpr(constScalarArrayOpExpr*expr,
903990
constWalkerContext*context,
904-
WrapperNode*result)
991+
WrapperNode*result)/* ret value #1 */
905992
{
906-
Node*exprnode= (Node*)linitial(expr->args);
907-
Node*arraynode= (Node*)lsecond(expr->args);
993+
Node*part_expr= (Node*)linitial(expr->args);
994+
Node*array= (Node*)lsecond(expr->args);
908995
constPartRelationInfo*prel=context->prel;
909996
TypeCacheEntry*tce;
910997
intstrategy;
911998

912-
result->orig= (constNode*)expr;
913-
914999
tce=lookup_type_cache(prel->ev_type,TYPECACHE_BTREE_OPFAMILY);
9151000
strategy=get_op_opfamily_strategy(expr->opno,tce->btree_opf);
9161001

917-
if (!match_expr_to_operand(context->prel_expr,exprnode))
1002+
/* Check if expression tree is a partitioning expression */
1003+
if (!match_expr_to_operand(context->prel_expr,part_expr))
9181004
gotohandle_arrexpr_return;
9191005

920-
/* Handle non-null Const arrays */
921-
if (arraynode&&IsA(arraynode,Const)&& !((Const*)arraynode)->constisnull)
922-
{
923-
ArrayType*arrayval;
924-
925-
int16elemlen;
926-
boolelembyval;
927-
charelemalign;
1006+
/* Check if we can work with this strategy */
1007+
if (strategy==0)
1008+
gotohandle_arrexpr_return;
9281009

929-
intnum_elems;
1010+
/* Examine the array node */
1011+
switch (nodeTag(array))
1012+
{
1013+
caseT_Const:
1014+
{
1015+
Const*c= (Const*)array;
9301016

931-
Datum*elem_values;
932-
bool*elem_isnull;
1017+
/* Array is NULL */
1018+
if (c->constisnull)
1019+
gotohandle_arrexpr_return;
9331020

934-
WalkerContextnested_wcxt;
935-
List*ranges;
936-
inti;
1021+
/* Examine array */
1022+
handle_array(DatumGetArrayTypeP(c->constvalue),
1023+
strategy,expr->useOr,context,result);
9371024

938-
/*Extract values from array */
939-
arrayval=DatumGetArrayTypeP(((Const*)arraynode)->constvalue);
1025+
/*Save expression */
1026+
result->orig=(constNode*)expr;
9401027

941-
get_typlenbyvalalign(ARR_ELEMTYPE(arrayval),
942-
&elemlen,&elembyval,&elemalign);
1028+
return;/* done, exit */
1029+
}
9431030

944-
deconstruct_array(arrayval,
945-
ARR_ELEMTYPE(arrayval),
946-
elemlen,elembyval,elemalign,
947-
&elem_values,&elem_isnull,&num_elems);
1031+
caseT_ArrayExpr:
1032+
{
1033+
ArrayExpr*arr_expr= (ArrayExpr*)array;
1034+
Oidelem_type=arr_expr->element_typeid;
1035+
boolarray_has_params= false;
1036+
List*ranges;
1037+
ListCell*lc;
9481038

949-
/* Copy WalkerContext */
950-
memcpy((void*)&nested_wcxt,
951-
(constvoid*)context,
952-
sizeof(WalkerContext));
1039+
/* Set default ranges for OR | AND */
1040+
ranges=expr->useOr ?NIL :list_make1_irange_full(prel,IR_COMPLETE);
9531041

954-
/* Set default ranges for OR | AND */
955-
ranges=expr->useOr ?NIL :list_make1_irange_full(prel,IR_COMPLETE);
1042+
/* Walk trough elements list */
1043+
foreach (lc,arr_expr->elements)
1044+
{
1045+
Node*elem=lfirst(lc);
1046+
WrapperNodewrap;
9561047

957-
/* Select partitions using values */
958-
for (i=0;i<num_elems;i++)
959-
{
960-
WrapperNodesub_result;
961-
Constc;
1048+
/* Stop if ALL + quals evaluate to NIL */
1049+
if (!expr->useOr&&ranges==NIL)
1050+
break;
9621051

963-
NodeSetTag(&c,T_Const);
964-
c.consttype=ARR_ELEMTYPE(arrayval);
965-
c.consttypmod=-1;
966-
c.constcollid=InvalidOid;
967-
c.constlen=datumGetSize(elem_values[i],
968-
elembyval,
969-
elemlen);
970-
c.constvalue=elem_values[i];
971-
c.constisnull=elem_isnull[i];
972-
c.constbyval=elembyval;
973-
c.location=-1;
1052+
/* Is this a const value? */
1053+
if (IsConstValue(elem,context))
1054+
{
1055+
Const*c=ExtractConst(elem,context);
1056+
1057+
/* Is this an array?.. */
1058+
if (c->consttype!=elem_type)
1059+
{
1060+
/* Array is NULL */
1061+
if (c->constisnull)
1062+
gotohandle_arrexpr_return;
1063+
1064+
/* Examine array */
1065+
handle_array(DatumGetArrayTypeP(c->constvalue),
1066+
strategy,expr->useOr,context,&wrap);
1067+
}
1068+
/* ... or a single element? */
1069+
elsehandle_const(c,strategy,context,&wrap);
1070+
1071+
/* Should we use OR | AND? */
1072+
ranges=expr->useOr ?
1073+
irange_list_union(ranges,wrap.rangeset) :
1074+
irange_list_intersection(ranges,wrap.rangeset);
1075+
}
1076+
elsearray_has_params= true;/* we have non-const nodes */
1077+
}
9741078

975-
handle_const(&c,strategy,&nested_wcxt,&sub_result);
1079+
/* Check for PARAM-related optimizations */
1080+
if (array_has_params)
1081+
{
1082+
/* We can't say anything if PARAMs + ANY */
1083+
if (expr->useOr)
1084+
gotohandle_arrexpr_return;
9761085

977-
ranges=expr->useOr ?
978-
irange_list_union(ranges,sub_result.rangeset) :
979-
irange_list_intersection(ranges,sub_result.rangeset);
1086+
/* Recheck condition on a narrowed set of partitions */
1087+
ranges=irange_list_set_lossiness(ranges,IR_LOSSY);
1088+
}
9801089

981-
result->paramsel=Max(result->paramsel,sub_result.paramsel);
982-
}
1090+
/* Save rangeset */
1091+
result->rangeset=ranges;
9831092

984-
result->rangeset=ranges;
985-
if (num_elems==0)
986-
result->paramsel=0.0;
1093+
/* Save expression */
1094+
result->orig= (constNode*)expr;
9871095

988-
/* Free resources */
989-
pfree(elem_values);
990-
pfree(elem_isnull);
1096+
return;/* done, exit */
1097+
}
9911098

992-
return;/* done, exit */
1099+
default:
1100+
break;
9931101
}
9941102

9951103
handle_arrexpr_return:
9961104
result->rangeset=list_make1_irange_full(prel,IR_LOSSY);
9971105
result->paramsel=estimate_paramsel_using_prel(prel,strategy);
1106+
1107+
/* Save expression */
1108+
result->orig= (constNode*)expr;
9981109
}
9991110

10001111
/* Operator expression handler */
10011112
staticvoid
10021113
handle_opexpr(constOpExpr*expr,
10031114
constWalkerContext*context,
1004-
WrapperNode*result)
1115+
WrapperNode*result)/* ret value #1 */
10051116
{
10061117
Node*param;
10071118
constPartRelationInfo*prel=context->prel;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp