99 *
1010 *
1111 * IDENTIFICATION
12- * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.204 2006/04/09 18:18:41 tgl Exp $
12+ * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.205 2006/05/18 17:12:10 tgl Exp $
1313 *
1414 *-------------------------------------------------------------------------
1515 */
@@ -50,6 +50,10 @@ static List *find_usable_indexes(PlannerInfo *root, RelOptInfo *rel,
5050bool istoplevel ,bool isjoininner ,
5151Relids outer_relids ,
5252SaOpControl saop_control );
53+ static List * find_saop_paths (PlannerInfo * root ,RelOptInfo * rel ,
54+ List * clauses ,List * outer_clauses ,
55+ bool istoplevel ,bool isjoininner ,
56+ Relids outer_relids );
5357static Path * choose_bitmap_and (PlannerInfo * root ,RelOptInfo * rel ,List * paths );
5458static int bitmap_path_comparator (const void * a ,const void * b );
5559static Cost bitmap_and_cost_est (PlannerInfo * root ,RelOptInfo * rel ,List * paths );
@@ -189,6 +193,15 @@ create_index_paths(PlannerInfo *root, RelOptInfo *rel)
189193 false,NULL );
190194bitindexpaths = list_concat (bitindexpaths ,indexpaths );
191195
196+ /*
197+ * Likewise, generate paths using ScalarArrayOpExpr clauses; these can't
198+ * be simple indexscans but they can be used in bitmap scans.
199+ */
200+ indexpaths = find_saop_paths (root ,rel ,
201+ rel -> baserestrictinfo ,NIL ,
202+ true, false,NULL );
203+ bitindexpaths = list_concat (bitindexpaths ,indexpaths );
204+
192205/*
193206 * If we found anything usable, generate a BitmapHeapPath for the most
194207 * promising combination of bitmap index paths.
@@ -279,10 +292,6 @@ find_usable_indexes(PlannerInfo *root, RelOptInfo *rel,
279292 * predOK index to an arm of an OR, which would be a legal but
280293 * pointlessly inefficient plan. (A better plan will be generated by
281294 * just scanning the predOK index alone, no OR.)
282- *
283- * If saop_control is SAOP_REQUIRE and istoplevel is false, the caller
284- * is only interested in indexquals involving ScalarArrayOps, so don't
285- * set useful_predicate to true.
286295 */
287296useful_predicate = false;
288297if (index -> indpred != NIL )
@@ -308,8 +317,7 @@ find_usable_indexes(PlannerInfo *root, RelOptInfo *rel,
308317if (!predicate_implied_by (index -> indpred ,all_clauses ))
309318continue ;/* can't use it at all */
310319
311- if (saop_control != SAOP_REQUIRE &&
312- !predicate_implied_by (index -> indpred ,outer_clauses ))
320+ if (!predicate_implied_by (index -> indpred ,outer_clauses ))
313321useful_predicate = true;
314322}
315323}
@@ -398,11 +406,54 @@ find_usable_indexes(PlannerInfo *root, RelOptInfo *rel,
398406}
399407
400408
409+ /*
410+ * find_saop_paths
411+ *Find all the potential indexpaths that make use of ScalarArrayOpExpr
412+ *clauses. The executor only supports these in bitmap scans, not
413+ *plain indexscans, so we need to segregate them from the normal case.
414+ *Otherwise, same API as find_usable_indexes().
415+ *Returns a list of IndexPaths.
416+ */
417+ static List *
418+ find_saop_paths (PlannerInfo * root ,RelOptInfo * rel ,
419+ List * clauses ,List * outer_clauses ,
420+ bool istoplevel ,bool isjoininner ,
421+ Relids outer_relids )
422+ {
423+ bool have_saop = false;
424+ ListCell * l ;
425+
426+ /*
427+ * Since find_usable_indexes is relatively expensive, don't bother to
428+ * run it unless there are some top-level ScalarArrayOpExpr clauses.
429+ */
430+ foreach (l ,clauses )
431+ {
432+ RestrictInfo * rinfo = (RestrictInfo * )lfirst (l );
433+
434+ Assert (IsA (rinfo ,RestrictInfo ));
435+ if (IsA (rinfo -> clause ,ScalarArrayOpExpr ))
436+ {
437+ have_saop = true;
438+ break ;
439+ }
440+ }
441+ if (!have_saop )
442+ return NIL ;
443+
444+ return find_usable_indexes (root ,rel ,
445+ clauses ,outer_clauses ,
446+ istoplevel ,isjoininner ,
447+ outer_relids ,
448+ SAOP_REQUIRE );
449+ }
450+
451+
401452/*
402453 * generate_bitmap_or_paths
403- *Look through the list of clauses to find OR clauses and
404- *ScalarArrayOpExpr clauses, and generate a BitmapOrPath for each one
405- *we can handle that way. Return a list of the generated BitmapOrPaths.
454+ *Look through the list of clauses to find OR clauses, and generate
455+ *a BitmapOrPath for each one we can handle that way. Return a list
456+ *of the generated BitmapOrPaths.
406457 *
407458 * outer_clauses is a list of additional clauses that can be assumed true
408459 * for the purpose of generating indexquals, but are not to be searched for
@@ -416,7 +467,6 @@ generate_bitmap_or_paths(PlannerInfo *root, RelOptInfo *rel,
416467{
417468List * result = NIL ;
418469List * all_clauses ;
419- bool have_saop = false;
420470ListCell * l ;
421471
422472/*
@@ -433,16 +483,9 @@ generate_bitmap_or_paths(PlannerInfo *root, RelOptInfo *rel,
433483ListCell * j ;
434484
435485Assert (IsA (rinfo ,RestrictInfo ));
436- /*
437- * In this loop we ignore RestrictInfos that aren't ORs; but take
438- * note of ScalarArrayOpExpr for later.
439- */
486+ /* Ignore RestrictInfos that aren't ORs */
440487if (!restriction_is_or_clause (rinfo ))
441- {
442- if (IsA (rinfo -> clause ,ScalarArrayOpExpr ))
443- have_saop = true;
444488continue ;
445- }
446489
447490/*
448491 * We must be able to match at least one index to each of the arms of
@@ -516,29 +559,6 @@ generate_bitmap_or_paths(PlannerInfo *root, RelOptInfo *rel,
516559}
517560}
518561
519- /*
520- * If we saw any top-level ScalarArrayOpExpr clauses, see if we can
521- * generate a bitmap index path that uses those but not any OR clauses.
522- */
523- if (have_saop )
524- {
525- List * pathlist ;
526- Path * bitmapqual ;
527-
528- pathlist = find_usable_indexes (root ,rel ,
529- clauses ,
530- outer_clauses ,
531- false,
532- isjoininner ,
533- outer_relids ,
534- SAOP_REQUIRE );
535- if (pathlist != NIL )
536- {
537- bitmapqual = (Path * )create_bitmap_or_path (root ,rel ,pathlist );
538- result = lappend (result ,bitmapqual );
539- }
540- }
541-
542562return result ;
543563}
544564
@@ -1429,14 +1449,24 @@ best_inner_indexscan(PlannerInfo *root, RelOptInfo *rel,
14291449SAOP_FORBID );
14301450
14311451/*
1432- * Generate BitmapOrPaths for any suitable OR-clausesor ScalarArrayOpExpr
1433- *clauses present in the clause list.
1452+ * Generate BitmapOrPaths for any suitable OR-clausespresent in the
1453+ * clause list.
14341454 */
14351455bitindexpaths = generate_bitmap_or_paths (root ,rel ,
14361456clause_list ,NIL ,
14371457 true,
14381458outer_relids );
14391459
1460+ /*
1461+ * Likewise, generate paths using ScalarArrayOpExpr clauses; these can't
1462+ * be simple indexscans but they can be used in bitmap scans.
1463+ */
1464+ bitindexpaths = list_concat (bitindexpaths ,
1465+ find_saop_paths (root ,rel ,
1466+ clause_list ,NIL ,
1467+ false, true,
1468+ outer_relids ));
1469+
14401470/*
14411471 * Include the regular index paths in bitindexpaths.
14421472 */