@@ -1080,6 +1080,9 @@ handle_arrexpr(const ScalarArrayOpExpr *expr,
1080
1080
tce = lookup_type_cache (prel -> ev_type , TYPECACHE_BTREE_OPFAMILY );
1081
1081
strategy = get_op_opfamily_strategy (expr -> opno , tce -> btree_opf );
1082
1082
1083
+ /* Save expression */
1084
+ result -> orig = (const Node * ) expr ;
1085
+
1083
1086
/* Check if expression tree is a partitioning expression */
1084
1087
if (!match_expr_to_operand (context -> prel_expr , part_expr ))
1085
1088
goto handle_arrexpr_all ;
@@ -1097,10 +1100,12 @@ handle_arrexpr(const ScalarArrayOpExpr *expr,
1097
1100
1098
1101
/* Array is NULL */
1099
1102
if (c -> constisnull )
1100
- goto handle_arrexpr_none ;
1103
+ {
1104
+ result -> rangeset = NIL ;
1105
+ result -> paramsel = 0.0 ;
1101
1106
1102
- /* Provide expression for optimizations */
1103
- result -> orig = ( const Node * ) expr ;
1107
+ return ; /* done, exit */
1108
+ }
1104
1109
1105
1110
/* Examine array */
1106
1111
handle_array (DatumGetArrayTypeP (c -> constvalue ),
@@ -1114,7 +1119,8 @@ handle_arrexpr(const ScalarArrayOpExpr *expr,
1114
1119
{
1115
1120
ArrayExpr * arr_expr = (ArrayExpr * ) array ;
1116
1121
Oid elem_type = arr_expr -> element_typeid ;
1117
- bool array_has_params = false;
1122
+ int array_params = 0 ;
1123
+ double paramsel = 1.0 ;
1118
1124
List * ranges ;
1119
1125
ListCell * lc ;
1120
1126
@@ -1158,25 +1164,40 @@ handle_arrexpr(const ScalarArrayOpExpr *expr,
1158
1164
irange_list_union (ranges , wrap .rangeset ) :
1159
1165
irange_list_intersection (ranges , wrap .rangeset );
1160
1166
}
1161
- else array_has_params = true ; /* we have non-const nodes */
1167
+ else array_params ++ ; /* we've just met non-const nodes */
1162
1168
}
1163
1169
1164
1170
/* Check for PARAM-related optimizations */
1165
- if (array_has_params )
1171
+ if (array_params > 0 )
1166
1172
{
1167
- /* We can't say anything if PARAMs + ANY */
1173
+ double sel = estimate_paramsel_using_prel (prel , strategy );
1174
+ int i ;
1175
+
1168
1176
if (expr -> useOr )
1169
- goto handle_arrexpr_all ;
1177
+ {
1178
+ /* We can't say anything if PARAMs + ANY */
1179
+ ranges = list_make1_irange_full (prel , IR_LOSSY );
1180
+
1181
+ /* See handle_boolexpr() */
1182
+ for (i = 0 ; i < array_params ; i ++ )
1183
+ paramsel *= (1 - sel );
1184
+
1185
+ paramsel = 1 - paramsel ;
1186
+ }
1187
+ else
1188
+ {
1189
+ /* Recheck condition on a narrowed set of partitions */
1190
+ ranges = irange_list_set_lossiness (ranges , IR_LOSSY );
1170
1191
1171
- /* Recheck condition on a narrowed set of partitions */
1172
- ranges = irange_list_set_lossiness (ranges , IR_LOSSY );
1192
+ /* See handle_boolexpr() */
1193
+ for (i = 0 ; i < array_params ; i ++ )
1194
+ paramsel *= sel ;
1195
+ }
1173
1196
}
1174
1197
1175
- /* Save rangeset */
1198
+ /* Save result */
1176
1199
result -> rangeset = ranges ;
1177
-
1178
- /* Save expression */
1179
- result -> orig = (const Node * ) expr ;
1200
+ result -> paramsel = paramsel ;
1180
1201
1181
1202
return ; /* done, exit */
1182
1203
}
@@ -1187,21 +1208,7 @@ handle_arrexpr(const ScalarArrayOpExpr *expr,
1187
1208
1188
1209
handle_arrexpr_all :
1189
1210
result -> rangeset = list_make1_irange_full (prel , IR_LOSSY );
1190
- result -> paramsel = estimate_paramsel_using_prel (prel , strategy );
1191
-
1192
- /* Save expression */
1193
- result -> orig = (const Node * ) expr ;
1194
-
1195
- return ;
1196
-
1197
- handle_arrexpr_none :
1198
- result -> rangeset = NIL ;
1199
- result -> paramsel = 0.0 ;
1200
-
1201
- /* Save expression */
1202
- result -> orig = (const Node * ) expr ;
1203
-
1204
- return ;
1211
+ result -> paramsel = 1.0 ;
1205
1212
}
1206
1213
1207
1214
/* Operator expression handler */
0 commit comments