From 43d32d368378e061d29f7ece94fb4a453ae6be63 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 13 Sep 1999 00:17:25 +0000 Subject: First cut at doing something reasonable with OR-of-ANDs WHERE conditions. There are some pretty bogus heuristics in prepqual.c that try to decide whether to output CNF or DNF format; they need to be replaced, likely. Right now the code is probably too willing to choose DNF form, which might hurt performance in some cases that used to work OK. But at least we have a foundation to build on. --- src/backend/optimizer/path/indxpath.c | 44 +++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) (limited to 'src/backend/optimizer/path/indxpath.c') diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c index 6af480629e2..68fb4eda07e 100644 --- a/src/backend/optimizer/path/indxpath.c +++ b/src/backend/optimizer/path/indxpath.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.70 1999/08/21 03:49:00 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.71 1999/09/13 00:17:19 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -48,6 +48,9 @@ static void match_index_orclauses(RelOptInfo *rel, RelOptInfo *index, int indexk int xclass, List *restrictinfo_list); static List *match_index_orclause(RelOptInfo *rel, RelOptInfo *index, int indexkey, int xclass, List *or_clauses, List *other_matching_indices); +static bool match_or_subclause_to_indexkey(RelOptInfo *rel, RelOptInfo *index, + int indexkey, int xclass, + Expr *clause); static List *group_clauses_by_indexkey(RelOptInfo *rel, RelOptInfo *index, int *indexkeys, Oid *classes, List *restrictinfo_list); static List *group_clauses_by_ikey_for_joins(RelOptInfo *rel, RelOptInfo *index, @@ -327,8 +330,8 @@ match_index_orclause(RelOptInfo *rel, { Expr *clause = lfirst(clist); - if (match_clause_to_indexkey(rel, index, indexkey, xclass, - clause, false)) + if (match_or_subclause_to_indexkey(rel, index, indexkey, xclass, + clause)) { /* OK to add this index to sublist for this subclause */ lfirst(matching_indices) = lcons(index, @@ -341,6 +344,38 @@ match_index_orclause(RelOptInfo *rel, return index_list; } +/* + * See if a subclause of an OR clause matches an index. + * + * We accept the subclause if it is an operator clause that matches the + * index, or if it is an AND clause all of whose members are operators + * that match the index. (XXX Would accepting a single match be useful?) + */ +static bool +match_or_subclause_to_indexkey(RelOptInfo *rel, + RelOptInfo *index, + int indexkey, + int xclass, + Expr *clause) +{ + if (and_clause((Node *) clause)) + { + List *item; + + foreach(item, clause->args) + { + if (! match_clause_to_indexkey(rel, index, indexkey, xclass, + lfirst(item), false)) + return false; + } + return true; + } + else + return match_clause_to_indexkey(rel, index, indexkey, xclass, + clause, false); +} + + /**************************************************************************** * ---- ROUTINES TO CHECK RESTRICTIONS ---- ****************************************************************************/ @@ -559,7 +594,8 @@ group_clauses_by_ikey_for_joins(RelOptInfo *rel, * * Returns true if the clause can be used with this index key. * - * NOTE: returns false if clause is an or_clause; that's handled elsewhere. + * NOTE: returns false if clause is an OR or AND clause; to the extent + * we cope with those at all, it is done by higher-level routines. */ static bool match_clause_to_indexkey(RelOptInfo *rel, -- cgit v1.2.3