*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.204 2006/04/09 18:18:41 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.205 2006/05/18 17:12:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
bool istoplevel, bool isjoininner,
Relids outer_relids,
SaOpControl saop_control);
+static List *find_saop_paths(PlannerInfo *root, RelOptInfo *rel,
+ List *clauses, List *outer_clauses,
+ bool istoplevel, bool isjoininner,
+ Relids outer_relids);
static Path *choose_bitmap_and(PlannerInfo *root, RelOptInfo *rel, List *paths);
static int bitmap_path_comparator(const void *a, const void *b);
static Cost bitmap_and_cost_est(PlannerInfo *root, RelOptInfo *rel, List *paths);
false, NULL);
bitindexpaths = list_concat(bitindexpaths, indexpaths);
+ /*
+ * Likewise, generate paths using ScalarArrayOpExpr clauses; these can't
+ * be simple indexscans but they can be used in bitmap scans.
+ */
+ indexpaths = find_saop_paths(root, rel,
+ rel->baserestrictinfo, NIL,
+ true, false, NULL);
+ bitindexpaths = list_concat(bitindexpaths, indexpaths);
+
/*
* If we found anything usable, generate a BitmapHeapPath for the most
* promising combination of bitmap index paths.
* predOK index to an arm of an OR, which would be a legal but
* pointlessly inefficient plan. (A better plan will be generated by
* just scanning the predOK index alone, no OR.)
- *
- * If saop_control is SAOP_REQUIRE and istoplevel is false, the caller
- * is only interested in indexquals involving ScalarArrayOps, so don't
- * set useful_predicate to true.
*/
useful_predicate = false;
if (index->indpred != NIL)
if (!predicate_implied_by(index->indpred, all_clauses))
continue; /* can't use it at all */
- if (saop_control != SAOP_REQUIRE &&
- !predicate_implied_by(index->indpred, outer_clauses))
+ if (!predicate_implied_by(index->indpred, outer_clauses))
useful_predicate = true;
}
}
}
+/*
+ * find_saop_paths
+ * Find all the potential indexpaths that make use of ScalarArrayOpExpr
+ * clauses. The executor only supports these in bitmap scans, not
+ * plain indexscans, so we need to segregate them from the normal case.
+ * Otherwise, same API as find_usable_indexes().
+ * Returns a list of IndexPaths.
+ */
+static List *
+find_saop_paths(PlannerInfo *root, RelOptInfo *rel,
+ List *clauses, List *outer_clauses,
+ bool istoplevel, bool isjoininner,
+ Relids outer_relids)
+{
+ bool have_saop = false;
+ ListCell *l;
+
+ /*
+ * Since find_usable_indexes is relatively expensive, don't bother to
+ * run it unless there are some top-level ScalarArrayOpExpr clauses.
+ */
+ foreach(l, clauses)
+ {
+ RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
+
+ Assert(IsA(rinfo, RestrictInfo));
+ if (IsA(rinfo->clause, ScalarArrayOpExpr))
+ {
+ have_saop = true;
+ break;
+ }
+ }
+ if (!have_saop)
+ return NIL;
+
+ return find_usable_indexes(root, rel,
+ clauses, outer_clauses,
+ istoplevel, isjoininner,
+ outer_relids,
+ SAOP_REQUIRE);
+}
+
+
/*
* generate_bitmap_or_paths
- * Look through the list of clauses to find OR clauses and
- * ScalarArrayOpExpr clauses, and generate a BitmapOrPath for each one
- * we can handle that way. Return a list of the generated BitmapOrPaths.
+ * Look through the list of clauses to find OR clauses, and generate
+ * a BitmapOrPath for each one we can handle that way. Return a list
+ * of the generated BitmapOrPaths.
*
* outer_clauses is a list of additional clauses that can be assumed true
* for the purpose of generating indexquals, but are not to be searched for
{
List *result = NIL;
List *all_clauses;
- bool have_saop = false;
ListCell *l;
/*
ListCell *j;
Assert(IsA(rinfo, RestrictInfo));
- /*
- * In this loop we ignore RestrictInfos that aren't ORs; but take
- * note of ScalarArrayOpExpr for later.
- */
+ /* Ignore RestrictInfos that aren't ORs */
if (!restriction_is_or_clause(rinfo))
- {
- if (IsA(rinfo->clause, ScalarArrayOpExpr))
- have_saop = true;
continue;
- }
/*
* We must be able to match at least one index to each of the arms of
}
}
- /*
- * If we saw any top-level ScalarArrayOpExpr clauses, see if we can
- * generate a bitmap index path that uses those but not any OR clauses.
- */
- if (have_saop)
- {
- List *pathlist;
- Path *bitmapqual;
-
- pathlist = find_usable_indexes(root, rel,
- clauses,
- outer_clauses,
- false,
- isjoininner,
- outer_relids,
- SAOP_REQUIRE);
- if (pathlist != NIL)
- {
- bitmapqual = (Path *) create_bitmap_or_path(root, rel, pathlist);
- result = lappend(result, bitmapqual);
- }
- }
-
return result;
}
SAOP_FORBID);
/*
- * Generate BitmapOrPaths for any suitable OR-clauses or ScalarArrayOpExpr
- * clauses present in the clause list.
+ * Generate BitmapOrPaths for any suitable OR-clauses present in the
+ * clause list.
*/
bitindexpaths = generate_bitmap_or_paths(root, rel,
clause_list, NIL,
true,
outer_relids);
+ /*
+ * Likewise, generate paths using ScalarArrayOpExpr clauses; these can't
+ * be simple indexscans but they can be used in bitmap scans.
+ */
+ bitindexpaths = list_concat(bitindexpaths,
+ find_saop_paths(root, rel,
+ clause_list, NIL,
+ false, true,
+ outer_relids));
+
/*
* Include the regular index paths in bitindexpaths.
*/