@@ -1080,6 +1080,9 @@ handle_arrexpr(const ScalarArrayOpExpr *expr,
10801080tce = lookup_type_cache (prel -> ev_type ,TYPECACHE_BTREE_OPFAMILY );
10811081strategy = 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 */
10841087if (!match_expr_to_operand (context -> prel_expr ,part_expr ))
10851088gotohandle_arrexpr_all ;
@@ -1097,10 +1100,12 @@ handle_arrexpr(const ScalarArrayOpExpr *expr,
10971100
10981101/* Array is NULL */
10991102if (c -> constisnull )
1100- gotohandle_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 */
11061111handle_array (DatumGetArrayTypeP (c -> constvalue ),
@@ -1114,7 +1119,8 @@ handle_arrexpr(const ScalarArrayOpExpr *expr,
11141119{
11151120ArrayExpr * arr_expr = (ArrayExpr * )array ;
11161121Oid elem_type = arr_expr -> element_typeid ;
1117- bool array_has_params = false;
1122+ int array_params = 0 ;
1123+ double paramsel = 1.0 ;
11181124List * ranges ;
11191125ListCell * lc ;
11201126
@@ -1158,25 +1164,40 @@ handle_arrexpr(const ScalarArrayOpExpr *expr,
11581164irange_list_union (ranges ,wrap .rangeset ) :
11591165irange_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+
11681176if (expr -> useOr )
1169- gotohandle_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- /* Saverangeset */
1198+ /* Saveresult */
11761199result -> rangeset = ranges ;
1177-
1178- /* Save expression */
1179- result -> orig = (const Node * )expr ;
1200+ result -> paramsel = paramsel ;
11801201
11811202return ;/* done, exit */
11821203}
@@ -1187,21 +1208,7 @@ handle_arrexpr(const ScalarArrayOpExpr *expr,
11871208
11881209handle_arrexpr_all :
11891210result -> 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 */