1 /*-------------------------------------------------------------------------
4 * Routines to determine which indices are usable for scanning a
5 * given relation, and create IndexPaths accordingly.
7 * Copyright (c) 1994, Regents of the University of California
11 * $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.65 1999/07/25 23:07:24 tgl Exp $
13 *-------------------------------------------------------------------------
19 #include "access/heapam.h"
20 #include "access/nbtree.h"
21 #include "catalog/catname.h"
22 #include "catalog/pg_amop.h"
23 #include "executor/executor.h"
24 #include "nodes/makefuncs.h"
25 #include "nodes/nodeFuncs.h"
26 #include "optimizer/clauses.h"
27 #include "optimizer/cost.h"
28 #include "optimizer/keys.h"
29 #include "optimizer/ordering.h"
30 #include "optimizer/pathnode.h"
31 #include "optimizer/paths.h"
32 #include "optimizer/plancat.h"
33 #include "optimizer/restrictinfo.h"
34 #include "parser/parse_coerce.h"
35 #include "parser/parse_expr.h"
36 #include "parser/parse_oper.h"
37 #include "parser/parsetree.h"
38 #include "utils/lsyscache.h"
41 static void match_index_orclauses(RelOptInfo *rel, RelOptInfo *index, int indexkey,
42 int xclass, List *restrictinfo_list);
43 static List *match_index_orclause(RelOptInfo *rel, RelOptInfo *index, int indexkey,
44 int xclass, List *or_clauses, List *other_matching_indices);
45 static List *group_clauses_by_indexkey(RelOptInfo *rel, RelOptInfo *index,
46 int *indexkeys, Oid *classes, List *restrictinfo_list);
47 static List *group_clauses_by_ikey_for_joins(RelOptInfo *rel, RelOptInfo *index,
48 int *indexkeys, Oid *classes, List *join_cinfo_list, List *restr_cinfo_list);
49 static bool match_clause_to_indexkey(RelOptInfo *rel, RelOptInfo *index,
50 int indexkey, int xclass,
51 Expr *clause, bool join);
52 static bool pred_test(List *predicate_list, List *restrictinfo_list,
54 static bool one_pred_test(Expr *predicate, List *restrictinfo_list);
55 static bool one_pred_clause_expr_test(Expr *predicate, Node *clause);
56 static bool one_pred_clause_test(Expr *predicate, Node *clause);
57 static bool clause_pred_clause_test(Expr *predicate, Node *clause);
58 static void indexable_joinclauses(RelOptInfo *rel, RelOptInfo *index,
59 List *joininfo_list, List *restrictinfo_list,
60 List **clausegroups, List **outerrelids);
61 static List *index_innerjoin(Query *root, RelOptInfo *rel, RelOptInfo *index,
62 List *clausegroup_list, List *outerrelids_list);
63 static List *create_index_path_group(Query *root, RelOptInfo *rel, RelOptInfo *index,
64 List *clausegroup_list, bool join);
65 static bool match_index_to_operand(int indexkey, Expr *operand,
66 RelOptInfo *rel, RelOptInfo *index);
67 static bool function_index_operand(Expr *funcOpnd, RelOptInfo *rel, RelOptInfo *index);
71 * create_index_paths()
72 * Generate all interesting index paths for the given relation.
74 * To be considered for an index scan, an index must match one or more
75 * restriction clauses or join clauses from the query's qual condition.
77 * Note: an index scan might also be used simply to order the result,
78 * either for use in a mergejoin or to satisfy an ORDER BY request.
79 * That possibility is handled elsewhere.
81 * 'rel' is the relation for which we want to generate index paths
82 * 'indices' is a list of available indexes for 'rel'
83 * 'restrictinfo_list' is a list of restrictinfo nodes for 'rel'
84 * 'joininfo_list' is a list of joininfo nodes for 'rel'
86 * Returns a list of IndexPath access path descriptors.
89 create_index_paths(Query *root,
92 List *restrictinfo_list,
98 foreach(ilist, indices)
100 RelOptInfo *index = (RelOptInfo *) lfirst(ilist);
101 List *scanclausegroups;
102 List *joinclausegroups;
103 List *joinouterrelids;
106 * If this is a partial index, we can only use it if it passes
107 * the predicate test.
109 if (index->indpred != NIL)
110 if (!pred_test(index->indpred, restrictinfo_list, joininfo_list))
114 * 1. Try matching the index against subclauses of restriction 'or'
115 * clauses (ie, 'or' clauses that reference only this relation).
116 * The restrictinfo nodes for the 'or' clauses are marked with lists
117 * of the matching indices. No paths are actually created now;
118 * that will be done in orindxpath.c after all indexes for the rel
119 * have been examined. (We need to do it that way because we can
120 * potentially use a different index for each subclause of an 'or',
121 * so we can't build a path for an 'or' clause until all indexes have
122 * been matched against it.)
124 * We currently only look to match the first key of each index against
125 * 'or' subclauses. There are cases where a later key of a multi-key
126 * index could be used (if other top-level clauses match earlier keys
127 * of the index), but our poor brains are hurting already...
129 * We don't even think about special handling of 'or' clauses that
130 * involve more than one relation, since they can't be processed by
131 * a single indexscan path anyway. Currently, cnfify() is certain
132 * to have restructured any such toplevel 'or' clauses anyway.
134 match_index_orclauses(rel,
141 * 2. If the keys of this index match any of the available non-'or'
142 * restriction clauses, then create a path using those clauses
145 scanclausegroups = group_clauses_by_indexkey(rel,
151 if (scanclausegroups != NIL)
152 retval = nconc(retval,
153 create_index_path_group(root,
160 * 3. If this index can be used with any join clause, then create
161 * pathnodes for each group of usable clauses. An index can be
162 * used with a join clause if its ordering is useful for a
163 * mergejoin, or if the index can possibly be used for scanning
164 * the inner relation of a nestloop join.
166 indexable_joinclauses(rel, index,
167 joininfo_list, restrictinfo_list,
171 if (joinclausegroups != NIL)
173 retval = nconc(retval,
174 create_index_path_group(root,
179 rel->innerjoin = nconc(rel->innerjoin,
180 index_innerjoin(root, rel, index,
190 /****************************************************************************
191 * ---- ROUTINES TO PROCESS 'OR' CLAUSES ----
192 ****************************************************************************/
196 * match_index_orclauses
197 * Attempt to match an index against subclauses within 'or' clauses.
198 * Each subclause that does match is marked with the index's node.
200 * Essentially, this adds 'index' to the list of subclause indices in
201 * the RestrictInfo field of each of the 'or' clauses where it matches.
202 * NOTE: we can use storage in the RestrictInfo for this purpose because
203 * this processing is only done on single-relation restriction clauses.
204 * Therefore, we will never have indexes for more than one relation
205 * mentioned in the same RestrictInfo node's list.
207 * 'rel' is the node of the relation on which the index is defined.
208 * 'index' is the index node.
209 * 'indexkey' is the (single) key of the index that we will consider.
210 * 'class' is the class of the operator corresponding to 'indexkey'.
211 * 'restrictinfo_list' is the list of available restriction clauses.
214 match_index_orclauses(RelOptInfo *rel,
218 List *restrictinfo_list)
222 foreach(i, restrictinfo_list)
224 RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(i);
226 if (restriction_is_or_clause(restrictinfo))
229 * Add this index to the subclause index list for each
230 * subclause that it matches.
232 restrictinfo->indexids =
233 match_index_orclause(rel, index,
235 restrictinfo->clause->args,
236 restrictinfo->indexids);
242 * match_index_orclause
243 * Attempts to match an index against the subclauses of an 'or' clause.
245 * A match means that:
246 * (1) the operator within the subclause can be used with the
247 * index's specified operator class, and
248 * (2) the variable on one side of the subclause matches the index key.
250 * 'or_clauses' is the list of subclauses within the 'or' clause
251 * 'other_matching_indices' is the list of information on other indices
252 * that have already been matched to subclauses within this
253 * particular 'or' clause (i.e., a list previously generated by
254 * this routine), or NIL if this routine has not previously been
255 * run for this 'or' clause.
257 * Returns a list of the form ((a b c) (d e f) nil (g h) ...) where
258 * a,b,c are nodes of indices that match the first subclause in
259 * 'or-clauses', d,e,f match the second subclause, no indices
260 * match the third, g,h match the fourth, etc.
263 match_index_orclause(RelOptInfo *rel,
268 List *other_matching_indices)
270 List *matching_indices;
274 /* first time through, we create list of same length as OR clause,
275 * containing an empty sublist for each subclause.
277 if (!other_matching_indices)
279 matching_indices = NIL;
280 foreach(clist, or_clauses)
281 matching_indices = lcons(NIL, matching_indices);
284 matching_indices = other_matching_indices;
286 index_list = matching_indices;
288 foreach(clist, or_clauses)
290 Expr *clause = lfirst(clist);
292 if (match_clause_to_indexkey(rel, index, indexkey, xclass,
295 /* OK to add this index to sublist for this subclause */
296 lfirst(matching_indices) = lcons(index,
297 lfirst(matching_indices));
300 matching_indices = lnext(matching_indices);
306 /****************************************************************************
307 * ---- ROUTINES TO CHECK RESTRICTIONS ----
308 ****************************************************************************/
312 * DoneMatchingIndexKeys() - MACRO
314 * Determine whether we should continue matching index keys in a clause.
315 * Depends on if there are more to match or if this is a functional index.
316 * In the latter case we stop after the first match since the there can
317 * be only key (i.e. the function's return value) and the attributes in
318 * keys list represent the arguments to the function. -mer 3 Oct. 1991
320 #define DoneMatchingIndexKeys(indexkeys, index) \
321 (indexkeys[0] == 0 || \
322 (index->indproc != InvalidOid))
325 * group_clauses_by_indexkey
326 * Generates a list of restriction clauses that can be used with an index.
328 * 'rel' is the node of the relation itself.
329 * 'index' is a index on 'rel'.
330 * 'indexkeys' are the index keys to be matched.
331 * 'classes' are the classes of the index operators on those keys.
332 * 'restrictinfo_list' is the list of available restriction clauses for 'rel'.
334 * Returns NIL if no clauses can be used with this index.
335 * Otherwise, a list containing a single sublist is returned (indicating
336 * to create_index_path_group() that a single IndexPath should be created).
337 * The sublist contains the RestrictInfo nodes for all clauses that can be
338 * used with this index.
340 * The sublist is ordered by index key (but as far as I can tell, this is
341 * an implementation artifact of this routine, and is not depended on by
342 * any user of the returned list --- tgl 7/99).
344 * Note that in a multi-key index, we stop if we find a key that cannot be
345 * used with any clause. For example, given an index on (A,B,C), we might
346 * return ((C1 C2 C3 C4)) if we find that clauses C1 and C2 use column A,
347 * clauses C3 and C4 use column B, and no clauses use column C. But if no
348 * clauses match B we will return ((C1 C2)), whether or not there are
349 * clauses matching column C, because the executor couldn't use them anyway.
352 group_clauses_by_indexkey(RelOptInfo *rel,
356 List *restrictinfo_list)
358 List *clausegroup_list = NIL;
360 if (restrictinfo_list == NIL || indexkeys[0] == 0)
365 int curIndxKey = indexkeys[0];
366 Oid curClass = classes[0];
367 List *clausegroup = NIL;
370 foreach(curCinfo, restrictinfo_list)
372 RestrictInfo *rinfo = (RestrictInfo *) lfirst(curCinfo);
374 if (match_clause_to_indexkey(rel,
380 clausegroup = lappend(clausegroup, rinfo);
383 /* If no clauses match this key, we're done; we don't want to
384 * look at keys to its right.
386 if (clausegroup == NIL)
389 clausegroup_list = nconc(clausegroup_list, clausegroup);
394 } while (!DoneMatchingIndexKeys(indexkeys, index));
396 /* clausegroup_list holds all matched clauses ordered by indexkeys */
397 if (clausegroup_list != NIL)
398 return lcons(clausegroup_list, NIL);
403 * group_clauses_by_ikey_for_joins
404 * Generates a list of join clauses that can be used with an index.
406 * This is much like group_clauses_by_indexkey(), but we consider both
407 * join and restriction clauses. For each indexkey in the index, we
408 * accept both join and restriction clauses that match it (since both
409 * will make useful indexquals if the index is being used to scan the
410 * inner side of a join). But there must be at least one matching
411 * join clause, or we return NIL indicating that this index isn't useful
415 group_clauses_by_ikey_for_joins(RelOptInfo *rel,
419 List *join_cinfo_list,
420 List *restr_cinfo_list)
422 List *clausegroup_list = NIL;
425 if (join_cinfo_list == NIL || indexkeys[0] == 0)
430 int curIndxKey = indexkeys[0];
431 Oid curClass = classes[0];
432 List *clausegroup = NIL;
435 foreach(curCinfo, join_cinfo_list)
437 RestrictInfo *rinfo = (RestrictInfo *) lfirst(curCinfo);
439 if (match_clause_to_indexkey(rel,
446 clausegroup = lappend(clausegroup, rinfo);
450 foreach(curCinfo, restr_cinfo_list)
452 RestrictInfo *rinfo = (RestrictInfo *) lfirst(curCinfo);
454 if (match_clause_to_indexkey(rel,
460 clausegroup = lappend(clausegroup, rinfo);
463 /* If no clauses match this key, we're done; we don't want to
464 * look at keys to its right.
466 if (clausegroup == NIL)
469 clausegroup_list = nconc(clausegroup_list, clausegroup);
474 } while (!DoneMatchingIndexKeys(indexkeys, index));
476 /* clausegroup_list holds all matched clauses ordered by indexkeys */
478 if (clausegroup_list != NIL)
481 * if no join clause was matched then there ain't clauses for
486 freeList(clausegroup_list);
489 return lcons(clausegroup_list, NIL);
496 * match_clause_to_indexkey()
497 * Determines whether a restriction or join clause matches
500 * To match, the clause must:
501 * (1) be in the form (var op const) for a restriction clause,
502 * or (var op var) for a join clause, where the var or one
503 * of the vars matches the index key; and
504 * (2) contain an operator which is in the same class as the index
505 * operator for this key.
507 * In the restriction case, we can cope with (const op var) by commuting
508 * the clause to (var op const), if there is a commutator operator.
509 * XXX why do we bother to commute? The executor doesn't care!!
511 * In the join case, later code will try to commute the clause if needed
512 * to put the inner relation's var on the right. We have no idea here
513 * which relation might wind up on the inside, so we just accept
514 * a match for either var.
515 * XXX is this right? We are making a list for this relation to
516 * be an inner join relation, so if there is any commuting then
517 * this rel must be on the right. But again, it's not really clear
518 * that we have to commute at all!
520 * 'rel' is the relation of interest.
521 * 'index' is an index on 'rel'.
522 * 'indexkey' is a key of 'index'.
523 * 'xclass' is the corresponding operator class.
524 * 'clause' is the clause to be tested.
525 * 'join' is true if we are considering this clause for joins.
527 * Returns true if the clause can be used with this index key.
529 * NOTE: returns false if clause is an or_clause; that's handled elsewhere.
532 match_clause_to_indexkey(RelOptInfo *rel,
539 bool isIndexable = false;
543 if (! is_opclause((Node *) clause))
545 leftop = get_leftop(clause);
546 rightop = get_rightop(clause);
547 if (! leftop || ! rightop)
553 * Not considering joins, so check for clauses of the form:
554 * (var/func operator constant) and (constant operator var/func)
556 Oid restrict_op = InvalidOid;
559 * Check for standard s-argable clause
561 if (IsA(rightop, Const) || IsA(rightop, Param))
563 restrict_op = ((Oper *) ((Expr *) clause)->oper)->opno;
565 isIndexable = (op_class(restrict_op, xclass, index->relam) &&
566 match_index_to_operand(indexkey,
571 #ifndef IGNORE_BINARY_COMPATIBLE_INDICES
574 * Didn't find an index? Then maybe we can find another
575 * binary-compatible index instead... thomas 1998-08-14
579 Oid ltype = exprType((Node *) leftop);
580 Oid rtype = exprType((Node *) rightop);
583 * make sure we have two different binary-compatible
587 && IS_BINARY_COMPATIBLE(ltype, rtype))
592 opname = get_opname(restrict_op);
594 newop = oper(opname, ltype, ltype, TRUE);
598 /* actually have a different operator to try? */
599 if (HeapTupleIsValid(newop) &&
600 (oprid(newop) != restrict_op))
602 restrict_op = oprid(newop);
604 isIndexable = (op_class(restrict_op, xclass, index->relam) &&
605 match_index_to_operand(indexkey,
611 ((Oper *) ((Expr *) clause)->oper)->opno = restrict_op;
619 * Must try to commute the clause to standard s-arg format.
621 else if (IsA(leftop, Const) || IsA(leftop, Param))
623 restrict_op = get_commutator(((Oper *) ((Expr *) clause)->oper)->opno);
625 isIndexable = ((restrict_op != InvalidOid) &&
626 op_class(restrict_op, xclass, index->relam) &&
627 match_index_to_operand(indexkey,
632 #ifndef IGNORE_BINARY_COMPATIBLE_INDICES
638 ltype = exprType((Node *) leftop);
639 rtype = exprType((Node *) rightop);
642 && IS_BINARY_COMPATIBLE(ltype, rtype))
647 restrict_op = ((Oper *) ((Expr *) clause)->oper)->opno;
649 opname = get_opname(restrict_op);
651 newop = oper(opname, rtype, rtype, TRUE);
655 if (HeapTupleIsValid(newop) && (oprid(newop) != restrict_op))
657 restrict_op = get_commutator(oprid(newop));
659 isIndexable = ((restrict_op != InvalidOid) &&
660 op_class(restrict_op, xclass, index->relam) &&
661 match_index_to_operand(indexkey,
667 ((Oper *) ((Expr *) clause)->oper)->opno = oprid(newop);
677 * In place list modification. (op const var/func) -> (op
680 CommuteClause((Node *) clause);
687 * Check for an indexable scan on one of the join relations.
688 * clause is of the form (operator var/func var/func)
689 * XXX this does not seem right. Should check other side
690 * looks like var/func? do we really want to only consider
691 * this rel on lefthand side??
693 Oid join_op = InvalidOid;
695 if (match_index_to_operand(indexkey, (Expr *) leftop,
697 join_op = ((Oper *) ((Expr *) clause)->oper)->opno;
698 else if (match_index_to_operand(indexkey, (Expr *) rightop,
700 join_op = get_commutator(((Oper *) ((Expr *) clause)->oper)->opno);
702 if (join_op && op_class(join_op, xclass, index->relam) &&
703 is_joinable((Node *) clause))
710 /****************************************************************************
711 * ---- ROUTINES TO DO PARTIAL INDEX PREDICATE TESTS ----
712 ****************************************************************************/
716 * Does the "predicate inclusion test" for partial indexes.
718 * Recursively checks whether the clauses in restrictinfo_list imply
719 * that the given predicate is true.
721 * This routine (together with the routines it calls) iterates over
722 * ANDs in the predicate first, then reduces the qualification
723 * clauses down to their constituent terms, and iterates over ORs
724 * in the predicate last. This order is important to make the test
725 * succeed whenever possible (assuming the predicate has been
726 * successfully cnfify()-ed). --Nels, Jan '93
729 pred_test(List *predicate_list, List *restrictinfo_list, List *joininfo_list)
736 * Note: if Postgres tried to optimize queries by forming equivalence
737 * classes over equi-joined attributes (i.e., if it recognized that a
738 * qualification such as "where a.b=c.d and a.b=5" could make use of
739 * an index on c.d), then we could use that equivalence class info
740 * here with joininfo_list to do more complete tests for the usability
741 * of a partial index. For now, the test only uses restriction
742 * clauses (those in restrictinfo_list). --Nels, Dec '92
745 if (predicate_list == NULL)
746 return true; /* no predicate: the index is usable */
747 if (restrictinfo_list == NULL)
748 return false; /* no restriction clauses: the test must
751 foreach(pred, predicate_list)
755 * if any clause is not implied, the whole predicate is not
758 if (and_clause(lfirst(pred)))
760 items = ((Expr *) lfirst(pred))->args;
763 if (!one_pred_test(lfirst(item), restrictinfo_list))
767 else if (!one_pred_test(lfirst(pred), restrictinfo_list))
776 * Does the "predicate inclusion test" for one conjunct of a predicate
780 one_pred_test(Expr *predicate, List *restrictinfo_list)
782 RestrictInfo *restrictinfo;
785 Assert(predicate != NULL);
786 foreach(item, restrictinfo_list)
788 restrictinfo = (RestrictInfo *) lfirst(item);
789 /* if any clause implies the predicate, return true */
790 if (one_pred_clause_expr_test(predicate, (Node *) restrictinfo->clause))
798 * one_pred_clause_expr_test
799 * Does the "predicate inclusion test" for a general restriction-clause
803 one_pred_clause_expr_test(Expr *predicate, Node *clause)
808 if (is_opclause(clause))
809 return one_pred_clause_test(predicate, clause);
810 else if (or_clause(clause))
812 items = ((Expr *) clause)->args;
815 /* if any OR item doesn't imply the predicate, clause doesn't */
816 if (!one_pred_clause_expr_test(predicate, lfirst(item)))
821 else if (and_clause(clause))
823 items = ((Expr *) clause)->args;
828 * if any AND item implies the predicate, the whole clause
831 if (one_pred_clause_expr_test(predicate, lfirst(item)))
838 /* unknown clause type never implies the predicate */
845 * one_pred_clause_test
846 * Does the "predicate inclusion test" for one conjunct of a predicate
847 * expression for a simple restriction clause.
850 one_pred_clause_test(Expr *predicate, Node *clause)
855 if (is_opclause((Node *) predicate))
856 return clause_pred_clause_test(predicate, clause);
857 else if (or_clause((Node *) predicate))
859 items = predicate->args;
862 /* if any item is implied, the whole predicate is implied */
863 if (one_pred_clause_test(lfirst(item), clause))
868 else if (and_clause((Node *) predicate))
870 items = predicate->args;
875 * if any item is not implied, the whole predicate is not
878 if (!one_pred_clause_test(lfirst(item), clause))
885 elog(DEBUG, "Unsupported predicate type, index will not be used");
892 * Define an "operator implication table" for btree operators ("strategies").
893 * The "strategy numbers" are: (1) < (2) <= (3) = (4) >= (5) >
895 * The interpretation of:
897 * test_op = BT_implic_table[given_op-1][target_op-1]
899 * where test_op, given_op and target_op are strategy numbers (from 1 to 5)
900 * of btree operators, is as follows:
902 * If you know, for some ATTR, that "ATTR given_op CONST1" is true, and you
903 * want to determine whether "ATTR target_op CONST2" must also be true, then
904 * you can use "CONST1 test_op CONST2" as a test. If this test returns true,
905 * then the target expression must be true; if the test returns false, then
906 * the target expression may be false.
908 * An entry where test_op==0 means the implication cannot be determined, i.e.,
909 * this test should always be considered false.
912 static StrategyNumber
913 BT_implic_table[BTMaxStrategyNumber][BTMaxStrategyNumber] = {
923 * clause_pred_clause_test
924 * Use operator class info to check whether clause implies predicate.
926 * Does the "predicate inclusion test" for a "simple clause" predicate
927 * for a single "simple clause" restriction. Currently, this only handles
928 * (binary boolean) operators that are in some btree operator class.
929 * Eventually, rtree operators could also be handled by defining an
930 * appropriate "RT_implic_table" array.
933 clause_pred_clause_test(Expr *predicate, Node *clause)
943 StrategyNumber pred_strategy,
953 ScanKeyData entry[3];
956 pred_var = (Var *) get_leftop(predicate);
957 pred_const = (Const *) get_rightop(predicate);
958 clause_var = (Var *) get_leftop((Expr *) clause);
959 clause_const = (Const *) get_rightop((Expr *) clause);
961 /* Check the basic form; for now, only allow the simplest case */
962 if (!is_opclause(clause) ||
963 !IsA(clause_var, Var) ||
964 clause_const == NULL ||
965 !IsA(clause_const, Const) ||
966 !IsA(predicate->oper, Oper) ||
967 !IsA(pred_var, Var) ||
968 !IsA(pred_const, Const))
972 * The implication can't be determined unless the predicate and the
973 * clause refer to the same attribute.
975 if (clause_var->varattno != pred_var->varattno)
978 /* Get the operators for the two clauses we're comparing */
979 pred_op = ((Oper *) ((Expr *) predicate)->oper)->opno;
980 clause_op = ((Oper *) ((Expr *) clause)->oper)->opno;
984 * 1. Find a "btree" strategy number for the pred_op
986 ScanKeyEntryInitialize(&entry[0], 0,
989 ObjectIdGetDatum(BTREE_AM_OID));
991 ScanKeyEntryInitialize(&entry[1], 0,
992 Anum_pg_amop_amopopr,
994 ObjectIdGetDatum(pred_op));
996 relation = heap_openr(AccessMethodOperatorRelationName);
999 * The following assumes that any given operator will only be in a
1000 * single btree operator class. This is true at least for all the
1001 * pre-defined operator classes. If it isn't true, then whichever
1002 * operator class happens to be returned first for the given operator
1003 * will be used to find the associated strategy numbers for the test.
1006 scan = heap_beginscan(relation, false, SnapshotNow, 2, entry);
1007 tuple = heap_getnext(scan, 0);
1008 if (!HeapTupleIsValid(tuple))
1010 elog(DEBUG, "clause_pred_clause_test: unknown pred_op");
1013 aform = (Form_pg_amop) GETSTRUCT(tuple);
1015 /* Get the predicate operator's strategy number (1 to 5) */
1016 pred_strategy = (StrategyNumber) aform->amopstrategy;
1018 /* Remember which operator class this strategy number came from */
1019 opclass_id = aform->amopclaid;
1025 * 2. From the same opclass, find a strategy num for the clause_op
1027 ScanKeyEntryInitialize(&entry[1], 0,
1028 Anum_pg_amop_amopclaid,
1030 ObjectIdGetDatum(opclass_id));
1032 ScanKeyEntryInitialize(&entry[2], 0,
1033 Anum_pg_amop_amopopr,
1035 ObjectIdGetDatum(clause_op));
1037 scan = heap_beginscan(relation, false, SnapshotNow, 3, entry);
1038 tuple = heap_getnext(scan, 0);
1039 if (!HeapTupleIsValid(tuple))
1041 elog(DEBUG, "clause_pred_clause_test: unknown clause_op");
1044 aform = (Form_pg_amop) GETSTRUCT(tuple);
1046 /* Get the restriction clause operator's strategy number (1 to 5) */
1047 clause_strategy = (StrategyNumber) aform->amopstrategy;
1052 * 3. Look up the "test" strategy number in the implication table
1055 test_strategy = BT_implic_table[clause_strategy - 1][pred_strategy - 1];
1056 if (test_strategy == 0)
1057 return false; /* the implication cannot be determined */
1061 * 4. From the same opclass, find the operator for the test strategy
1064 ScanKeyEntryInitialize(&entry[2], 0,
1065 Anum_pg_amop_amopstrategy,
1067 Int16GetDatum(test_strategy));
1069 scan = heap_beginscan(relation, false, SnapshotNow, 3, entry);
1070 tuple = heap_getnext(scan, 0);
1071 if (!HeapTupleIsValid(tuple))
1073 elog(DEBUG, "clause_pred_clause_test: unknown test_op");
1076 aform = (Form_pg_amop) GETSTRUCT(tuple);
1078 /* Get the test operator */
1079 test_op = aform->amopopr;
1084 * 5. Evaluate the test
1086 test_oper = makeOper(test_op, /* opno */
1087 InvalidOid, /* opid */
1088 BOOLOID, /* opresulttype */
1090 NULL); /* op_fcache */
1091 replace_opid(test_oper);
1093 test_expr = make_opclause(test_oper,
1094 copyObject(clause_const),
1095 copyObject(pred_const));
1097 #ifndef OMIT_PARTIAL_INDEX
1098 test_result = ExecEvalExpr((Node *) test_expr, NULL, &isNull, NULL);
1099 #endif /* OMIT_PARTIAL_INDEX */
1102 elog(DEBUG, "clause_pred_clause_test: null test result");
1109 /****************************************************************************
1110 * ---- ROUTINES TO CHECK JOIN CLAUSES ----
1111 ****************************************************************************/
1114 * indexable_joinclauses
1115 * Finds all groups of join clauses from among 'joininfo_list' that can
1116 * be used in conjunction with 'index'.
1118 * Each clause group comes from a single joininfo node plus the current
1119 * rel's restrictinfo list. Therefore, every clause in the group references
1120 * the current rel plus the same set of other rels (except for the restrict
1121 * clauses, which only reference the current rel). Therefore, this set
1122 * of clauses could be used as an indexqual if the relation is scanned
1123 * as the inner side of a nestloop join when the outer side contains
1124 * (at least) all those "other rels".
1126 * XXX Actually, given that we are considering a join that requires an
1127 * outer rel set (A,B,C), we should use all qual clauses that reference
1128 * any subset of these rels, not just the full set or none. This is
1129 * doable with a doubly nested loop over joininfo_list; is it worth it?
1131 * Returns two parallel lists of the same length: the clause groups,
1132 * and the required outer rel set for each one.
1134 * 'rel' is the relation for which 'index' is defined
1135 * 'joininfo_list' is the list of JoinInfo nodes for 'rel'
1136 * 'restrictinfo_list' is the list of restriction clauses for 'rel'
1137 * '*clausegroups' receives a list of clause sublists
1138 * '*outerrelids' receives a list of relid lists
1141 indexable_joinclauses(RelOptInfo *rel, RelOptInfo *index,
1142 List *joininfo_list, List *restrictinfo_list,
1143 List **clausegroups, List **outerrelids)
1145 List *cg_list = NIL;
1146 List *relid_list = NIL;
1149 foreach(i, joininfo_list)
1151 JoinInfo *joininfo = (JoinInfo *) lfirst(i);
1154 if (joininfo->jinfo_restrictinfo == NIL)
1156 clausegroups = group_clauses_by_ikey_for_joins(rel,
1160 joininfo->jinfo_restrictinfo,
1164 * This code knows that group_clauses_by_ikey_for_joins() returns
1165 * either NIL or a list containing a single sublist of clauses.
1167 * cg_list = nconc(cg_list, clausegroups);
1169 * cg_list = lappend(cg_list, lfirst(clausegroups));
1170 * That is, we are appending the only sublist returned by
1171 * group_clauses_by_ikey_for_joins() to the list of clause sublists
1172 * that this routine will return. By using nconc() we recycle
1173 * a cons cell that would be wasted ... whoever wrote this code
1174 * was too clever by half...
1177 if (clausegroups != NIL)
1179 cg_list = nconc(cg_list, clausegroups);
1180 relid_list = lappend(relid_list, joininfo->unjoined_relids);
1184 /* Make sure above clever code didn't screw up */
1185 Assert(length(cg_list) == length(relid_list));
1187 *clausegroups = cg_list;
1188 *outerrelids = relid_list;
1191 /****************************************************************************
1192 * ---- PATH CREATION UTILITIES ----
1193 ****************************************************************************/
1197 * Creates index path nodes corresponding to paths to be used as inner
1198 * relations in nestloop joins.
1200 * 'rel' is the relation for which 'index' is defined
1201 * 'clausegroup_list' is a list of lists of restrictinfo nodes which can use
1202 * 'index' on their inner relation.
1203 * 'outerrelids_list' is a list of the required outer rels for each group
1206 * Returns a list of index pathnodes.
1209 index_innerjoin(Query *root, RelOptInfo *rel, RelOptInfo *index,
1210 List *clausegroup_list, List *outerrelids_list)
1212 List *path_list = NIL;
1215 foreach(i, clausegroup_list)
1217 List *clausegroup = lfirst(i);
1218 IndexPath *pathnode = makeNode(IndexPath);
1223 indexquals = get_actual_clauses(clausegroup);
1225 index_selectivity(root,
1226 lfirsti(rel->relids),
1227 lfirsti(index->relids),
1232 /* XXX this code ought to be merged with create_index_path */
1234 pathnode->path.pathtype = T_IndexScan;
1235 pathnode->path.parent = rel;
1236 pathnode->path.pathorder = makeNode(PathOrder);
1237 pathnode->path.pathorder->ordtype = SORTOP_ORDER;
1238 pathnode->path.pathorder->ord.sortop = index->ordering;
1239 pathnode->path.pathkeys = NIL;
1241 /* Note that we are making a pathnode for a single-scan indexscan;
1242 * therefore, both indexid and indexqual should be single-element
1245 pathnode->indexid = index->relids;
1246 pathnode->indexkeys = index->indexkeys;
1247 pathnode->indexqual = lcons(indexquals, NIL);
1249 /* joinid saves the rels needed on the outer side of the join */
1250 pathnode->path.joinid = lfirst(outerrelids_list);
1252 pathnode->path.path_cost = cost_index((Oid) lfirsti(index->relids),
1262 * copy restrictinfo list into path for expensive function
1263 * processing -- JMH, 7/7/92
1265 pathnode->path.loc_restrictinfo = set_difference(copyObject((Node *) rel->restrictinfo),
1268 #ifdef NOT_USED /* fix xfunc */
1269 /* add in cost for expensive functions! -- JMH, 7/7/92 */
1270 if (XfuncMode != XFUNC_OFF)
1271 ((Path *) pathnode)->path_cost += xfunc_get_path_cost((Path *) pathnode);
1273 path_list = lappend(path_list, pathnode);
1274 outerrelids_list = lnext(outerrelids_list);
1280 * create_index_path_group
1281 * Creates a list of index path nodes for each group of clauses
1282 * (restriction or join) that can be used in conjunction with an index.
1284 * 'rel' is the relation for which 'index' is defined
1285 * 'clausegroup_list' is the list of clause groups (lists of restrictinfo
1286 * nodes) grouped by mergejoinorder
1287 * 'join' is a flag indicating whether or not the clauses are join
1290 * Returns a list of new index path nodes.
1294 create_index_path_group(Query *root,
1297 List *clausegroup_list,
1300 List *path_list = NIL;
1303 foreach(i, clausegroup_list)
1305 List *clausegroup = lfirst(i);
1312 foreach(j, clausegroup)
1314 RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(j);
1315 if (!(is_joinable((Node *) restrictinfo->clause) &&
1316 equal_path_merge_ordering(index->ordering,
1317 restrictinfo->mergejoinorder)))
1327 path_list = lappend(path_list,
1328 create_index_path(root, rel, index,
1329 clausegroup, join));
1335 /****************************************************************************
1336 * ---- ROUTINES TO CHECK OPERANDS ----
1337 ****************************************************************************/
1340 * match_index_to_operand()
1341 * Generalized test for a match between an index's key
1342 * and the operand on one side of a restriction or join clause.
1343 * Now check for functional indices as well.
1346 match_index_to_operand(int indexkey,
1351 if (index->indproc == InvalidOid)
1356 return match_indexkey_operand(indexkey, (Var *) operand, rel);
1360 * functional index check
1362 return function_index_operand(operand, rel, index);
1366 function_index_operand(Expr *funcOpnd, RelOptInfo *rel, RelOptInfo *index)
1368 Oid heapRelid = (Oid) lfirsti(rel->relids);
1371 int *indexKeys = index->indexkeys;
1376 * sanity check, make sure we know what we're dealing with here.
1378 if (funcOpnd == NULL ||
1379 nodeTag(funcOpnd) != T_Expr || funcOpnd->opType != FUNC_EXPR ||
1380 funcOpnd->oper == NULL || indexKeys == NULL)
1383 function = (Func *) funcOpnd->oper;
1384 funcargs = funcOpnd->args;
1386 if (function->funcid != index->indproc)
1390 * Check that the arguments correspond to the same arguments used to
1391 * create the functional index. To do this we must check that 1.
1392 * refer to the right relatiion. 2. the args have the right attr.
1393 * numbers in the right order.
1395 * Check all args refer to the correct relation (i.e. the one with the
1396 * functional index defined on it (rel). To do this we can simply
1397 * compare range table entry numbers, they must be the same.
1399 foreach(arg, funcargs)
1401 if (heapRelid != ((Var *) lfirst(arg))->varno)
1406 * check attr numbers and order.
1409 foreach(arg, funcargs)
1411 if (indexKeys[i] == 0)
1414 if (((Var *) lfirst(arg))->varattno != indexKeys[i])