@@ -99,7 +99,7 @@ static Path *get_cheapest_parameterized_child_path(PlannerInfo *root,
99
99
RelOptInfo * rel ,
100
100
Relids required_outer );
101
101
102
-
102
+ static bool match_expr_to_operand ( Node * operand , Node * expr );
103
103
/* We can transform Param into Const provided that 'econtext' is available */
104
104
#define IsConstValue (wcxt , node ) \
105
105
( IsA((node), Const) || (WcxtHasExprContext(wcxt) ? IsA((node), Param) : false) )
@@ -895,36 +895,22 @@ static WrapperNode *
895
895
handle_arrexpr (const ScalarArrayOpExpr * expr , WalkerContext * context )
896
896
{
897
897
WrapperNode * result = (WrapperNode * ) palloc (sizeof (WrapperNode ));
898
- Node * varnode = (Node * ) linitial (expr -> args );
899
- Var * var ;
898
+ Node * exprnode = (Node * ) linitial (expr -> args );
900
899
Node * arraynode = (Node * ) lsecond (expr -> args );
901
900
const PartRelationInfo * prel = context -> prel ;
902
901
903
902
result -> orig = (const Node * ) expr ;
904
903
result -> args = NIL ;
905
904
result -> paramsel = 0.0 ;
906
905
907
- Assert (varnode != NULL );
906
+ Assert (exprnode != NULL );
908
907
909
- /* If variable is not the partition key then skip it */
910
- if (IsA (varnode , Var ) || IsA (varnode , RelabelType ))
911
- {
912
- var = !IsA (varnode , RelabelType ) ?
913
- (Var * ) varnode :
914
- (Var * ) ((RelabelType * ) varnode )-> arg ;
915
-
916
- /* Skip if base types or attribute numbers do not match */
917
- /* FIX: use exprsssion
918
- if (getBaseType(var->vartype) != getBaseType(prel->atttype) ||
919
- var->varoattno != prel->attnum ||
920
- var->varno != context->prel_varno)
921
- {
922
- goto handle_arrexpr_return;
923
- } */
924
- }
925
- else
908
+ if (!match_expr_to_operand (context -> prel_expr , exprnode ))
926
909
goto handle_arrexpr_return ;
927
910
911
+ if (exprnode && IsA (exprnode , RelabelType ))
912
+ exprnode = (Node * ) ((RelabelType * ) exprnode )-> arg ;
913
+
928
914
if (arraynode && IsA (arraynode , Const ) &&
929
915
!((Const * ) arraynode )-> constisnull )
930
916
{
@@ -1084,16 +1070,9 @@ handle_binary_opexpr(WalkerContext *context, WrapperNode *result,
1084
1070
{
1085
1071
int strategy ;
1086
1072
TypeCacheEntry * tce ;
1087
- Oid vartype ;
1088
1073
const OpExpr * expr = (const OpExpr * ) result -> orig ;
1089
1074
const PartRelationInfo * prel = context -> prel ;
1090
1075
1091
- Assert (IsA (varnode , Var ) || IsA (varnode , RelabelType ));
1092
-
1093
- vartype = !IsA (varnode , RelabelType ) ?
1094
- ((Var * ) varnode )-> vartype :
1095
- ((RelabelType * ) varnode )-> resulttype ;
1096
-
1097
1076
/* Exit if Constant is NULL */
1098
1077
if (c -> constisnull )
1099
1078
{
@@ -1102,7 +1081,7 @@ handle_binary_opexpr(WalkerContext *context, WrapperNode *result,
1102
1081
return ;
1103
1082
}
1104
1083
1105
- tce = lookup_type_cache (vartype , TYPECACHE_BTREE_OPFAMILY );
1084
+ tce = lookup_type_cache (prel -> atttype , TYPECACHE_BTREE_OPFAMILY );
1106
1085
strategy = get_op_opfamily_strategy (expr -> opno , tce -> btree_opf );
1107
1086
1108
1087
/* There's no strategy for this operator, go to end */
@@ -1164,25 +1143,36 @@ handle_binary_opexpr_param(const PartRelationInfo *prel,
1164
1143
const OpExpr * expr = (const OpExpr * ) result -> orig ;
1165
1144
TypeCacheEntry * tce ;
1166
1145
int strategy ;
1167
- Oid vartype ;
1168
-
1169
- Assert (IsA (varnode , Var ) || IsA (varnode , RelabelType ));
1170
-
1171
- vartype = !IsA (varnode , RelabelType ) ?
1172
- ((Var * ) varnode )-> vartype :
1173
- ((RelabelType * ) varnode )-> resulttype ;
1174
1146
1175
1147
/* Determine operator type */
1176
- tce = lookup_type_cache (vartype , TYPECACHE_BTREE_OPFAMILY );
1148
+ tce = lookup_type_cache (prel -> atttype , TYPECACHE_BTREE_OPFAMILY );
1177
1149
strategy = get_op_opfamily_strategy (expr -> opno , tce -> btree_opf );
1178
1150
1179
1151
result -> rangeset = list_make1_irange (make_irange (0 , PrelLastChild (prel ), IR_LOSSY ));
1180
1152
result -> paramsel = estimate_paramsel_using_prel (prel , strategy );
1181
1153
}
1182
1154
1155
+
1156
+ /*
1157
+ * Compare clause operand with our expression
1158
+ */
1159
+ static bool
1160
+ match_expr_to_operand (Node * operand , Node * expr )
1161
+ {
1162
+ /* strip relabeling for both operand and expr */
1163
+ if (operand && IsA (operand , RelabelType ))
1164
+ operand = (Node * ) ((RelabelType * ) operand )-> arg ;
1165
+
1166
+ if (expr && IsA (expr , RelabelType ))
1167
+ expr = (Node * ) ((RelabelType * ) expr )-> arg ;
1168
+
1169
+ /* compare expressions and return result right away */
1170
+ return equal (expr , operand );
1171
+ }
1172
+
1183
1173
/*
1184
1174
* Checks if expression is a KEY OP PARAM or PARAM OP KEY, where KEY is
1185
- * partition key (it could be Var or RelableType) and PARAM is whatever.
1175
+ * partition expression and PARAM is whatever.
1186
1176
*
1187
1177
* NOTE: returns false if partition key is not in expression.
1188
1178
*/
@@ -1194,45 +1184,21 @@ pull_var_param(const WalkerContext *ctx,
1194
1184
{
1195
1185
Node * left = linitial (expr -> args ),
1196
1186
* right = lsecond (expr -> args );
1197
- Var * v = NULL ;
1198
1187
1199
- /* Check the case when variable is on the left side */
1200
- if (IsA (left , Var ) || IsA (left , RelabelType ))
1188
+ if (match_expr_to_operand (left , ctx -> prel_expr ))
1201
1189
{
1202
- v = !IsA (left , RelabelType ) ?
1203
- (Var * ) left :
1204
- (Var * ) ((RelabelType * ) left )-> arg ;
1205
-
1206
- /* Check if 'v' is partitioned column of 'prel' */
1207
- /* FIX this */
1208
- if (v -> varoattno == 0 &&
1209
- v -> varno == ctx -> prel_varno )
1210
- {
1211
- * var_ptr = left ;
1212
- * param_ptr = right ;
1213
- return true;
1214
- }
1190
+ * var_ptr = left ;
1191
+ * param_ptr = right ;
1192
+ return true;
1215
1193
}
1216
1194
1217
- /* ... variable is on the right side */
1218
- if (IsA (right , Var ) || IsA (right , RelabelType ))
1195
+ if (match_expr_to_operand (right , ctx -> prel_expr ))
1219
1196
{
1220
- v = !IsA (right , RelabelType ) ?
1221
- (Var * ) right :
1222
- (Var * ) ((RelabelType * ) right )-> arg ;
1223
-
1224
- /* Check if 'v' is partitioned column of 'prel' */
1225
- /* FIX this */
1226
- if (v -> varoattno == 0 &&
1227
- v -> varno == ctx -> prel_varno )
1228
- {
1229
- * var_ptr = right ;
1230
- * param_ptr = left ;
1231
- return true;
1232
- }
1197
+ * var_ptr = right ;
1198
+ * param_ptr = left ;
1199
+ return true;
1233
1200
}
1234
1201
1235
- /* Variable isn't a partitionig key */
1236
1202
return false;
1237
1203
}
1238
1204
0 commit comments