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: }