|
|
1.1 root 1: # include <ingres.h>
2: # include <symbol.h>
3: # include <tree.h>
4: # include "../decomp/globs.h"
5: # include <sccs.h>
6:
7: SCCSID(@(#)scan.c 8.1 12/31/84)
8:
9:
10: /*
11: ** SCAN
12: **
13: ** performs tuple by tuple scan of source reln or index reln
14: ** within limits found by strategy routine.
15: ** When the source reln tuple is obtained the interpreter is invoked
16: ** to continue further processing
17: **
18: */
19:
20:
21: scan()
22: {
23: register j, mode, domno;
24: struct symbol **rlist; /* "result" list of query */
25: long count;
26: long tid, temptid;
27: char agtup[MAXTUP], outtup1[MAXTUP];
28: int qualfound, ok, istarget;
29: struct symbol *interpret();
30: int getnxt;
31: long pageid, lpageid;
32:
33: # ifdef xOTR1
34: if (tTf(71, -1))
35: {
36: printf("SCAN\tScanr=%.12s\n", De.ov_scanr ? De.ov_scanr->reldum.relid : "(none)");
37: printf("\tDe.ov_result %x\n", De.ov_result);
38: if (tTf(71, 4))
39: printf(" De.ov_alist=%x, De.ov_bylist=%x, De.ov_tlist=%x, De.ov_qlist=%x\n", De.ov_alist, De.ov_bylist, De.ov_tlist, De.ov_qlist);
40: if (De.ov_result)
41: printdesc(De.ov_result);
42: }
43: # endif
44:
45: if (De.ov_result || De.ov_alist)
46: {
47: if (De.ov_result)
48: {
49: clr_tuple(De.ov_result, De.ov_outtup);
50: }
51: else
52: {
53: j = MAXTUP;
54: while (j--)
55: De.ov_outtup[j] = 0;
56: }
57: }
58:
59: count = 0;
60: qualfound = EMPTY;
61: mode = De.de_qmode;
62:
63: /*
64: ** Check for identical source and result relations.
65: ** For modes mdREPL and mdDEL, De.ov_origtup must point
66: ** to the original (unmodified result tuple).
67: **
68: ** If there is no De.ov_source or De.ov_result relations then
69: ** the code has no effect.
70: */
71:
72: if (De.ov_source == NULL ||
73: !bequal(De.ov_source->reldum.relid, De.ov_result->reldum.relid, MAXNAME))
74: {
75: De.ov_diffrel = TRUE;
76: De.ov_origtup = outtup1;
77: }
78: else
79: {
80: De.ov_diffrel = FALSE;
81: De.ov_origtup = De.ov_intup;
82: }
83:
84: /* determine type of result list */
85: /* the only valid combinations are:
86: **
87: ** De.ov_tlist=no De.ov_alist=no De.ov_bylist=no
88: ** De.ov_tlist=yes De.ov_alist=no De.ov_bylist=no
89: ** De.ov_tlist=no De.ov_alist=yes De.ov_bylist=no
90: ** De.ov_tlist=no De.ov_alist=yes De.ov_bylist=yes
91: */
92:
93: if (De.ov_tlist)
94: istarget = TRUE;
95: else
96: istarget = FALSE;
97:
98: rlist = (De.ov_tlist? De.ov_tlist: De.ov_alist);
99: if (De.ov_bylist)
100: rlist = 0;
101:
102: De.ov_counter= &count;
103: if (De.ov_bylist)
104: {
105: /*
106: ** For aggregate functions the result relation
107: ** is in the format:
108: ** domain 1 = I4 (used as a counter)
109: ** domain 2 through relatts - De.ov_agcount (by-domains)
110: ** remaining domains (the actual aggregate values)
111: */
112:
113: /* set up keys for the getequal */
114: /* domno must end with the domain number of the first aggregate */
115:
116: for (domno = 2; domno <= De.ov_result->reldum.relatts - De.ov_agcount; domno++)
117: De.ov_result->relgiven[domno] = 1;
118:
119:
120: De.ov_counter = (long *)De.ov_outtup; /* first four bytes of De.ov_outtup is counter for De.ov_bylist */
121: }
122:
123:
124: /*
125: ** check for constant qualification.
126: ** If the constant qual is true then remove
127: ** the qual to save reprocessing it.
128: ** If it is false then block further processing.
129: */
130:
131: ok = TRUE;
132: if (De.ov_qlist && De.ov_qualvc == 0)
133: if (interpret(FALSE, De.ov_qlist)->value.sym_data.i2type)
134: De.ov_qlist = 0; /* qual always true */
135: else
136: ok = FALSE; /* qual always false */
137:
138:
139:
140: /* if no source relation, interpret target list */
141: if (!De.ov_scanr && ok)
142: {
143: /* there is no source relation and the qual is true */
144: qualfound = NONEMPTY;
145: De.ov_tend = De.ov_outtup;
146: /* if there is a rlist then process it. (There should always be one) */
147: if (rlist)
148: {
149: (*De.ov_counter)++;
150: interpret(istarget, rlist);
151: }
152: if (De.ov_tlist)
153: dispose(mode);
154: else
155: if (De.ov_userqry)
156: De.ov_tupsfound++;
157: }
158:
159:
160: if (De.ov_scanr && ok)
161: {
162: /* stop search if exact lid provided */
163: getnxt = (De.ov_fmode == BTREEKEY) ? CURTUP : NXTTUP;
164: /* There is a source relation. Iterate through each tuple */
165: pluck_page(&De.ov_hitid, &lpageid);
166: while (!(j = get(De.ov_scanr, &De.ov_lotid, &De.ov_hitid, De.ov_intup, getnxt)))
167: {
168: # ifdef xOTR1
169: if (tTf(71, 5))
170: {
171: if (De.ov_scanr != De.ov_source)
172: printf("Sec Index:");
173: else
174: printf("De.ov_intup:");
175: printup(De.ov_scanr, De.ov_intup);
176: dumptid(&De.ov_lotid);
177: }
178: # endif
179: if (De.ov_fmode == BTREERANGE && De.ov_scanr->reldum.relspec == M_HEAP)
180: {
181: pluck_page(&De.ov_lotid, &pageid);
182: if (pageid >= lpageid + 1)
183: break;
184: }
185: De.ov_intid = De.ov_lotid;
186: if (De.ov_scanr != De.ov_source)
187: {
188: /* make sure index tuple is part of the solution */
189: if (!indexcheck())
190: /* index keys don't match what we want */
191: continue;
192: bmove(De.ov_intup + De.ov_scanr->reldum.relwid - TIDLEN, (char *)&tid, TIDLEN);
193: if (j = get(De.ov_source, &tid, &temptid, De.ov_intup, CURTUP))
194: syserr("scan:indx get %d %.12s", j, De.ov_scanr->reldum.relid);
195: # ifdef xOTR1
196: if (tTf(71, 6))
197: {
198: printf("De.ov_intup:");
199: printup(De.ov_source, De.ov_intup);
200: }
201: # endif
202: De.ov_intid = tid;
203: }
204:
205:
206: if (!De.ov_qlist || interpret(FALSE,De.ov_qlist)->value.sym_data.i2type)
207: {
208: qualfound = NONEMPTY;
209: De.ov_tend = De.ov_outtup;
210: if (rlist)
211: {
212: (*De.ov_counter)++;
213: interpret(istarget,rlist);
214: }
215:
216: if (De.ov_tlist)
217: dispose(mode);
218: else
219: if (De.ov_userqry)
220: De.ov_tupsfound++;
221:
222: if (!De.ov_targvc) /* constant Target list */
223: break;
224:
225:
226: /* process De.ov_bylist if any */
227: if (De.ov_bylist)
228: {
229: interpret(istarget,De.ov_bylist);
230: if ((j = getequal(De.ov_result, De.ov_outtup, agtup, &De.ov_uptid)) < 0)
231: syserr("scan:getequal %d,%.12s", j, De.ov_result->reldum.relid);
232:
233: if (!j)
234: {
235: /* match on bylist */
236: bmove(agtup, De.ov_outtup, De.ov_result->reldum.relwid);
237: mode = mdREPL;
238: (*De.ov_counter)++;
239: }
240: else
241: {
242: /* first of this bylist */
243: mode = mdAPP;
244: *De.ov_counter = 1;
245: }
246:
247: De.ov_tend = De.ov_outtup + De.ov_result->reloff[domno];
248: interpret(istarget,De.ov_alist);
249: dispose(mode);
250: }
251: }
252: if (De.ov_fmode == BTREEKEY)
253: break;
254: }
255:
256:
257: if (j < 0 && De.ov_fmode != BTREEKEY)
258: syserr("scan:get prim %d %.12s", j, De.ov_source->reldum.relid);
259: }
260: if (De.ov_result)
261: {
262: if (j = noclose(De.ov_result))
263: syserr("scan:noclose %d %.12s", j, De.ov_result->reldum.relid);
264: }
265: return (qualfound);
266: }
267: /*
268: ** DISPOSE
269: */
270:
271: dispose(mode)
272: {
273: register int i;
274:
275: i = 0;
276:
277: if (!De.ov_result)
278: {
279: if (Equel)
280: equeleol(EOTUP);
281: else
282: printeol();
283: }
284: else
285: {
286: # ifdef xOTR1
287: if (tTf(71, -1))
288: {
289: if (tTf(71, 1))
290: printf("mode=%d,",mode);
291: if (tTf(71, 2) && (mode == mdREPL || mode == mdDEL))
292: printf("De.ov_uptid:%ld, ",De.ov_uptid);
293: if (tTf(71, 3))
294: if (mode == mdDEL)
295: printup(De.ov_source, De.ov_intup);
296: else
297: printup(De.ov_result, De.ov_outtup);
298: }
299: # endif
300:
301:
302: /* SPOOL UPDATES OF EXISTING USER RELNS TO BATCH PROCESSOR */
303: if (De.de_buflag)
304: {
305: addbatch(&De.ov_uptid, De.ov_outtup, De.ov_origtup);
306: return;
307: }
308:
309: /* PERFORM ALL OTHER OPERATIONS DIRECTLY */
310: switch (mode)
311: {
312: case mdRETR:
313: case mdAPP:
314: if ((i = insert(De.ov_result, &De.ov_uptid, De.ov_outtup, NODUPS)) < 0)
315: syserr("dispose:insert %d %.12s", i, De.ov_result->reldum.relid);
316: break;
317:
318: case mdREPL:
319: if ((i = replace(De.ov_result, &De.ov_uptid, De.ov_outtup, NODUPS)) < 0)
320: syserr("dispose:replace %d %.12s", i, De.ov_result->reldum.relid);
321: break;
322:
323: case mdDEL:
324: if ((i = delete(De.ov_result, &De.ov_uptid)) < 0)
325: syserr("dispose:delete %d %.12s", i, De.ov_result->reldum.relid);
326: break;
327:
328: default:
329: syserr("dispose:bad mode %d", mode);
330: }
331: }
332:
333: if (De.ov_userqry && i == 0)
334: De.ov_tupsfound++;
335: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.