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