|
|
1.1 root 1: # include <ingres.h>
2: # include <aux.h>
3: # include <catalog.h>
4: # include <symbol.h>
5: # include <tree.h>
6: # include "../decomp/globs.h"
7: # include "strategy.h"
8: # include <sccs.h>
9:
10: SCCSID(@(#)strategy.c 7.2 9/12/83)
11:
12: /*
13: ** STRATEGY
14: **
15: ** Attempts to limit access scan to less than the entire De.ov_source
16: ** relation by finding a key which can be used for associative
17: ** access to the De.ov_source reln or an index thereon. The key is
18: ** constructed from domain-value specifications found in the
19: ** clauses of the qualification list using sub-routine findsimp
20: ** in findsimp.c and other subroutines in file key.c
21: */
22:
23:
24:
25: strategy()
26: {
27: register int i, allexact;
28: struct accessparam sourceparm, indexparm;
29: struct index itup, rtup;
30: struct key lowikey[MAXKEYS+1], highikey[MAXKEYS+1];
31: register DESC *d;
32: DESC *openindex();
33: extern DESC Inddes;
34:
35: # ifdef xOTR1
36: if (tTf(70, 0))
37: printf("STRATEGY\tSource=%.12s\tNewq = %d\n",
38: De.ov_source ? De.ov_source->reldum.relid : "(none)",
39: De.de_newq);
40: # endif
41:
42: while (De.de_newq) /* if De.de_newq=TRUE then compute a new strategy */
43: /* NOTE: This while loop is executed only once */
44: {
45: De.ov_scanr = De.ov_source;
46:
47: if (!De.ov_scanr)
48: return (1); /* return immediately if there is no source relation */
49:
50: De.ov_fmode = NOKEY; /* assume a find mode with no key */
51:
52: if (!De.ov_qlist)
53: break; /* if no qualification then you must scan entire rel */
54:
55: /*
56: ** Here we check for the special condition
57: ** of a where clause consisting only of a tid.
58: */
59: if ( tid_only_test() )
60: return (1);
61:
62: /* copy structure of source relation into sourceparm */
63: paramd(De.ov_source, &sourceparm);
64:
65: /* if source is unkeyed and has no sec index then give up */
66: if (sourceparm.mode == NOKEY && De.ov_source->reldum.relindxd <= 0)
67: break;
68:
69: /* find all simple clauses if any */
70: if (!findsimps())
71: break; /* break if there are no simple clauses */
72:
73: /* Four steps are now performed to try and find a key.
74: ** First if the relation is hashed then an exact key is searched for.
75: **
76: ** Second if there are secondary indexes, then a search is made
77: ** for an exact key. If that fails then a check is made for
78: ** a range key. The result of the rangekey check is saved.
79: **
80: ** Third if the relation is an ISAM a check is made for
81: ** an exact key or a range key.
82: **
83: ** Fourth if there is a secondary index, then if step two
84: ** found a key, that key is used.
85: **
86: ** Lastly, give up and scan the entire relation
87: */
88:
89: /* step one. Try to find exact key on primary */
90: if (exactkey(&sourceparm, De.ov_lkey_struct))
91: {
92: De.ov_fmode = EXACTKEY;
93: break;
94: }
95:
96: /* step two. If there is an index, try to find an exactkey on one of them */
97: if (De.ov_source->reldum.relindxd)
98: {
99:
100: opencatalog("indexes", 0);
101: setkey(&Inddes, &itup, De.ov_source->reldum.relid, IRELIDP);
102: setkey(&Inddes, &itup, De.ov_source->reldum.relowner, IOWNERP);
103: if (i = find(&Inddes, EXACTKEY, &De.ov_lotid, &De.ov_hitid, (char *)&itup))
104: syserr("strategy:find indexes %d", i);
105:
106: while (!(i = get(&Inddes, &De.ov_lotid, &De.ov_hitid, (char *)&itup, NXTTUP)))
107: {
108: # ifdef xOTR1
109: if (tTf(70, 3))
110: printup(&Inddes, (char *)&itup);
111: # endif
112: if (!bequal(itup.irelidp, De.ov_source->reldum.relid, MAXNAME) ||
113: !bequal(itup.iownerp, De.ov_source->reldum.relowner, 2))
114: continue;
115: parami(&itup, &indexparm);
116: if (exactkey(&indexparm, De.ov_lkey_struct))
117: {
118: De.ov_fmode = EXACTKEY;
119: d = openindex(itup.irelidi);
120: /* temp check for 6.0 index */
121: if ((int) d->reldum.relindxd == -1)
122: ov_err(BADSECINDX);
123: De.ov_scanr = d;
124: break;
125: }
126: if (De.ov_fmode == LRANGEKEY)
127: continue; /* a range key on a s.i. has already been found */
128: if (allexact = rangekey(&indexparm, lowikey, highikey))
129: {
130: bmove((char *)&itup, (char *)&rtup, sizeof itup); /* save tuple */
131: De.ov_fmode = LRANGEKEY;
132: }
133: }
134: if (i < 0)
135: syserr("stragery:bad get from index-rel %d", i);
136: /* If an exactkey on a secondary index was found, look no more. */
137: if (De.ov_fmode == EXACTKEY)
138: break;
139: }
140:
141:
142:
143: /* step three. Look for a range key on primary */
144: if (i = rangekey(&sourceparm, De.ov_lkey_struct, De.ov_hkey_struct))
145: {
146: if (i < 0)
147: De.ov_fmode = EXACTKEY;
148: else
149: De.ov_fmode = LRANGEKEY;
150: break;
151: }
152:
153: /* last step. If a secondary index range key was found, use it */
154: if (De.ov_fmode == LRANGEKEY)
155: {
156: if (allexact < 0)
157: De.ov_fmode = EXACTKEY;
158: d = openindex(rtup.irelidi);
159: /* temp check for 6.0 index */
160: if ((int) d->reldum.relindxd == -1)
161: ov_err(BADSECINDX);
162: De.ov_scanr = d;
163: bmove((char *)lowikey, (char *)De.ov_lkey_struct, sizeof lowikey);
164: bmove((char *)highikey, (char *)De.ov_hkey_struct, sizeof highikey);
165: break;
166: }
167:
168: /* nothing will work. give up! */
169: break;
170:
171: }
172:
173: /* check for De.de_newq = FALSE and no source relation */
174: if (!De.ov_scanr)
175: return (1);
176: /*
177: ** At this point the strategy is determined.
178: **
179: ** If De.ov_fmode is EXACTKEY then De.ov_lkey_struct contains
180: ** the pointers to the keys.
181: **
182: ** If De.ov_fmode is LRANGEKEY then De.ov_lkey_struct contains
183: ** the pointers to the low keys and De.ov_hkey_struct
184: ** contains pointers to the high keys.
185: **
186: ** If De.ov_fmode is NOKEY, then a full scan will be performed
187: */
188: # ifdef xOTR1
189: if (tTf(70, -1))
190: printf("De.ov_fmode= %d\n",De.ov_fmode);
191: # endif
192:
193: /* set up the key tuples */
194: if (De.ov_fmode != NOKEY)
195: {
196: if (setallkey(De.ov_lkey_struct, De.ov_keyl))
197: return (0); /* query false. There is a simple
198: ** clause which can never be satisfied.
199: ** These simple clauses can be choosey!
200: */
201: }
202:
203: if (i = find(De.ov_scanr, De.ov_fmode, &De.ov_lotid, &De.ov_hitid, De.ov_keyl))
204: syserr("strategy:find1 %.12s, %d", De.ov_scanr->reldum.relid, i);
205:
206: if (De.ov_fmode == LRANGEKEY)
207: {
208: setallkey(De.ov_hkey_struct, De.ov_keyh);
209: if (i = find(De.ov_scanr, HRANGEKEY, &De.ov_lotid, &De.ov_hitid, De.ov_keyh))
210: syserr("strategy:find2 %.12s, %d", De.ov_scanr->reldum.relid, i);
211: }
212:
213: # ifdef xOTR1
214: if (tTf(70, 1))
215: {
216: printf("Lo");
217: dumptid(&De.ov_lotid);
218: printf("Hi");
219: dumptid(&De.ov_hitid);
220: }
221: # endif
222:
223: return (1);
224: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.