@@ -1080,6 +1080,9 @@ handle_arrexpr(const ScalarArrayOpExpr *expr,
10801080 tce = lookup_type_cache (prel -> ev_type , TYPECACHE_BTREE_OPFAMILY );
10811081 strategy = get_op_opfamily_strategy (expr -> opno , tce -> btree_opf );
10821082
1083+ /* Save expression */
1084+ result -> orig = (const Node * ) expr ;
1085+
10831086 /* Check if expression tree is a partitioning expression */
10841087 if (!match_expr_to_operand (context -> prel_expr , part_expr ))
10851088 goto handle_arrexpr_all ;
@@ -1097,10 +1100,12 @@ handle_arrexpr(const ScalarArrayOpExpr *expr,
10971100
10981101 /* Array is NULL */
10991102 if (c -> constisnull )
1100- goto handle_arrexpr_none ;
1103+ {
1104+ result -> rangeset = NIL ;
1105+ result -> paramsel = 0.0 ;
11011106
1102- /* Provide expression for optimizations */
1103- result -> orig = ( const Node * ) expr ;
1107+ return ; /* done, exit */
1108+ }
11041109
11051110 /* Examine array */
11061111 handle_array (DatumGetArrayTypeP (c -> constvalue ),
@@ -1114,7 +1119,8 @@ handle_arrexpr(const ScalarArrayOpExpr *expr,
11141119 {
11151120 ArrayExpr * arr_expr = (ArrayExpr * ) array ;
11161121 Oid elem_type = arr_expr -> element_typeid ;
1117- bool array_has_params = false;
1122+ int array_params = 0 ;
1123+ double paramsel = 1.0 ;
11181124 List * ranges ;
11191125 ListCell * lc ;
11201126
@@ -1158,25 +1164,40 @@ handle_arrexpr(const ScalarArrayOpExpr *expr,
11581164 irange_list_union (ranges , wrap .rangeset ) :
11591165 irange_list_intersection (ranges , wrap .rangeset );
11601166 }
1161- else array_has_params = true ; /* we have non-const nodes */
1167+ else array_params ++ ; /* we've just met non-const nodes */
11621168 }
11631169
11641170 /* Check for PARAM-related optimizations */
1165- if (array_has_params )
1171+ if (array_params > 0 )
11661172 {
1167- /* We can't say anything if PARAMs + ANY */
1173+ double sel = estimate_paramsel_using_prel (prel , strategy );
1174+ int i ;
1175+
11681176 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 );
11701191
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+ }
11731196 }
11741197
1175- /* Save rangeset */
1198+ /* Save result */
11761199 result -> rangeset = ranges ;
1177-
1178- /* Save expression */
1179- result -> orig = (const Node * ) expr ;
1200+ result -> paramsel = paramsel ;
11801201
11811202 return ; /* done, exit */
11821203 }
@@ -1187,21 +1208,7 @@ handle_arrexpr(const ScalarArrayOpExpr *expr,
11871208
11881209handle_arrexpr_all :
11891210 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 ;
12051212}
12061213
12071214/* Operator expression handler */
0 commit comments