|
|
1.1 root 1: # include <ingres.h>
2: # include <aux.h>
3: # include <symbol.h>
4: # include <tree.h>
5: # include <catalog.h>
6: # include "../decomp/globs.h"
7: # include "strategy.h"
8: # include <btree.h>
9: # include <sccs.h>
10:
11: SCCSID(@(#)key.c 8.4 3/20/85)
12:
13:
14:
15: /*
16: ** Exactkey checks to see if the relation described
17: ** by "ap" can be used in a hashed scan.
18: ** All the key domains of the relation must
19: ** have simple clauses of equality associated
20: ** with them in the qualification.
21: **
22: ** Returns 0 if the relation can't be used.
23: **
24: ** Returns > 0 if it can.
25: */
26:
27: exactkey(ap, key)
28: struct accessparam *ap;
29: struct key *key;
30: {
31: register struct accessparam *a;
32: register struct key *k;
33: register struct simp *s;
34: int d, i, j;
35:
36: # ifdef xOTR1
37: if (tTf(85, -1))
38: printf("Exactkey\n");
39: # endif
40:
41: a = ap;
42: k = key;
43: i = 0;
44: if (a->mode == EXACTKEY)
45: {
46:
47: for (i = 0; d = a->keydno[i]; i++)
48: {
49:
50: s = De.ov_simp;
51: for (j = 0; j < De.ov_nsimp; j++)
52: {
53: if (s->relop == opEQ && s->att == d)
54: {
55: k->keysym = s->const;
56: k->dnumber = (a->sec_index == TRUE) ? i+1 : d;
57: k++;
58: # ifdef xOTR1
59: if (tTf(85, 1))
60: {
61: printf("exact key on dom %d\tvalue=", d);
62: prsym(s->const);
63: }
64: # endif
65: break;
66: }
67: s++;
68: }
69: if (j == De.ov_nsimp)
70: {
71: i = 0; /* failure. at lease one key isn't used */
72: break;
73: }
74: }
75: k->dnumber = 0; /* mark end of list */
76: }
77: # ifdef xOTR1
78: if (tTf(85, 9))
79: printf("exactkey returning %d\n", i);
80: # endif
81: return (i);
82: }
83:
84: /*
85: ** Attempts to use the B-Tree for retrieval.
86: ** There are two types of searches possible, exact and range searches.
87: ** In order for an exact search to be possible, there must be a simple
88: ** equality clause using the lid field.
89: ** For a range search, either or both lid ranges must be provided.
90: **
91: ** Returns 1 exact BTREEKEY search possible
92: ** -1 low lid key provided
93: ** -2 high lid key provided
94: ** -3 both lids provided
95: */
96:
97: btreekey(lkey, hkey)
98:
99: struct key *lkey, *hkey;
100: {
101: register struct key *l, *h;
102: register struct simp *s;
103: int i, j, k;
104: int provided[MAXLID];
105: SYMBOL *(save[MAXLID]);
106:
107: # ifdef xOTR1
108: if (tTf(85, -1))
109: printf("Btreekey\n");
110: # endif
111:
112: l = lkey;
113: h = hkey;
114: i = 0;
115: for (j = 0; j < MAXLID; ++j)
116: provided[j] = 0;
117: if (De.ov_scanr->reldum.reldim > 0 && De.ov_scanr->reldum.reltups > 0)
118: {
119: s = De.ov_simp;
120: for (j = 0; j < De.ov_nsimp; ++j)
121: {
122: if (s->att >= De.ov_scanr->reldum.relatts - De.ov_scanr->reldum.reldim + 1)
123: {
124: if (s->relop == opEQ || s->relop == opGTGE)
125: {
126: l->keysym = s->const;
127: l->dnumber = s->att;
128: if (s->relop == opEQ)
129: {
130: provided[De.ov_scanr->reldum.relatts - s->att] = 1;
131: save[De.ov_scanr->reldum.relatts - s->att] = l->keysym;
132:
133: }
134: else if (i == -2)
135: i = -3;
136: else if (!i)
137: i = -1;
138: ++l;
139: }
140: if (s->relop == opLTLE)
141: {
142: h->keysym = s->const;
143: h->dnumber = s->att;
144: h++;
145: if (i == -1)
146: i = -3;
147: else if (!i)
148: i = -2;
149: }
150: }
151: s++;
152: for (k = 0; k < De.ov_scanr->reldum.reldim; ++k)
153: if (!provided[k])
154: break;
155: if (k >= De.ov_scanr->reldum.reldim)
156: {
157: i = 1;
158: break;
159: }
160: }
161: if (i != 1)
162: for (k = 0; k < De.ov_scanr->reldum.reldim; ++k)
163: if (provided[k])
164: {
165: h->keysym = save[k];
166: h->dnumber = De.ov_scanr->reldum.relatts - k;
167: h++;
168: i = -3;
169: }
170: /* mark ends of lists */
171: l->dnumber = 0;
172: h->dnumber = 0;
173: }
174: # ifdef xOTR1
175: if (tTf(85, 9))
176: printf("btreekey returning %d\n", i);
177: # endif
178: return(i);
179: }
180: /*
181: ** Range key checks if the relation described by
182: ** "ap" is ISAM and there are simple clauses
183: ** on the first key and any additional keys.
184: **
185: ** Rangekey accumulates both high and low keys,
186: ** which are not necessary the same. If it
187: ** every finds a high or a low key on the first
188: ** domain of the relation then success=TRUE.
189: **
190: ** Returns 1 if Rangekey ok
191: ** 0 if Rangekey is not ok
192: ** -1 if Rangekey ok and all clauses are equality clauses
193: */
194:
195: rangekey(ap, l, h)
196: struct accessparam *ap;
197: struct key *l;
198: struct key *h;
199: {
200: register struct key *low, *high;
201: register struct simp *s;
202: struct accessparam *a;
203: int sec_indx, d, i;
204: int rel, success, ns, lowkey, allexact;
205:
206: # ifdef xOTR1
207: if (tTf(85, 5))
208: printf("Rangekey\n");
209: # endif
210:
211: a = ap;
212: sec_indx = a->sec_index == TRUE;
213: low = l;
214: high = h;
215: allexact = -1; /* assume all clauses equality clauses */
216: s = De.ov_simp;
217: success = FALSE;
218: if (a->mode == LRANGEKEY)
219: {
220:
221: for (ns = 0; ns < De.ov_nsimp; ns++)
222: {
223: rel = s->relop;
224: for (i = 0; d = a->keydno[i]; i++)
225: {
226: if (d == s->att)
227: {
228: /* this is either a high range value or low range value */
229: lowkey = (rel == opGTGE);
230: if (lowkey || rel == opEQ)
231: {
232: /* low range key */
233: # ifdef xOTR1
234: if (tTf(85, 6))
235: printf("low key on dom %d\t", d);
236: # endif
237: low->keysym = s->const;
238: low->dnumber = sec_indx ? i+1 : d;
239: low++;
240: }
241: if (!lowkey || rel == opEQ)
242: {
243: /* high range key */
244: # ifdef xOTR1
245: if (tTf(85, 6))
246: printf("high key on dom %d\t", d);
247: # endif
248: high->keysym = s->const;
249: high->dnumber = sec_indx ? i+1 : d;
250: high++;
251: }
252: # ifdef xOTR1
253: if (tTf(85, 6))
254: prsym(s->const);
255: # endif
256: if (i == 0)
257: success = TRUE;
258: if (rel != opEQ)
259: allexact = 1; /* at least one inequality */
260: break;
261: }
262: }
263: s++; /* try next simple clause */
264: }
265: }
266:
267: high->dnumber = 0; /* mark end of list */
268: low->dnumber = 0; /* mask end of list */
269:
270: /* if success then return whether all clauses were equality */
271: if (success)
272: success = allexact;
273:
274: # ifdef xOTR1
275: if (tTf(85, 5))
276: printf("rangekey returning %d\n", success);
277: # endif
278: return (success);
279: }
280: /*
281: ** Setallkey takes a key struct, decodes it and
282: ** calls setkey with each value.
283: **
284: ** Called from strategy().
285: **
286: ** returns 0 if ok.
287: ** returns -1 in the special case of a deblanked hashkey
288: ** being bigger than the corresponding domain.
289: */
290:
291: setallkey(relkey, keytuple)
292: struct key *relkey;
293: char *keytuple;
294: {
295: register struct key *k;
296: register SYMBOL *sk;
297: register int dnum;
298: struct symbol **s;
299: char *p, temp[256];
300: int l;
301:
302: clearkeys(De.ov_scanr);
303: k = relkey;
304: while (dnum = k->dnumber)
305: {
306: s = &k->keysym;
307: sk = (SYMBOL *) De.ov_stack;
308: getsymbol(sk, &s); /* copy symbol to stack. caution:getsym changes the value of s. */
309: rcvt(sk, De.ov_scanr->relfrmt[dnum], De.ov_scanr->relfrml[dnum]); /* convert key to correct type */
310: p = (char *)&sk->value;
311:
312: if (sk->type == CHAR)
313: {
314: /*
315: ** The length of a character key must
316: ** be made equal to the domain length.
317: ** The key is copied to a temp place
318: ** and a null byte is inserted at the
319: ** end. In addition, if the key without
320: ** blanks is longer than the domain and
321: ** this is an exactkey, then the query
322: ** is false.
323: */
324: p = temp;
325: l = cmove(sk, p); /* copy symbol to temp removing blanks & nulls */
326: # ifdef xOTR1
327: if (tTf(86, 9))
328: printf("length is %d\n", l);
329: # endif
330: if (De.ov_fmode == EXACTKEY && l > (De.ov_scanr->relfrml[dnum] & I1MASK))
331: /* key too large. qualification is false */
332: return (-1);
333: }
334: setkey(De.ov_scanr, keytuple, p, dnum); /* set the key */
335: k++;
336: }
337: # ifdef xOTR1
338: if (tTf(86, 8))
339: printup(De.ov_scanr, keytuple);
340: # endif
341: return (0);
342: }
343: /*
344: ** Cmove copies a char symbol into "dest".
345: ** It stops when the length is reached or
346: ** when a null byte is found.
347: **
348: ** returns the number of non-blank chars
349: ** in the string.
350: */
351:
352: cmove(sym, dest)
353: SYMBOL *sym;
354: char *dest;
355: {
356: register char *d, *s;
357: register int l;
358: int blank;
359:
360: s = sym->value.sym_data.cptype; /* s points to the char string */
361: d = dest;
362: blank = 0;
363:
364: for (l = (sym->len & I1MASK); l--; s++)
365: {
366: *d++ = *s;
367: if (*s == ' ')
368: blank++;
369: if (*s == '\0')
370: {
371: d--;
372: break;
373: }
374: }
375:
376: *d = '\0';
377: return ((d - dest) - blank); /* return length of string */
378: }
379: /*
380: ** Indexcheck is called by scan() to check whether
381: ** a secondary index tuple satisfies the simple
382: ** clauses under which it was scanned.
383: **
384: ** Returns 1 if the tuple is ok,
385: ** 0 otherwise.
386: */
387:
388: indexcheck()
389: {
390: register int i;
391:
392: if (De.ov_fmode == EXACTKEY)
393: i = keycheck(De.ov_lkey_struct, De.ov_keyl, 0); /* check for equality */
394: else
395: {
396: i = keycheck(De.ov_lkey_struct, De.ov_keyl, 1); /* check for >= */
397: /* If the lowkey passed, check the highkey also */
398: if (i)
399: i = keycheck(De.ov_hkey_struct, De.ov_keyh, -1); /* check for <= */
400: }
401: # ifdef xOTR1
402: if (tTf(86, 10))
403: printf("indexcheck ret %d\n", i);
404: # endif
405: return (i);
406: }
407: /*
408: ** Keycheck compares De.ov_intup with keytuple
409: ** according to the domains specified in the
410: ** "keys" struct.
411: **
412: ** mode is either >0, =0, <0 depending on
413: ** whether check is for De.ov_intup >= keytuple,
414: ** De.ov_intup == keytuple, De.ov_intup <= keytuple respectively
415: **
416: ** returns TRUE or FALSE accordingly.
417: */
418:
419: keycheck(keys, keytuple, mode)
420: struct key *keys;
421: char *keytuple;
422: int mode;
423: {
424: register struct key *k;
425: register char *kp;
426: register int dnum;
427: int offset, i, success;
428:
429: kp = keytuple;
430: success = TRUE;
431:
432: for (k = keys; dnum = k->dnumber; k++)
433: {
434:
435: offset = De.ov_scanr->reloff[dnum];
436: if (i = icompare(&De.ov_intup[offset], &kp[offset], De.ov_scanr->relfrmt[dnum], De.ov_scanr->relfrml[dnum] & I1MASK))
437: {
438: if (i < 0 && mode < 0 || i > 0 && mode > 0)
439: continue;
440: success = FALSE;
441: break;
442: }
443: }
444: return (success);
445: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.