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