1: # include "../ingres.h" 2: # include "../aux.h" 3: # include "../pipes.h" 4: # include "../symbol.h" 5: # include "parser.h" 6: # include "../scanner.h" 7: 8: /* 9: ** CONTROL.C -- -- collection of control functions for the parser 10: ** 11: ** These routines administrate the operation of the parser for internal 12: ** sequencing. There are 3 pairs of routines, one pair for each 13: ** quel statement, one for each go-block, and one to handle syncronization 14: ** with up and down processes. 15: ** 16: ** Defines: 17: ** init_quelst -- initialize for a quel statement 18: ** endquelst -- clean up after a quel statement 19: ** syncup -- sync the process above 20: ** syncdn -- sync the process below 21: ** startgo -- initialize for a go-block 22: ** endgo -- clean up after a go-block 23: ** 24: ** Trace Flags: 25: ** 33.0 -- in endquelst for done with it 26: ** 60.0 -- reading tuple count and saving 27: ** 60.1 -- final tuple count, written to monitor 28: ** 29: ** History: 30: ** 15 Jan 79 (rick) collected and documented more 31: ** ancient history 32: */ 33: 34: 35: 36: 37: 38: 39: 40: /* 41: ** INIT_QUELST -- set vbles for default mode before each quel statement 42: */ 43: init_quelst() 44: { 45: extern int neederr(); 46: 47: initp(); /* reset dbu buffer */ 48: initbuf(Qbuf, TREEMAX, TREEOFLO, &neederr); /* reset tree allocation */ 49: Ingerr = 0; /* clear error condition */ 50: Patflag = 0; /* reset pattern matching flag */ 51: Pars = 1; /* set scanner into "parser" mode */ 52: Lcase = Dcase; /* set case mapping to default */ 53: Agflag = 0; /* reset aggregate flag */ 54: Opflag = 0; /* reset qmode flag */ 55: Resrng = 0; /* reset result relation ptr */ 56: Qlflag = 0; /* reset qualification flag */ 57: freesym(); /* free symbol table space */ 58: rngreset(); /* reset used bits in range tbl */ 59: } 60: 61: /* 62: ** ENDQUELST -- finish command checking and processing for each quel statement 63: */ 64: endquelst(op1) 65: int op1; 66: { 67: register int i; 68: register int op; 69: char ibuf[2]; /* two char buffer for index keys */ 70: 71: op = op1; 72: 73: /* check next token for GOVAL if the next token has been read */ 74: switch (op) 75: { 76: case mdSAVE: 77: case mdCOPY: 78: case mdCREATE: 79: 80: # ifdef DISTRIB 81: case mdDCREATE: 82: # endif 83: 84: case mdINDEX: 85: case mdRANGE: 86: break; 87: 88: default: 89: /* has vble ending and therefore must detect valid end of command */ 90: if (Lastok.tokop != GOVAL) 91: /* next token not start of command */ 92: yyerror(NXTCMDERR, 0); 93: break; 94: } 95: if (Agflag >= MAXAGG) 96: /* too many aggregates */ 97: yyerror(AGGXTRA, 0); 98: 99: /* command ok so far, finish up */ 100: switch (op) 101: { 102: case mdRETR: 103: case mdRET_UNI: 104: case mdVIEW: 105: if (Resrng) 106: { 107: /* need to do create, everything is ready */ 108: call_p(mdCREATE, EXEC_DBU); 109: cleanrel(&Desc); 110: } 111: else if (!Equel) 112: /* need to print header */ 113: header(); 114: if (Ingerr) 115: { 116: /* 117: ** might be nice to back out the create already done 118: ** by this point so that the user doesn't need to 119: */ 120: endgo(); /* abort rest of go-block */ 121: reset(); 122: } 123: /* fall through */ 124: 125: case mdAPP: 126: case mdDEL: 127: case mdREPL: 128: if (op != mdVIEW) 129: { 130: call_tree(op, EXEC_DECOMP); 131: break; 132: } 133: 134: # ifdef DISTRIB 135: case mdDISTRIB: 136: op = mdVIEW; 137: # endif 138: /* else, do VIEW */ 139: initp(); 140: setp(Resrng->relnm); 141: call_tree(mdDEFINE, EXEC_QRYMOD); 142: call_p(op, EXEC_QRYMOD); 143: break; 144: 145: case mdINTEG: 146: case mdPROT: 147: call_tree(mdDEFINE, EXEC_QRYMOD); 148: call_p(op, EXEC_QRYMOD); 149: break; 150: 151: case mdCREATE: 152: 153: # ifdef DISTRIB 154: case mdDCREATE: 155: # endif 156: 157: case mdDESTROY: 158: case mdMODIFY: 159: call_p(op, EXEC_DBU); 160: cleanrel(&Desc); 161: break; 162: 163: case mdCOPY: 164: case mdHELP: 165: case mdPRINT: 166: case mdSAVE: 167: case mdDISPLAY: 168: case mdREMQM: 169: call_p(op, EXEC_DBU); 170: break; 171: 172: case mdRANGE: 173: break; 174: 175: case mdINDEX: 176: call_p(op, EXEC_DBU); 177: if (Ingerr) 178: { 179: endgo(); /* abort rest of go-block */ 180: reset(); 181: } 182: if (Indexspec) 183: { 184: setp(Indexname); 185: setp(Indexspec); 186: setp("num"); 187: for (i = 1; i <= Rsdmno; i++) 188: { 189: ibuf[0] = i & I1MASK; 190: ibuf[1] = '\0'; 191: setp(ibuf); 192: } 193: call_p(mdMODIFY, EXEC_DBU); 194: } 195: break; 196: } 197: 198: /* refresh relstat bits if necessary */ 199: rngfresh(op); 200: init_quelst(); 201: } 202: 203: /* 204: ** SYNCUP -- sync with process above 205: ** 206: ** send tuple count if present 207: */ 208: syncup() 209: { 210: struct pipfrmt p; 211: register struct pipfrmt *pp; 212: 213: pp = &p; 214: wrpipe(P_PRIME, pp, 0, 0, 0); 215: if (Lastcnt != NULL) 216: { 217: wrpipe(P_NORM, pp, W_up, Lastcnt, sizeof(*Lastcnt)); 218: } 219: wrpipe(P_END, pp, W_up); 220: } 221: 222: /* 223: ** SYNCDN -- wait for sync from below 224: ** 225: ** save tuple count if present 226: */ 227: syncdn() 228: { 229: struct retcode up; 230: struct pipfrmt p; 231: register struct pipfrmt *pp; 232: 233: pp = &p; 234: rdpipe(P_PRIME, pp); 235: if (rdpipe(P_NORM, pp, R_down, &up, sizeof(up)) != 0) 236: { 237: bmove(&up, &Lastcsp, sizeof(up)); 238: Lastcnt = &Lastcsp; 239: # ifdef xPTR3 240: if (tTf(60, 1)) 241: printf("Reading tuple count: %s\n", locv(Lastcnt->rc_tupcount)); 242: # endif 243: } 244: } 245: 246: /* 247: ** STARTGO -- do whatever needs doing to set up a go-block 248: */ 249: startgo() 250: { 251: /* initialize for go-block */ 252: getscr(1); /* prime the scanner input */ 253: Lastcnt = NULL; /* reset ptr to last tuple count */ 254: init_quelst(); /* most other init's are done for each statement */ 255: yyline = 1; /* reset line counter */ 256: yypflag = 1; /* reset action stmnts */ 257: } 258: 259: /* 260: ** ENDGO -- do whatever needs doing to clean up after a go block 261: */ 262: endgo() 263: { 264: getscr(2); 265: syncup(); 266: }