|
|
1.1 root 1: # include <ingres.h>
2: # include <aux.h>
3: # include <symbol.h>
4: # include <tree.h>
5: # include "parser.h"
6: # include <pv.h>
7: # include "scanner.h"
8: # include <sccs.h>
9: # include <../ovqp/ovqp.h>
10: # include <errors.h>
11:
12: SCCSID(@(#)control.c 8.3 2/8/85)
13:
14: /*
15: ** CONTROL.C -- -- collection of control functions for the parser
16: **
17: ** These routines administrate the operation of the parser for internal
18: ** sequencing. There are 2 pairs of routines, one pair for each
19: ** quel statement, and one for each go-block, and there is one
20: ** routine to finish retrieve statements.
21: **
22: ** Defines:
23: ** startgo -- initialize for a go-block
24: ** init_quelst -- initialize for a quel statement
25: ** endquelst -- clean up after a quel statement
26: ** endretrieve -- clean up after a retrieve
27: ** endgo -- clean up after a go-block
28: **
29: ** Trace Flags:
30: ** control.c ~~ 48, 49
31: **
32: ** History:
33: ** 6 Jun 80 (jiw) modified and redocumented for 6.3
34: ** 15 Jan 79 (rick) collected and documented more
35: ** ancient history
36: */
37:
38: /*
39: ** INIT_QUELST -- set vbles for default mode before each quel statement
40: **
41: ** Parameters:
42: ** none
43: **
44: ** Returns:
45: ** nothing
46: **
47: ** Trace Flags:
48: ** init_quelst ~~ 48.0
49: */
50:
51: int
52: init_quelst()
53: {
54: extern int neederr();
55: extern ack_err();
56: extern int Err_current;
57: extern int Pars;
58: extern int Lcase;
59: extern int Dcase;
60: extern int Agflag;
61: extern int Opflag;
62: extern int Resrng;
63: extern int Qlflag;
64:
65: # ifdef xPTR3
66: tTfp(48, 0, "Init_quelst\n");
67: # endif
68:
69: Err_current = 0; /* no error yet */
70: Pars = 1; /* set scanner into "parser" mode */
71: Lcase = Dcase; /* set case mapping to default */
72: Agflag = 0; /* reset aggregate flag */
73: Opflag = 0; /* reset qmode flag */
74: Resrng = -1; /* reset result relation slot */
75: Qlflag = 0; /* reset qualification flag */
76:
77: initp(); /* initialize parameter vector */
78: init_qt(); /* assume we have qrytree */
79:
80: freesym(); /* free symbol table space */
81: rngreset(); /* reset used bits in range tbl */
82:
83: return (1);
84: }
85:
86: /*
87: ** ENDQUELST -- finish command checking and processing for each quel statement
88: **
89: ** Parameters:
90: ** op -- the type of query to finish up
91: **
92: ** Returns:
93: ** nothing
94: **
95: ** Trace Flags:
96: ** endquelst ~~ 48.4, 48.5
97: */
98:
99: int
100: endquelst(op)
101: register int op;
102: {
103: register int i;
104: char ibuf[2]; /* two char buffer for index keys */
105:
106: extern char *Indexspec;
107: extern char *Indexname;
108: extern int Equel;
109: extern int Agflag;
110:
111: extern struct lasttok *Lasttok;
112:
113: extern int yyerrflag;
114: extern int Err_current;
115: extern int Ingerr;
116: extern int Err_fnd;
117:
118: extern DESC Attdes;
119: extern DESC Reldesc;
120: extern int Rsdmno;
121: extern PARRNG Parrng[];
122: extern int Resrng;
123:
124: extern int printtrail();
125:
126: # ifdef xPTR3
127: if (tTf(48, 4))
128: prvect(0, getp());
129: # endif
130:
131: /* check next token for GOVAL if the next token has been read */
132: if (!Err_current && !yyerrflag)
133: switch (op)
134: {
135: case mdSAVE:
136: case mdCOPY:
137: case mdCREATE:
138:
139: # ifdef DISTRIB
140: case mdDCREATE:
141: # endif
142:
143: case mdINDEX:
144: case mdRANGE:
145: case mdSTOP:
146: break;
147:
148: default:
149: /* has vble ending and therefore must detect valid end of command */
150: # ifdef xPTR3
151: tTfp(48, 5, "before NXTCMDERR\n");
152: # endif
153: if (Lastok.tokop != GOVAL)
154: /* next token not start of command */
155: par_error(NXTCMDERR, WARN, 0);
156: break;
157: }
158:
159: if (Agflag >= MAXAGG)
160: /* too many aggregates */
161: par_error(AGGXTRA, WARN, 0);
162:
163: /* command ok so far, finish up */
164: if (!Err_fnd)
165: {
166: switch (op)
167: {
168: case mdINDEX:
169: if (tTf(48, 5))
170: printf("mdINDEX\n");
171: if (call(op, NULL) < 0)
172: ack_err();
173: if (tTf(48, 5))
174: printf("after call to call\n");
175:
176: if (Ingerr)
177: {
178: if (tTf(48, 5))
179: printf("Ingerr = %d\n", Ingerr);
180:
181: endgo();
182:
183: return (-1);
184: }
185:
186: if (Indexspec)
187: {
188: initp();
189: setp(PV_STR, Indexname); /* type */
190: setp(PV_STR, Indexspec); /* specs */
191: setp(PV_STR, "num");
192: for (i = 1; i <= Rsdmno; i++)
193: {
194: ibuf[0] = i & I1MASK;
195: ibuf[1] = '\0';
196: setp(PV_STR, ibuf);
197: }
198: if (call(mdMODIFY, NULL) < 0)
199: ack_err();
200: }
201: break;
202:
203: case mdRETR:
204: case mdRET_UNI:
205: case mdVIEW:
206: if (Resrng >= 0) /* implies result reln */
207: {
208: if (calln(mdCREATE, NULL) < 0)
209: ack_err();
210:
211: cleanrel(&Attdes);
212:
213: if ((i = openr(&Reldesc, OR_RELTID, trim_relname(Parrng[Resrng].vardesc.reldum.relid))) < 0)
214: syserr("result reln: error in openr '%d'", i);
215:
216: rngent(R_INTERNAL, "", &Reldesc);
217: }
218: else if (!Equel)
219: /* need to print header */
220: header(getp());
221:
222: if (Ingerr)
223: {
224: /*
225: ** might be nice to back out the create already done
226: ** by this point so that the user doesn't need to
227: */
228: resetp();
229:
230: endgo(); /* abort rest of go-block */
231:
232: return (-1);
233: }
234: initp();
235: /* fall through */
236:
237: case mdAPP:
238: case mdDEL:
239: case mdREPL:
240: if (op != mdVIEW)
241: {
242: call_tree(op, mdQRY, ack_err);
243:
244: if (op == mdRETR || op == mdRET_UNI)
245: endretrieve(ack_err);
246:
247: Patnum = 0;
248: for (i = 0; i < PATNUM; i++)
249: if (Pats[i].string)
250: {
251: free(Pats[i].string);
252: Pats[i].string = NULL;
253: Pats[i].len = 0;
254: }
255: break;
256: }
257:
258: # ifdef DISTRIB
259: case mdDISTRIB:
260: op = mdVIEW;
261: # endif
262: /* else, do VIEW */
263: setp(PV_STR, trim_relname(Parrng[Resrng].vardesc.reldum.relid));
264:
265: case mdINTEG:
266: case mdPROT:
267: call_tree(op, op, ack_err);
268: break;
269:
270: case mdCREATE:
271:
272: # ifdef DISTRIB
273: case mdDCREATE:
274: # endif
275:
276: case mdDESTROY:
277: case mdMODIFY:
278: # ifdef V6POINT3COMPAT
279: /* in this case, if an error in the dbu's will not */
280: /* cause other processing to halt */
281: call(op, NULL);
282: # else
283: if (call(op, NULL) < 0)
284: ack_err();
285: # endif
286: cleanrel(&Attdes);
287: break;
288:
289: case mdCOPY:
290: case mdHELP:
291: case mdPRINT:
292: case mdSAVE:
293: case mdDISPLAY:
294: case mdREMQM:
295: # ifdef V6POINT3COMPAT
296: call(op, NULL);
297: # else
298: if (call(op, NULL) < 0)
299: ack_err();
300: # endif
301: break;
302:
303: case mdSTOP:
304: case mdRANGE:
305: break;
306:
307: default:
308: syserr("Endquelst: bad op %d", op);
309: }
310: }
311:
312: /* refresh relstat bits if necessary */
313: rngfresh(op);
314: if (init_quelst() < 0)
315: return (-1);
316:
317: return (1);
318: }
319:
320: /*
321: ** STARTGO -- do whatever needs doing to set up a go-block
322: **
323: ** Parameters:
324: ** none
325: **
326: ** Returns:
327: ** nothing
328: **
329: ** Trace Flags:
330: ** startgo ~~ 48.8
331: */
332:
333: startgo()
334: {
335: extern int Err_fnd;
336: extern int Ing_err;
337: extern int yyline;
338:
339: # ifdef xPTR3
340: tTfp(48, 8, "startgo\n");
341: # endif
342:
343: /* initialize for go-block */
344: get_scan(PRIME); /* prime the scanner input */
345: Err_fnd = 0; /* no errors have been found yet */
346: Ingerr = 0;
347:
348: if (init_quelst() < 0) /* most other init's are done for each statement */
349: return (-1);
350:
351: yyline = 1; /* reset line counter */
352:
353: return (1);
354: }
355:
356: /*
357: ** ENDGO -- do whatever needs doing to clean up after a go block
358: **
359: ** Parameters:
360: ** none
361: **
362: ** Returns:
363: ** nothing
364: **
365: ** Trace Flags:
366: ** endgo ~~ 48.12
367: */
368:
369: endgo()
370: {
371: # ifdef xPTR3
372: tTfp(48, 12, "endgo\n");
373: # endif
374:
375: if (!Equel && Err_fnd > 1)
376: error(SUMMARY, iocv(Err_fnd), 0);
377:
378: get_scan(SYNC);
379:
380: resetp();
381: }
382:
383: /*
384: ** ENDRETRIEVE -- finishes any sort of retrieve
385: **
386: ** Endretrieve either creates a result relation or prints a trailer
387: **
388: ** Parameters:
389: ** err_fcn -- function to pass to call
390: **
391: ** Returns:
392: ** nothing
393: **
394: ** Trace Flags:
395: ** endretrieve ~~ 48.14
396: **
397: ** History:
398: ** June '80 -- (jiw) broken off from call_tree
399: */
400:
401: endretrieve(err_fcn)
402: int (*err_fcn)();
403: {
404: extern int Resrng;
405: extern char *Relspec;
406: extern PARRNG Parrng[];
407: extern int Equel;
408: extern int Hdr;
409:
410: if (Resrng >= 0)
411: {
412: if (Relspec)
413: {
414: initp();
415:
416: setp(PV_STR, trim_relname(Parrng[Resrng].vardesc.reldum.relid));
417: setp(PV_STR, Relspec);
418: if (call(mdMODIFY, err_fcn) < 0)
419: (*err_fcn)();
420: }
421: }
422: else if (!Equel)
423: {
424: printeh();
425: Hdr = FALSE;
426: }
427: }
428:
429: printtrail()
430: {
431: extern int Equel;
432:
433: if (!Equel)
434: printeh();
435:
436: return (-1);
437: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.