1 /*-------------------------------------------------------------------------
4 * Routines to determine which indices are usable for scanning a
7 * Copyright (c) 1994, Regents of the University of California
11 * $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.51 1999/02/18 00:49:18 momjian Exp $
13 *-------------------------------------------------------------------------
19 #include "access/attnum.h"
20 #include "access/heapam.h"
21 #include "access/nbtree.h"
22 #include "catalog/catname.h"
23 #include "catalog/pg_amop.h"
24 #include "catalog/pg_type.h"
25 #include "executor/executor.h"
27 #include "nodes/makefuncs.h"
28 #include "nodes/nodeFuncs.h"
29 #include "nodes/pg_list.h"
30 #include "nodes/relation.h"
31 #include "optimizer/clauses.h"
32 #include "optimizer/restrictinfo.h"
33 #include "optimizer/cost.h"
34 #include "optimizer/internal.h"
35 #include "optimizer/keys.h"
36 #include "optimizer/ordering.h"
37 #include "optimizer/paths.h"
38 #include "optimizer/plancat.h"
39 #include "optimizer/pathnode.h"
40 #include "optimizer/xfunc.h"
41 #include "parser/parsetree.h" /* for getrelid() */
42 #include "parser/parse_expr.h" /* for exprType() */
43 #include "parser/parse_oper.h" /* for oprid() and oper() */
44 #include "parser/parse_coerce.h"/* for IS_BINARY_COMPATIBLE() */
45 #include "utils/lsyscache.h"
48 static void match_index_orclauses(RelOptInfo *rel, RelOptInfo *index, int indexkey,
49 int xclass, List *restrictinfo_list);
50 static bool match_index_to_operand(int indexkey, Expr *operand,
51 RelOptInfo *rel, RelOptInfo *index);
52 static List *match_index_orclause(RelOptInfo *rel, RelOptInfo *index, int indexkey,
53 int xclass, List *or_clauses, List *other_matching_indices);
54 static List *group_clauses_by_indexkey(RelOptInfo *rel, RelOptInfo *index,
55 int *indexkeys, Oid *classes, List *restrictinfo_list);
56 static List *group_clauses_by_ikey_for_joins(RelOptInfo *rel, RelOptInfo *index,
57 int *indexkeys, Oid *classes, List *join_cinfo_list, List *restr_cinfo_list);
58 static RestrictInfo *match_clause_to_indexkey(RelOptInfo *rel, RelOptInfo *index, int indexkey,
59 int xclass, RestrictInfo *restrictInfo, bool join);
60 static bool pred_test(List *predicate_list, List *restrictinfo_list,
62 static bool one_pred_test(Expr *predicate, List *restrictinfo_list);
63 static bool one_pred_clause_expr_test(Expr *predicate, Node *clause);
64 static bool one_pred_clause_test(Expr *predicate, Node *clause);
65 static bool clause_pred_clause_test(Expr *predicate, Node *clause);
66 static List *indexable_joinclauses(RelOptInfo *rel, RelOptInfo *index,
67 List *joininfo_list, List *restrictinfo_list);
68 static List *index_innerjoin(Query *root, RelOptInfo *rel,
69 List *clausegroup_list, RelOptInfo *index);
70 static List *create_index_path_group(Query *root, RelOptInfo *rel, RelOptInfo *index,
71 List *clausegroup_list, bool join);
72 static List *add_index_paths(List *indexpaths, List *new_indexpaths);
73 static bool function_index_operand(Expr *funcOpnd, RelOptInfo *rel, RelOptInfo *index);
77 * Finds all possible index paths by determining which indices in the
78 * list 'indices' are usable.
80 * To be usable, an index must match against either a set of
81 * restriction clauses or join clauses.
83 * Note that the current implementation requires that there exist
84 * matching clauses for every key in the index (i.e., no partial
85 * matches are allowed).
87 * If an index can't be used with restriction clauses, but its keys
88 * match those of the result sort order (according to information stored
89 * within 'sortkeys'), then the index is also considered.
91 * 'rel' is the relation entry to which these index paths correspond
92 * 'indices' is a list of possible index paths
93 * 'restrictinfo_list' is a list of restriction restrictinfo nodes for 'rel'
94 * 'joininfo_list' is a list of joininfo nodes for 'rel'
95 * 'sortkeys' is a node describing the result sort order (from
98 * Returns a list of index nodes.
102 create_index_paths(Query *root,
105 List *restrictinfo_list,
108 List *scanclausegroups = NIL;
109 List *scanpaths = NIL;
110 RelOptInfo *index = (RelOptInfo *) NULL;
111 List *joinclausegroups = NIL;
112 List *joinpaths = NIL;
116 foreach(ilist, indices)
118 index = (RelOptInfo *) lfirst(ilist);
121 * If this is a partial index, return if it fails the predicate
124 if (index->indpred != NIL)
125 if (!pred_test(index->indpred, restrictinfo_list, joininfo_list))
129 * 1. Try matching the index against subclauses of an 'or' clause.
130 * The fields of the restrictinfo nodes are marked with lists of the
131 * matching indices. No path are actually created. We currently
132 * only look to match the first key. We don't find multi-key
133 * index cases where an AND matches the first key, and the OR
134 * matches the second key.
136 match_index_orclauses(rel,
143 * 2. If the keys of this index match any of the available
144 * restriction clauses, then create pathnodes corresponding to
145 * each group of usable clauses.
147 scanclausegroups = group_clauses_by_indexkey(rel,
154 if (scanclausegroups != NIL)
155 scanpaths = create_index_path_group(root,
162 * 3. If this index can be used with any join clause, then create
163 * pathnodes for each group of usable clauses. An index can be
164 * used with a join clause if its ordering is useful for a
165 * mergejoin, or if the index can possibly be used for scanning
166 * the inner relation of a nestloop join.
168 joinclausegroups = indexable_joinclauses(rel, index, joininfo_list, restrictinfo_list);
171 if (joinclausegroups != NIL)
173 joinpaths = create_index_path_group(root, rel,
177 rel->innerjoin = nconc(rel->innerjoin,
178 index_innerjoin(root, rel,
179 joinclausegroups, index));
183 * Some sanity checks to make sure that the indexpath is valid.
185 if (joinpaths != NULL)
186 retval = add_index_paths(joinpaths, retval);
187 if (scanpaths != NULL)
188 retval = add_index_paths(scanpaths, retval);
196 /****************************************************************************
197 * ---- ROUTINES TO MATCH 'OR' CLAUSES ----
198 ****************************************************************************/
202 * match_index_orclauses
203 * Attempt to match an index against subclauses within 'or' clauses.
204 * If the index does match, then the clause is marked with information
207 * Essentially, this adds 'index' to the list of indices in the
208 * RestrictInfo field of each of the clauses which it matches.
210 * 'rel' is the node of the relation on which the index is defined.
211 * 'index' is the index node.
212 * 'indexkey' is the (single) key of the index
213 * 'class' is the class of the operator corresponding to 'indexkey'.
214 * 'restrictinfo_list' is the list of available restriction clauses.
220 match_index_orclauses(RelOptInfo *rel,
224 List *restrictinfo_list)
226 RestrictInfo *restrictinfo = (RestrictInfo *) NULL;
229 foreach(i, restrictinfo_list)
231 restrictinfo = (RestrictInfo *) lfirst(i);
232 if (valid_or_clause(restrictinfo))
236 * Mark the 'or' clause with a list of indices which match
237 * each of its subclauses. The list is generated by adding
238 * 'index' to the existing list where appropriate.
240 restrictinfo->indexids = match_index_orclause(rel, index, indexkey,
242 restrictinfo->clause->args,
243 restrictinfo->indexids);
248 /* match_index_to_operand()
249 * Generalize test for a match between an existing index's key
250 * and the operand on the rhs of a restriction clause. Now check
251 * for functional indices as well.
254 match_index_to_operand(int indexkey,
264 if (index->indproc == InvalidOid)
266 result = match_indexkey_operand(indexkey, (Var *) operand, rel);
271 * functional index check
273 result = function_index_operand(operand, rel, index);
278 * match_index_orclause
279 * Attempts to match an index against the subclauses of an 'or' clause.
281 * A match means that:
282 * (1) the operator within the subclause can be used with one
283 * of the index's operator classes, and
284 * (2) there is a usable key that matches the variable within a
287 * 'or_clauses' are the remaining subclauses within the 'or' clause
288 * 'other_matching_indices' is the list of information on other indices
289 * that have already been matched to subclauses within this
290 * particular 'or' clause (i.e., a list previously generated by
293 * Returns a list of the form ((a b c) (d e f) nil (g h) ...) where
294 * a,b,c are nodes of indices that match the first subclause in
295 * 'or-clauses', d,e,f match the second subclause, no indices
296 * match the third, g,h match the fourth, etc.
299 match_index_orclause(RelOptInfo *rel,
304 List *other_matching_indices)
307 List *matching_indices = other_matching_indices;
308 List *index_list = NIL;
311 /* first time through, we create index list */
312 if (!other_matching_indices)
314 foreach(clist, or_clauses)
315 matching_indices = lcons(NIL, matching_indices);
318 matching_indices = other_matching_indices;
320 index_list = matching_indices;
322 foreach(clist, or_clauses)
324 clause = lfirst(clist);
326 if (is_opclause(clause))
328 Expr *left = (Expr *) get_leftop((Expr *) clause);
329 Expr *right = (Expr *) get_rightop((Expr *) clause);
331 op_class(((Oper *) ((Expr *) clause)->oper)->opno,
332 xclass, index->relam) &&
333 ((IsA(right, Const) &&
334 match_index_to_operand(indexkey, left, rel, index)) ||
336 match_index_to_operand(indexkey, right, rel, index))))
337 lfirst(matching_indices) = lcons(index,
338 lfirst(matching_indices));
341 matching_indices = lnext(matching_indices);
347 /****************************************************************************
348 * ---- ROUTINES TO CHECK RESTRICTIONS ----
349 ****************************************************************************/
353 * DoneMatchingIndexKeys() - MACRO
355 * Determine whether we should continue matching index keys in a clause.
356 * Depends on if there are more to match or if this is a functional index.
357 * In the latter case we stop after the first match since the there can
358 * be only key (i.e. the function's return value) and the attributes in
359 * keys list represent the arguments to the function. -mer 3 Oct. 1991
361 #define DoneMatchingIndexKeys(indexkeys, index) \
362 (indexkeys[0] == 0 || \
363 (index->indproc != InvalidOid))
366 * group_clauses_by_indexkey
367 * Determines whether there are clauses which will match each and every
368 * one of the remaining keys of an index.
370 * 'rel' is the node of the relation corresponding to the index.
371 * 'indexkeys' are the remaining index keys to be matched.
372 * 'classes' are the classes of the index operators on those keys.
373 * 'clauses' is either:
374 * (1) the list of available restriction clauses on a single
376 * (2) a list of join clauses between 'rel' and a fixed set of
378 * depending on the value of 'join'.
380 * NOTE: it works now for restriction clauses only. - vadim 03/18/97
382 * Returns all possible groups of clauses that will match (given that
383 * one or more clauses can match any of the remaining keys).
384 * E.g., if you have clauses A, B, and C, ((A B) (A C)) might be
385 * returned for an index with 2 keys.
389 group_clauses_by_indexkey(RelOptInfo *rel,
393 List *restrictinfo_list)
395 List *curCinfo = NIL;
396 RestrictInfo *matched_clause = (RestrictInfo *) NULL;
397 List *clausegroup = NIL;
401 if (restrictinfo_list == NIL || indexkeys[0] == 0)
406 List *tempgroup = NIL;
408 curIndxKey = indexkeys[0];
409 curClass = classes[0];
411 foreach(curCinfo, restrictinfo_list)
413 RestrictInfo *temp = (RestrictInfo *) lfirst(curCinfo);
415 matched_clause = match_clause_to_indexkey(rel,
424 tempgroup = lappend(tempgroup, matched_clause);
426 if (tempgroup == NIL)
429 clausegroup = nconc(clausegroup, tempgroup);
434 } while (!DoneMatchingIndexKeys(indexkeys, index));
436 /* clausegroup holds all matched clauses ordered by indexkeys */
438 if (clausegroup != NIL)
439 return lcons(clausegroup, NIL);
444 * group_clauses_by_ikey_for_joins
445 * special edition of group_clauses_by_indexkey - will
446 * match join & restriction clauses. See comment in indexable_joinclauses.
451 group_clauses_by_ikey_for_joins(RelOptInfo *rel,
455 List *join_cinfo_list,
456 List *restr_cinfo_list)
458 List *curCinfo = NIL;
459 RestrictInfo *matched_clause = (RestrictInfo *) NULL;
460 List *clausegroup = NIL;
465 if (join_cinfo_list == NIL || indexkeys[0] == 0)
470 List *tempgroup = NIL;
472 curIndxKey = indexkeys[0];
473 curClass = classes[0];
475 foreach(curCinfo, join_cinfo_list)
477 RestrictInfo *temp = (RestrictInfo *) lfirst(curCinfo);
479 matched_clause = match_clause_to_indexkey(rel,
488 tempgroup = lappend(tempgroup, matched_clause);
491 foreach(curCinfo, restr_cinfo_list)
493 RestrictInfo *temp = (RestrictInfo *) lfirst(curCinfo);
495 matched_clause = match_clause_to_indexkey(rel,
504 tempgroup = lappend(tempgroup, matched_clause);
506 if (tempgroup == NIL)
509 clausegroup = nconc(clausegroup, tempgroup);
514 } while (!DoneMatchingIndexKeys(indexkeys, index));
516 /* clausegroup holds all matched clauses ordered by indexkeys */
518 if (clausegroup != NIL)
522 * if no one join clause was matched then there ain't clauses for
527 freeList(clausegroup);
530 return lcons(clausegroup, NIL);
536 * IndexScanableClause () MACRO
538 * Generalize condition on which we match a clause with an index.
539 * Now we can match with functional indices.
541 #define IndexScanableOperand(opnd, indkeys, rel, index) \
542 ((index->indproc == InvalidOid) ? \
543 match_indexkey_operand(indkeys, opnd, rel) : \
544 function_index_operand((Expr*)opnd,rel,index))
548 * equal_indexkey_var(indkeys,opnd) : \
550 * match_indexkey_operand(indkeys, opnd, rel) : \
554 /* match_clause_to_indexkey()
555 * Finds the first of a relation's available restriction clauses that
556 * matches a key of an index.
558 * To match, the clause must:
559 * (1) be in the form (op var const) if the clause is a single-
560 * relation clause, and
561 * (2) contain an operator which is in the same class as the index
562 * operator for this key.
564 * If the clause being matched is a join clause, then 'join' is t.
566 * Returns a single restrictinfo node corresponding to the matching
569 * NOTE: returns nil if clause is an or_clause.
572 static RestrictInfo *
573 match_clause_to_indexkey(RelOptInfo *rel,
577 RestrictInfo *restrictInfo,
580 Expr *clause = restrictInfo->clause;
583 Oid join_op = InvalidOid;
584 Oid restrict_op = InvalidOid;
585 bool isIndexable = false;
587 if (or_clause((Node *) clause) ||
588 not_clause((Node *) clause) || single_node((Node *) clause))
589 return (RestrictInfo *) NULL;
591 leftop = get_leftop(clause);
592 rightop = get_rightop(clause);
595 * If this is not a join clause, check for clauses of the form:
596 * (operator var/func constant) and (operator constant var/func)
602 * Check for standard s-argable clause
604 if ((rightop && IsA(rightop, Const)) ||
605 (rightop && IsA(rightop, Param)))
607 restrict_op = ((Oper *) ((Expr *) clause)->oper)->opno;
609 isIndexable = (op_class(restrict_op, xclass, index->relam) &&
610 IndexScanableOperand(leftop,
615 #ifndef IGNORE_BINARY_COMPATIBLE_INDICES
618 * Didn't find an index? Then maybe we can find another
619 * binary-compatible index instead... thomas 1998-08-14
626 ltype = exprType((Node *) leftop);
627 rtype = exprType((Node *) rightop);
630 * make sure we have two different binary-compatible
634 && IS_BINARY_COMPATIBLE(ltype, rtype))
639 opname = get_opname(restrict_op);
641 newop = oper(opname, ltype, ltype, TRUE);
645 /* actually have a different operator to try? */
646 if (HeapTupleIsValid(newop) && (oprid(newop) != restrict_op))
648 restrict_op = oprid(newop);
650 isIndexable = (op_class(restrict_op, xclass, index->relam) &&
651 IndexScanableOperand(leftop,
657 ((Oper *) ((Expr *) clause)->oper)->opno = restrict_op;
665 * Must try to commute the clause to standard s-arg format.
667 else if ((leftop && IsA(leftop, Const)) ||
668 (leftop && IsA(leftop, Param)))
670 restrict_op = get_commutator(((Oper *) ((Expr *) clause)->oper)->opno);
672 isIndexable = ((restrict_op != InvalidOid) &&
673 op_class(restrict_op, xclass, index->relam) &&
674 IndexScanableOperand(rightop,
675 indexkey, rel, index));
677 #ifndef IGNORE_BINARY_COMPATIBLE_INDICES
683 ltype = exprType((Node *) leftop);
684 rtype = exprType((Node *) rightop);
687 && IS_BINARY_COMPATIBLE(ltype, rtype))
692 restrict_op = ((Oper *) ((Expr *) clause)->oper)->opno;
694 opname = get_opname(restrict_op);
696 newop = oper(opname, rtype, rtype, TRUE);
700 if (HeapTupleIsValid(newop) && (oprid(newop) != restrict_op))
702 restrict_op = get_commutator(oprid(newop));
704 isIndexable = ((restrict_op != InvalidOid) &&
705 op_class(restrict_op, xclass, index->relam) &&
706 IndexScanableOperand(rightop,
712 ((Oper *) ((Expr *) clause)->oper)->opno = oprid(newop);
722 * In place list modification. (op const var/func) -> (op
725 CommuteClause((Node *) clause);
731 * Check for an indexable scan on one of the join relations. clause is
732 * of the form (operator var/func var/func)
737 && match_index_to_operand(indexkey, (Expr *) rightop, rel, index))
740 join_op = get_commutator(((Oper *) ((Expr *) clause)->oper)->opno);
744 && match_index_to_operand(indexkey,
745 (Expr *) leftop, rel, index))
746 join_op = ((Oper *) ((Expr *) clause)->oper)->opno;
748 if (join_op && op_class(join_op, xclass, index->relam) &&
749 is_joinable((Node *) clause))
754 * If we're using the operand's commutator we must commute the
757 if (join_op != ((Oper *) ((Expr *) clause)->oper)->opno)
758 CommuteClause((Node *) clause);
768 /****************************************************************************
769 * ---- ROUTINES TO DO PARTIAL INDEX PREDICATE TESTS ----
770 ****************************************************************************/
774 * Does the "predicate inclusion test" for partial indexes.
776 * Recursively checks whether the clauses in restrictinfo_list imply
777 * that the given predicate is true.
779 * This routine (together with the routines it calls) iterates over
780 * ANDs in the predicate first, then reduces the qualification
781 * clauses down to their constituent terms, and iterates over ORs
782 * in the predicate last. This order is important to make the test
783 * succeed whenever possible (assuming the predicate has been
784 * successfully cnfify()-ed). --Nels, Jan '93
787 pred_test(List *predicate_list, List *restrictinfo_list, List *joininfo_list)
794 * Note: if Postgres tried to optimize queries by forming equivalence
795 * classes over equi-joined attributes (i.e., if it recognized that a
796 * qualification such as "where a.b=c.d and a.b=5" could make use of
797 * an index on c.d), then we could use that equivalence class info
798 * here with joininfo_list to do more complete tests for the usability
799 * of a partial index. For now, the test only uses restriction
800 * clauses (those in restrictinfo_list). --Nels, Dec '92
803 if (predicate_list == NULL)
804 return true; /* no predicate: the index is usable */
805 if (restrictinfo_list == NULL)
806 return false; /* no restriction clauses: the test must
809 foreach(pred, predicate_list)
813 * if any clause is not implied, the whole predicate is not
816 if (and_clause(lfirst(pred)))
818 items = ((Expr *) lfirst(pred))->args;
821 if (!one_pred_test(lfirst(item), restrictinfo_list))
825 else if (!one_pred_test(lfirst(pred), restrictinfo_list))
834 * Does the "predicate inclusion test" for one conjunct of a predicate
838 one_pred_test(Expr *predicate, List *restrictinfo_list)
840 RestrictInfo *restrictinfo;
843 Assert(predicate != NULL);
844 foreach(item, restrictinfo_list)
846 restrictinfo = (RestrictInfo *) lfirst(item);
847 /* if any clause implies the predicate, return true */
848 if (one_pred_clause_expr_test(predicate, (Node *) restrictinfo->clause))
856 * one_pred_clause_expr_test
857 * Does the "predicate inclusion test" for a general restriction-clause
861 one_pred_clause_expr_test(Expr *predicate, Node *clause)
866 if (is_opclause(clause))
867 return one_pred_clause_test(predicate, clause);
868 else if (or_clause(clause))
870 items = ((Expr *) clause)->args;
873 /* if any OR item doesn't imply the predicate, clause doesn't */
874 if (!one_pred_clause_expr_test(predicate, lfirst(item)))
879 else if (and_clause(clause))
881 items = ((Expr *) clause)->args;
886 * if any AND item implies the predicate, the whole clause
889 if (one_pred_clause_expr_test(predicate, lfirst(item)))
896 /* unknown clause type never implies the predicate */
903 * one_pred_clause_test
904 * Does the "predicate inclusion test" for one conjunct of a predicate
905 * expression for a simple restriction clause.
908 one_pred_clause_test(Expr *predicate, Node *clause)
913 if (is_opclause((Node *) predicate))
914 return clause_pred_clause_test(predicate, clause);
915 else if (or_clause((Node *) predicate))
917 items = predicate->args;
920 /* if any item is implied, the whole predicate is implied */
921 if (one_pred_clause_test(lfirst(item), clause))
926 else if (and_clause((Node *) predicate))
928 items = predicate->args;
933 * if any item is not implied, the whole predicate is not
936 if (!one_pred_clause_test(lfirst(item), clause))
943 elog(DEBUG, "Unsupported predicate type, index will not be used");
950 * Define an "operator implication table" for btree operators ("strategies").
951 * The "strategy numbers" are: (1) < (2) <= (3) = (4) >= (5) >
953 * The interpretation of:
955 * test_op = BT_implic_table[given_op-1][target_op-1]
957 * where test_op, given_op and target_op are strategy numbers (from 1 to 5)
958 * of btree operators, is as follows:
960 * If you know, for some ATTR, that "ATTR given_op CONST1" is true, and you
961 * want to determine whether "ATTR target_op CONST2" must also be true, then
962 * you can use "CONST1 test_op CONST2" as a test. If this test returns true,
963 * then the target expression must be true; if the test returns false, then
964 * the target expression may be false.
966 * An entry where test_op==0 means the implication cannot be determined, i.e.,
967 * this test should always be considered false.
970 StrategyNumber BT_implic_table[BTMaxStrategyNumber][BTMaxStrategyNumber] = {
980 * clause_pred_clause_test
981 * Use operator class info to check whether clause implies predicate.
983 * Does the "predicate inclusion test" for a "simple clause" predicate
984 * for a single "simple clause" restriction. Currently, this only handles
985 * (binary boolean) operators that are in some btree operator class.
986 * Eventually, rtree operators could also be handled by defining an
987 * appropriate "RT_implic_table" array.
990 clause_pred_clause_test(Expr *predicate, Node *clause)
1000 StrategyNumber pred_strategy,
1010 ScanKeyData entry[3];
1013 pred_var = (Var *) get_leftop(predicate);
1014 pred_const = (Const *) get_rightop(predicate);
1015 clause_var = (Var *) get_leftop((Expr *) clause);
1016 clause_const = (Const *) get_rightop((Expr *) clause);
1018 /* Check the basic form; for now, only allow the simplest case */
1019 if (!is_opclause(clause) ||
1020 !IsA(clause_var, Var) ||
1021 clause_const == NULL ||
1022 !IsA(clause_const, Const) ||
1023 !IsA(predicate->oper, Oper) ||
1024 !IsA(pred_var, Var) ||
1025 !IsA(pred_const, Const))
1029 * The implication can't be determined unless the predicate and the
1030 * clause refer to the same attribute.
1032 if (clause_var->varattno != pred_var->varattno)
1035 /* Get the operators for the two clauses we're comparing */
1036 pred_op = ((Oper *) ((Expr *) predicate)->oper)->opno;
1037 clause_op = ((Oper *) ((Expr *) clause)->oper)->opno;
1041 * 1. Find a "btree" strategy number for the pred_op
1043 ScanKeyEntryInitialize(&entry[0], 0,
1044 Anum_pg_amop_amopid,
1046 ObjectIdGetDatum(BTREE_AM_OID));
1048 ScanKeyEntryInitialize(&entry[1], 0,
1049 Anum_pg_amop_amopopr,
1051 ObjectIdGetDatum(pred_op));
1053 relation = heap_openr(AccessMethodOperatorRelationName);
1056 * The following assumes that any given operator will only be in a
1057 * single btree operator class. This is true at least for all the
1058 * pre-defined operator classes. If it isn't true, then whichever
1059 * operator class happens to be returned first for the given operator
1060 * will be used to find the associated strategy numbers for the test.
1063 scan = heap_beginscan(relation, false, SnapshotNow, 2, entry);
1064 tuple = heap_getnext(scan, 0);
1065 if (!HeapTupleIsValid(tuple))
1067 elog(DEBUG, "clause_pred_clause_test: unknown pred_op");
1070 form = (Form_pg_amop) GETSTRUCT(tuple);
1072 /* Get the predicate operator's strategy number (1 to 5) */
1073 pred_strategy = (StrategyNumber) form->amopstrategy;
1075 /* Remember which operator class this strategy number came from */
1076 opclass_id = form->amopclaid;
1082 * 2. From the same opclass, find a strategy num for the clause_op
1084 ScanKeyEntryInitialize(&entry[1], 0,
1085 Anum_pg_amop_amopclaid,
1087 ObjectIdGetDatum(opclass_id));
1089 ScanKeyEntryInitialize(&entry[2], 0,
1090 Anum_pg_amop_amopopr,
1092 ObjectIdGetDatum(clause_op));
1094 scan = heap_beginscan(relation, false, SnapshotNow, 3, entry);
1095 tuple = heap_getnext(scan, 0);
1096 if (!HeapTupleIsValid(tuple))
1098 elog(DEBUG, "clause_pred_clause_test: unknown clause_op");
1101 form = (Form_pg_amop) GETSTRUCT(tuple);
1103 /* Get the restriction clause operator's strategy number (1 to 5) */
1104 clause_strategy = (StrategyNumber) form->amopstrategy;
1109 * 3. Look up the "test" strategy number in the implication table
1112 test_strategy = BT_implic_table[clause_strategy - 1][pred_strategy - 1];
1113 if (test_strategy == 0)
1114 return false; /* the implication cannot be determined */
1118 * 4. From the same opclass, find the operator for the test strategy
1121 ScanKeyEntryInitialize(&entry[2], 0,
1122 Anum_pg_amop_amopstrategy,
1124 Int16GetDatum(test_strategy));
1126 scan = heap_beginscan(relation, false, SnapshotNow, 3, entry);
1127 tuple = heap_getnext(scan, 0);
1128 if (!HeapTupleIsValid(tuple))
1130 elog(DEBUG, "clause_pred_clause_test: unknown test_op");
1133 form = (Form_pg_amop) GETSTRUCT(tuple);
1135 /* Get the test operator */
1136 test_op = form->amopopr;
1141 * 5. Evaluate the test
1143 test_oper = makeOper(test_op, /* opno */
1144 InvalidOid, /* opid */
1145 BOOLOID, /* opresulttype */
1147 NULL); /* op_fcache */
1148 replace_opid(test_oper);
1150 test_expr = make_opclause(test_oper,
1151 copyObject(clause_const),
1152 copyObject(pred_const));
1154 #ifndef OMIT_PARTIAL_INDEX
1155 test_result = ExecEvalExpr((Node *) test_expr, NULL, &isNull, NULL);
1156 #endif /* OMIT_PARTIAL_INDEX */
1159 elog(DEBUG, "clause_pred_clause_test: null test result");
1166 /****************************************************************************
1167 * ---- ROUTINES TO CHECK JOIN CLAUSES ----
1168 ****************************************************************************/
1171 * indexable_joinclauses
1172 * Finds all groups of join clauses from among 'joininfo_list' that can
1173 * be used in conjunction with 'index'.
1175 * The first clause in the group is marked as having the other relation
1176 * in the join clause as its outer join relation.
1178 * Returns a list of these clause groups.
1180 * Added: restrictinfo_list - list of restriction RestrictInfos. It's to
1181 * support multi-column indices in joins and for cases
1182 * when a key is in both join & restriction clauses. - vadim 03/18/97
1186 indexable_joinclauses(RelOptInfo *rel, RelOptInfo *index,
1187 List *joininfo_list, List *restrictinfo_list)
1189 JoinInfo *joininfo = (JoinInfo *) NULL;
1190 List *cg_list = NIL;
1192 List *clausegroups = NIL;
1194 foreach(i, joininfo_list)
1196 joininfo = (JoinInfo *) lfirst(i);
1198 if (joininfo->jinfo_restrictinfo == NIL)
1200 clausegroups = group_clauses_by_ikey_for_joins(rel,
1204 joininfo->jinfo_restrictinfo,
1207 if (clausegroups != NIL)
1209 List *clauses = lfirst(clausegroups);
1211 ((RestrictInfo *) lfirst(clauses))->restrictinfojoinid = joininfo->unjoined_relids;
1213 cg_list = nconc(cg_list, clausegroups);
1218 /****************************************************************************
1219 * ---- PATH CREATION UTILITIES ----
1220 ****************************************************************************/
1223 * extract_restrict_clauses -
1224 * the list of clause info contains join clauses and restriction clauses.
1225 * This routine returns the restriction clauses only.
1229 extract_restrict_clauses(List *clausegroup)
1231 List *restrict_cls = NIL;
1234 foreach(l, clausegroup)
1236 RestrictInfo *cinfo = lfirst(l);
1238 if (!is_joinable((Node *) cinfo->clause))
1239 restrict_cls = lappend(restrict_cls, cinfo);
1241 return restrict_cls;
1248 * Creates index path nodes corresponding to paths to be used as inner
1249 * relations in nestloop joins.
1251 * 'clausegroup-list' is a list of list of restrictinfo nodes which can use
1252 * 'index' on their inner relation.
1254 * Returns a list of index pathnodes.
1258 index_innerjoin(Query *root, RelOptInfo *rel, List *clausegroup_list,
1261 List *clausegroup = NIL;
1262 List *cg_list = NIL;
1264 IndexPath *pathnode = (IndexPath *) NULL;
1268 foreach(i, clausegroup_list)
1274 clausegroup = lfirst(i);
1275 pathnode = makeNode(IndexPath);
1277 get_joinvars(lfirsti(rel->relids), clausegroup,
1278 &attnos, &values, &flags);
1279 index_selectivity(lfirsti(index->relids),
1281 get_opnos(clausegroup),
1282 getrelid(lfirsti(rel->relids),
1287 length(clausegroup),
1291 pathnode->path.pathtype = T_IndexScan;
1292 pathnode->path.parent = rel;
1293 pathnode->path.pathorder = makeNode(PathOrder);
1294 pathnode->path.pathorder->ordtype = SORTOP_ORDER;
1295 pathnode->path.pathorder->ord.sortop = index->ordering;
1296 pathnode->path.pathkeys = NIL;
1298 pathnode->indexid = index->relids;
1299 pathnode->indexkeys = index->indexkeys;
1300 pathnode->indexqual = clausegroup;
1302 pathnode->path.joinid = ((RestrictInfo *) lfirst(clausegroup))->restrictinfojoinid;
1304 pathnode->path.path_cost = cost_index((Oid) lfirsti(index->relids),
1314 * copy restrictinfo list into path for expensive function
1315 * processing -- JMH, 7/7/92
1317 pathnode->path.loc_restrictinfo = set_difference(copyObject((Node *) rel->restrictinfo),
1320 #if 0 /* fix xfunc */
1321 /* add in cost for expensive functions! -- JMH, 7/7/92 */
1322 if (XfuncMode != XFUNC_OFF)
1324 ((Path *) pathnode)->path_cost += xfunc_get_path_cost((Path *) pathnode);
1327 cg_list = lappend(cg_list, pathnode);
1333 * create_index_path_group
1334 * Creates a list of index path nodes for each group of clauses
1335 * (restriction or join) that can be used in conjunction with an index.
1337 * 'rel' is the relation for which 'index' is defined
1338 * 'clausegroup-list' is the list of clause groups (lists of restrictinfo
1339 * nodes) grouped by mergejoinorder
1340 * 'join' is a flag indicating whether or not the clauses are join
1343 * Returns a list of new index path nodes.
1347 create_index_path_group(Query *root,
1350 List *clausegroup_list,
1353 List *clausegroup = NIL;
1354 List *ip_list = NIL;
1357 IndexPath *temp_path;
1359 foreach(i, clausegroup_list)
1361 RestrictInfo *restrictinfo;
1364 clausegroup = lfirst(i);
1366 foreach(j, clausegroup)
1368 restrictinfo = (RestrictInfo *) lfirst(j);
1369 if (!(is_joinable((Node *) restrictinfo->clause) &&
1370 equal_path_merge_ordering(index->ordering,
1371 restrictinfo->mergejoinorder)))
1376 { /* restriction, ordering scan */
1377 temp_path = create_index_path(root, rel, index, clausegroup, join);
1378 ip_list = lappend(ip_list, temp_path);
1385 add_index_paths(List *indexpaths, List *new_indexpaths)
1387 return append(indexpaths, new_indexpaths);
1391 function_index_operand(Expr *funcOpnd, RelOptInfo *rel, RelOptInfo *index)
1393 Oid heapRelid = (Oid) lfirsti(rel->relids);
1396 int *indexKeys = index->indexkeys;
1401 * sanity check, make sure we know what we're dealing with here.
1403 if (funcOpnd == NULL ||
1404 nodeTag(funcOpnd) != T_Expr || funcOpnd->opType != FUNC_EXPR ||
1405 funcOpnd->oper == NULL || indexKeys == NULL)
1408 function = (Func *) funcOpnd->oper;
1409 funcargs = funcOpnd->args;
1411 if (function->funcid != index->indproc)
1415 * Check that the arguments correspond to the same arguments used to
1416 * create the functional index. To do this we must check that 1.
1417 * refer to the right relatiion. 2. the args have the right attr.
1418 * numbers in the right order.
1421 * Check all args refer to the correct relation (i.e. the one with the
1422 * functional index defined on it (rel). To do this we can simply
1423 * compare range table entry numbers, they must be the same.
1425 foreach(arg, funcargs)
1427 if (heapRelid != ((Var *) lfirst(arg))->varno)
1432 * check attr numbers and order.
1435 foreach(arg, funcargs)
1438 if (indexKeys[i] == 0)
1441 if (((Var *) lfirst(arg))->varattno != indexKeys[i])