1 /*-------------------------------------------------------------------------
4 * Key manipulation routines
6 * Copyright (c) 1994, Regents of the University of California
10 * $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/keys.c,v 1.11 1999/02/09 03:51:26 momjian Exp $
12 *-------------------------------------------------------------------------
15 #include "nodes/pg_list.h"
16 #include "nodes/nodes.h"
17 #include "nodes/relation.h"
18 #include "utils/elog.h"
20 #include "optimizer/internal.h"
21 #include "optimizer/keys.h"
22 #include "optimizer/tlist.h"
25 static Expr *matching2_tlvar(int var, List *tlist, bool (*test) ());
26 static bool equal_indexkey_var(int index_key, Var *var);
34 * (subkey1 ... subkeyN)
35 * where subkeyI is a var node
36 * note that the 'Keys field is a list of these
38 * (outer-subkey inner-subkey)
39 * where each subkey is a var node
45 * (may also refer to the 'SortKey field of a SortKey node,
46 * which looks exactly like an index key)
51 * match-indexkey-operand--
52 * Returns t iff an index key 'index-key' matches the given clause
57 match_indexkey_operand(int indexkey, Var *operand, RelOptInfo * rel)
59 if (IsA(operand, Var) &&
60 (lfirsti(rel->relids) == operand->varno) &&
61 equal_indexkey_var(indexkey, operand))
68 * equal_indexkey_var--
69 * Returns t iff an index key 'index-key' matches the corresponding
70 * fields of var node 'var'.
74 equal_indexkey_var(int index_key, Var *var)
76 if (index_key == var->varattno)
84 * Returns the subkey in a join key corresponding to the outer or inner
89 extract_subkey(JoinKey *jk, int which_subkey)
101 default: /* do nothing */
102 elog(DEBUG, "extract_subkey with neither INNER or OUTER");
110 * Returns t iff two sets of path keys are equivalent. They are
111 * equivalent if the first subkey (var node) within each sublist of
112 * list 'keys1' is contained within the corresponding sublist of 'keys2'.
114 * XXX It isn't necessary to check that each sublist exactly contain
115 * the same elements because if the routine that built these
116 * sublists together is correct, having one element in common
117 * implies having all elements in common.
121 samekeys(List *keys1, List *keys2)
126 for (key1 = keys1, key2 = keys2; key1 != NIL && key2 != NIL;
127 key1 = lnext(key1), key2 = lnext(key2))
128 if (!member(lfirst((List *)lfirst(key1)), lfirst(key2)))
131 /* Now the result should be true if list keys2 has at least as many
132 * entries as keys1, ie, we did not fall off the end of keys2 first.
133 * If key1 is now NIL then we hit the end of keys1 before or at the
134 * same time as the end of keys2.
143 * collect-index-pathkeys--
144 * Creates a list of subkeys by retrieving var nodes corresponding to
145 * each index key in 'index-keys' from the relation's target list
146 * 'tlist'. If the key is not in the target list, the key is irrelevant
147 * and is thrown away. The returned subkey list is of the form:
148 * ((var1) (var2) ... (varn))
150 * 'index-keys' is a list of index keys
151 * 'tlist' is a relation target list
153 * Returns the list of cons'd subkeys.
156 /* This function is identical to matching_tlvar and tlistentry_member.
157 * They should be merged.
160 matching2_tlvar(int var, List *tlist, bool (*test) ())
162 TargetEntry *tlentry = NULL;
170 if ((*test) (var, get_expr(lfirst(temp))))
172 tlentry = lfirst(temp);
179 return (Expr *) get_expr(tlentry);
181 return (Expr *) NULL;
186 collect_index_pathkeys(int *index_keys, List *tlist)
190 Assert(index_keys != NULL);
192 while (index_keys[0] != 0)
196 mvar = matching2_tlvar(index_keys[0],
200 retval = nconc(retval, lcons(lcons(mvar, NIL),