1: # include "../ingres.h" 2: # include "../aux.h" 3: # include "../pipes.h" 4: # include "../tree.h" 5: # include "../symbol.h" 6: # include "parser.h" 7: 8: /* 9: ** RNGINIT 10: ** initializes the pointers in the range table 11: ** it should be called prior to starting the parsing 12: ** it also initializes the attrib stash stuff because 13: ** the attrib stash is really part of the range table 14: */ 15: rnginit() 16: { 17: register int i; 18: register struct atstash *atptr; 19: register struct rngtab *rptr; 20: 21: rptr = Rngtab; /* ptr to head of range table */ 22: for (i = 0; i <= MAXVAR; i++, rptr++) /* ">=" includes the internal entry */ 23: { 24: rptr->ractiv = 0; 25: rptr->rmark = 0; 26: rptr->rposit = i; 27: smove("", rptr->varname); 28: smove("", rptr->relnm); 29: rptr->rstat = 0; 30: rptr->ratts = 0; 31: rptr->attlist = NULL; 32: } 33: rngreset(); 34: atptr = Attable; 35: for (i = 0; i < MAXATT - 1; i++) 36: { 37: atptr->atbnext = atptr + 1; 38: atptr++; 39: } 40: atptr->atbnext = NULL; 41: Freeatt = Attable; 42: } 43: 44: /* 45: ** RNGLOOK 46: ** returns a pointer to the range table entry else 0 47: ** type = LOOKREL lookup relation 48: ** type = LOOKVAR lookup variable 49: */ 50: struct rngtab * 51: rnglook(p, type) 52: char *p; 53: int type; 54: { 55: register struct rngtab *rptr; 56: register char *param; 57: register int i; 58: 59: param = p; 60: rptr = Rngtab; 61: switch (type) 62: { 63: case LOOKVAR: 64: case LOOKREL: 65: break; 66: 67: default: 68: syserr("rnglook: type '$d'", type); 69: } 70: for (i = 0; i < MAXVAR; i++, rptr++) /* search external vbles only */ 71: { 72: if (rptr->ractiv == 1 && scompare(param, MAXNAME, (type == LOOKVAR ? rptr->varname : rptr->relnm), MAXNAME) == 0) 73: { 74: rptr->rmark = 1; 75: # ifdef xPTR2 76: tTfp(21, 6, "fnd '%s' at '%d'\n", param, rptr->rentno); 77: # endif 78: rngfront(rptr); 79: return (rptr); 80: } 81: } 82: return (NULL); 83: } 84: 85: /* 86: ** RNGENT 87: ** Insert variable and relation in range table. 88: */ 89: struct rngtab * 90: rngent(type, var, rel, relown, atts, relstat) 91: int type; 92: char *var; 93: char *rel; 94: char *relown; 95: int atts; 96: int relstat; 97: { 98: register struct rngtab *rptr; 99: struct rngtab *rngatndx(); 100: 101: # ifdef xPTR2 102: if (tTf(21, 0)) 103: { 104: printf("rngent:\ttyp=%d\tvar=%s\trel=%s\n\town=%.2s\tatts=%d\tstat=%o\n", type, var, rel, relown, atts, relstat); 105: } 106: # endif 107: if (type == R_INTERNAL) 108: rptr = &Rngtab[MAXVAR]; 109: else if (type == R_EXTERNAL) 110: { 111: if ((rptr = rnglook(var, LOOKVAR)) == NULL) 112: { 113: /* not in range table */ 114: rptr = rngatndx(MAXVAR - 1); 115: } 116: rngfront(rptr); 117: } 118: else 119: syserr("rngent: type '%d'", type); 120: if (scompare(rel, MAXNAME, rptr->relnm, MAXNAME) != 0 || 121: !bequal(relown, rptr->relnowner, 2)) 122: { 123: attfree(rptr->attlist); 124: rptr->attlist = NULL; 125: } 126: 127: pmove(var, rptr->varname, MAXNAME, '\0'); 128: pmove(rel, rptr->relnm, MAXNAME, '\0'); 129: bmove(relown, rptr->relnowner, 2); 130: rptr->ractiv = 1; 131: rptr->ratts = atts; 132: rptr->rstat = relstat; 133: return (rptr); 134: } 135: 136: /* 137: ** RNGDEL 138: ** removes an entry from the range table 139: ** removes all variables for the relation name 140: */ 141: rngdel(rel) 142: char *rel; 143: { 144: register struct rngtab *rptr; 145: 146: while ((rptr = rnglook(rel, LOOKREL)) != NULL) 147: { 148: smove("", rptr->relnm); 149: smove("", rptr->varname); 150: rptr->rmark = 0; 151: rptr->ractiv = 0; 152: rngback(rptr); 153: attfree(rptr->attlist); 154: rptr->attlist = NULL; 155: } 156: } 157: 158: /* 159: ** RNGSEND 160: ** Writes range table information needed by DECOMP and OVQP. 161: */ 162: rngsend() 163: { 164: register struct rngtab *rptr; 165: register int i; 166: 167: rptr = Rngtab; 168: for (i = 0; i < MAXVAR; i++, rptr++) 169: { 170: if (rptr->rmark != 0) 171: { 172: rngwrite(rptr); 173: } 174: } 175: 176: /* send result relation range entry if not already sent */ 177: if (Resrng && Resrng->rentno == MAXVAR) 178: { 179: rngwrite(Resrng); 180: } 181: } 182: 183: /* 184: ** RNGFRONT 185: ** move entry 'r' to head of range table list 186: */ 187: rngfront(r) 188: struct rngtab *r; 189: { 190: register struct rngtab *rptr; 191: register struct rngtab *fptr; 192: register int i; 193: 194: fptr = r; 195: rptr = Rngtab; 196: for (i = 0; i < MAXVAR; i++, rptr++) /* check all external vbles */ 197: { 198: if (rptr->rposit < fptr->rposit) 199: rptr->rposit++; 200: } 201: fptr->rposit = 0; 202: } 203: 204: /* 205: ** RNGBACK 206: ** move entry 'r' to back of range table list 207: */ 208: rngback(r) 209: struct rngtab *r; 210: { 211: register struct rngtab *rptr; 212: register struct rngtab *bptr; 213: register int i; 214: 215: bptr = r; 216: rptr = Rngtab; 217: for (i = 0; i < MAXVAR; i++, rptr++) /* check all external vbles */ 218: { 219: if (rptr->rposit > bptr->rposit) 220: rptr->rposit--; 221: } 222: bptr->rposit = MAXVAR - 1; 223: } 224: 225: /* 226: ** RNGRESET 227: ** reset the used marks to '0' 228: */ 229: rngreset() 230: { 231: register struct rngtab *rptr; 232: register int i; 233: 234: rptr = Rngtab; 235: for (i = MAXVAR - 1; i >= 0; i--, rptr++) /* only do external ones */ 236: { 237: rptr->rmark = 0; 238: rptr->rentno = i; 239: } 240: Rngtab[MAXVAR].rentno = MAXVAR; /* internal vble is always MAXVAR */ 241: } 242: 243: /* 244: ** RNGOLD -- find least recently used vble entry 245: */ 246: struct rngtab * 247: rngatndx(ndx) 248: int ndx; 249: { 250: register struct rngtab *rptr; 251: register int i; 252: 253: rptr = Rngtab; 254: for (i = 0; i < MAXVAR; i++, rptr++) /* do external vbles */ 255: { 256: if (rptr->rposit == ndx) 257: return (rptr); 258: } 259: syserr("rngatndx: can't find %d", ndx); 260: } 261: 262: /* 263: ** CHECKUPD 264: ** checks to make sure that the user can update the relation 'name1' 265: ** the 'open' parameter is set if 'Reldesc' contains the openr info 266: ** for the relation in question. 267: */ 268: checkupd(rptr) 269: struct rngtab *rptr; 270: { 271: if (!Noupdt) 272: return; 273: if (rptr->rstat & S_NOUPDT) 274: /* no updates allowed on this relation */ 275: yyerror(CANTUPDATE, rptr->relnm, 0); 276: } 277: 278: /* 279: ** RNGFRESH -- check the range table relstat information for accuracy 280: ** 281: ** If the command specified could have changed the relstat info 282: ** make the appropriate adjustments to the range table 283: */ 284: rngfresh(op) 285: int op; 286: { 287: register struct rngtab *rptr; 288: register int i; 289: struct descriptor desc; 290: 291: /* search the entire table! */ 292: for (i = 0, rptr = Rngtab; i <= MAXVAR; i++, rptr++) 293: { 294: if (!rptr->ractiv) 295: continue; 296: switch (op) 297: { 298: case mdDESTROY: 299: if ((rptr->rstat & (S_VBASE | S_INTEG | S_PROTUPS | S_INDEX)) != 0) 300: { 301: fixordel: 302: /* 303: ** openr the relation, if it doesn't exist make 304: ** sure that all range table entries are gone 305: */ 306: if (!openr(&desc, -1, rptr->relnm)) 307: { 308: /* relation still there, copy bits anyway */ 309: rptr->rstat = desc.relstat; 310: } 311: else 312: { 313: /* relation not there, purge table */ 314: rngdel(rptr->relnm); 315: } 316: } 317: break; 318: 319: case mdVIEW: 320: if ((rptr->rstat & S_VBASE) == 0) 321: { 322: fixorerr: 323: /* 324: ** if the relation doesn't exist then it is 325: ** a syserr, otherwise, copy the bits. 326: */ 327: if (!openr(&desc, -1, rptr->relnm)) 328: { 329: /* exists, copy bits */ 330: rptr->rstat = desc.relstat; 331: } 332: else 333: { 334: /* not there, syserr */ 335: syserr("RNGFRESH: extra entry: %s", rptr->relnm); 336: } 337: } 338: break; 339: 340: case mdPROT: 341: if ((rptr->rstat & S_PROTUPS) == 0) 342: goto fixorerr; 343: break; 344: 345: case mdINTEG: 346: if ((rptr->rstat & S_INTEG) == 0) 347: goto fixorerr; 348: break; 349: 350: case mdMODIFY: 351: if ((rptr->rstat & S_INDEX) != 0) 352: goto fixordel; 353: break; 354: 355: default: 356: return; /* command ok, dont waste time on rest of table */ 357: } 358: } 359: }