|
|
1.1 ! root 1: # include <ingres.h> ! 2: # include <aux.h> ! 3: # include <tree.h> ! 4: # include <symbol.h> ! 5: # include <range.h> ! 6: # include "parser.h" ! 7: # include <sccs.h> ! 8: ! 9: SCCSID(@(#)range_fcn.c 7.1 2/5/81) ! 10: ! 11: /* ! 12: ** Range table variables ! 13: */ ! 14: ! 15: PARRNG Parrng[MAXRANGE]; /* table for keeping track of atts */ ! 16: /* and allocation of range vars */ ! 17: int Resrng; /* result reln slot */ ! 18: ! 19: PARRNG *Rngfront; /* the front of Rnga */ ! 20: PARRNG *Rngback; /* the back of Qt.qt_rangev */ ! 21: ! 22: ! 23: /* ! 24: ** RANGE_FCN.C -- functions for manipulating the range table ! 25: ** ! 26: ** Trace Flags: ! 27: ** RANGE_FCN.C ~~ 66, 67 ! 28: */ ! 29: ! 30: ctlmod_decl(slot) ! 31: int slot; ! 32: { ! 33: extern PARRNG Parrng[]; ! 34: ! 35: Qt.qt_rangev[slot].rngvdesc = NULL; ! 36: if (declare(slot, &Parrng[slot].vardesc) != slot) ! 37: syserr("declare misdeclared"); ! 38: } ! 39: ! 40: /* ! 41: ** RNGINIT ! 42: ** initializes the pointers in the range table ! 43: ** it should be called prior to starting the parsing ! 44: ** it also initializes the attrib stash stuff because ! 45: ** the attrib stash is really part of the range table ! 46: ** ! 47: ** Trace Flags: ! 48: ** rnginit ~~ 66.0 ! 49: */ ! 50: rnginit() ! 51: { ! 52: register int slot; ! 53: register PARRNG *parrngptr; ! 54: register RANGEV *rngptr; ! 55: ! 56: # ifdef xPTR2 ! 57: tTfp(66, 0, "rnginit\n"); ! 58: # endif ! 59: ! 60: Rngfront = &Parrng[MAXVAR - 1]; /* ptr to head of range table */ ! 61: parrngptr = Parrng; ! 62: /* initialize first element */ ! 63: parrngptr->attlist = NULL; ! 64: parrngptr->backpt = NULL; ! 65: parrngptr->frontpt = &Parrng[1]; ! 66: ! 67: rngptr = Qt.qt_rangev; ! 68: ! 69: for (slot = 0, parrngptr = &Parrng[1]; slot < MAXVAR; slot++, parrngptr++) ! 70: { ! 71: parrngptr->attlist = NULL; ! 72: ! 73: parrngptr->frontpt = parrngptr + 1; ! 74: parrngptr->backpt = parrngptr - 1; ! 75: } ! 76: ! 77: Rngback = Parrng; ! 78: ! 79: parrngptr = &Parrng[MAXVAR - 1]; ! 80: ! 81: parrngptr->frontpt = NULL; ! 82: ! 83: /* MAXVAR SLOT = Resultvar */ ! 84: (++parrngptr)->attlist = NULL; ! 85: parrngptr->frontpt = parrngptr->backpt = NULL; ! 86: ! 87: Rngfront->frontpt = NULL; ! 88: ! 89: clrrange(); ! 90: ! 91: attinit(); ! 92: } ! 93: ! 94: /* ! 95: ** RNGLOOK ! 96: ** returns a pointer to the range table entry else 0 ! 97: ** type = LOOKREL lookup relation ! 98: ** type = LOOKVAR lookup variable ! 99: ** ! 100: ** Trace Flags: ! 101: ** rnglook ~~ 66.4, 66.5, 66.6 ! 102: */ ! 103: int ! 104: rnglook(name, type) ! 105: char *name; ! 106: int type; ! 107: { ! 108: register PARRNG *rptr; ! 109: ! 110: register int slot; ! 111: ! 112: # ifdef xPTR2 ! 113: tTfp(66, 4, "rnglook:\ttype = %s\tname = %s\n", ! 114: (type == LOOKVAR ? "variable" : "relation"), name); ! 115: ! 116: if (tTf(66, 5)) ! 117: printtable(); ! 118: # endif ! 119: ! 120: rptr = Parrng; ! 121: ! 122: for (slot = 0; slot < MAXVAR; slot++, rptr++) /* search external vbles only */ ! 123: { ! 124: if (rptr->relvused ! 125: && scompare(name, MAXNAME, ! 126: (type == LOOKVAR ? rptr->vardesc.relvname : rptr->vardesc.reldum.relid), ! 127: MAXNAME) == 0) ! 128: { ! 129: Qt.qt_rangev[slot].rngvmark = 1; ! 130: ! 131: # ifdef xPTR2 ! 132: tTfp(66, 6, "fnd '%s' at '%d'\n", name, slot); ! 133: # endif ! 134: ! 135: rngfront(slot); ! 136: return (slot); ! 137: } ! 138: } ! 139: return (-1); ! 140: } ! 141: ! 142: /* ! 143: ** RNGENT ! 144: ** ! 145: ** Insert variable and relation in range table. ! 146: ** ! 147: ** Trace Flags: ! 148: ** rngent ~~ 66.8 ! 149: */ ! 150: ! 151: int ! 152: rngent(type, var, desc) ! 153: int type; ! 154: char *var; ! 155: register DESC *desc; ! 156: { ! 157: register PARRNG *rptr; ! 158: register int slot; ! 159: ! 160: # ifdef xPTR2 ! 161: tTfp(66, 8, "rngent:\ttype=%s\tvar=%s\n", ! 162: (type == R_INTERNAL ? "internal" : "external"), var); ! 163: # endif ! 164: ! 165: if (type == R_INTERNAL) ! 166: slot = MAXVAR; /* the internal variable */ ! 167: else ! 168: { ! 169: if ((slot = rnglook(var, LOOKVAR)) < 0) ! 170: { ! 171: /* not in range table */ ! 172: slot = rngold(); ! 173: } ! 174: ! 175: rngfront(slot); ! 176: } ! 177: ! 178: rptr = &Parrng[slot]; ! 179: ! 180: if (scompare(desc->reldum.relid, MAXNAME + 2, ! 181: rptr->vardesc.reldum.relid, MAXNAME + 2) != 0) ! 182: { ! 183: attfree(rptr->attlist); ! 184: rptr->attlist = NULL; ! 185: } ! 186: ! 187: rptr->relvused = 1; ! 188: ! 189: bmove(desc, &rptr->vardesc, sizeof(*desc)); ! 190: pmove(var, rptr->vardesc.relvname, MAXNAME, ' '); ! 191: ! 192: ctlmod_decl(slot); ! 193: ! 194: return (slot); ! 195: } ! 196: ! 197: /* ! 198: ** RNGDEL ! 199: ** removes an entry from the range table ! 200: ** removes all variables for the relation name ! 201: ** ! 202: ** Trace Flags: ! 203: ** rngdel ~~ 66.12 ! 204: */ ! 205: rngdel(rel) ! 206: register char *rel; ! 207: { ! 208: register int slot; ! 209: ! 210: # ifdef xPTR2 ! 211: tTfp(66, 12, "rngdel: %12s\n", rel); ! 212: # endif ! 213: ! 214: while ((slot = rnglook(rel, LOOKREL)) >= 0) ! 215: { ! 216: Parrng[slot].relvused = 0; ! 217: rngback(slot); ! 218: attfree(Parrng[slot].attlist); ! 219: Parrng[slot].attlist = NULL; ! 220: } ! 221: } ! 222: ! 223: ! 224: /* ! 225: ** RNGFRONT ! 226: ** move entry 'r' to head of range table list ! 227: ** ! 228: ** Trace Flags: ! 229: ** rngfront ~~ 67.0 ! 230: */ ! 231: rngfront(slot) ! 232: int slot; ! 233: { ! 234: register PARRNG *fptr; ! 235: ! 236: # ifdef xPTR2 ! 237: tTfp(67, 0, "rngfront:\tslot %d\n", slot); ! 238: # endif ! 239: ! 240: ! 241: rngget(slot); ! 242: ! 243: fptr = &Parrng[slot]; ! 244: ! 245: fptr->frontpt = NULL; ! 246: fptr->backpt = Rngfront; ! 247: Rngfront->frontpt = fptr; ! 248: ! 249: Rngfront = fptr; ! 250: } ! 251: ! 252: /* ! 253: ** RNGBACK ! 254: ** move entry 'r' to back of range table list ! 255: ** ! 256: ** Trace Flags: ! 257: ** rngback ~~ 67.4 ! 258: */ ! 259: rngback(slot) ! 260: int slot; ! 261: { ! 262: register PARRNG *bptr; ! 263: ! 264: # ifdef xPTR2 ! 265: tTfp(67, 4, "rngback:\tslot %d\n", slot); ! 266: # endif ! 267: ! 268: rngget(slot); ! 269: ! 270: bptr = &Parrng[slot]; ! 271: ! 272: bptr->backpt = NULL; ! 273: bptr->frontpt = Rngback; ! 274: Rngback->backpt = bptr; ! 275: ! 276: Rngback = bptr; ! 277: } ! 278: ! 279: /* ! 280: ** RNGGET -- get a descriptor from range table ! 281: ** ! 282: ** Trace Flags: ! 283: ** rngget ~~ 67.8 ! 284: */ ! 285: ! 286: rngget(slot) ! 287: int slot; ! 288: { ! 289: register PARRNG *slotptr; ! 290: register PARRNG *forward; ! 291: register PARRNG *backward; ! 292: ! 293: # ifdef xPTR2 ! 294: tTfp(67, 8, "rngget:\tslot %d\n", slot); ! 295: # endif ! 296: ! 297: ! 298: slotptr = &Parrng[slot]; ! 299: forward = slotptr->frontpt; ! 300: backward = slotptr->backpt; ! 301: ! 302: if (slotptr == Rngfront) ! 303: { ! 304: Rngfront = backward; ! 305: backward->frontpt = NULL; ! 306: } ! 307: else if (slotptr == Rngback) ! 308: { ! 309: Rngback = forward; ! 310: forward->backpt = NULL; ! 311: } ! 312: else ! 313: { ! 314: forward->backpt = backward; ! 315: backward->frontpt = forward; ! 316: } ! 317: ! 318: slotptr->backpt = slotptr->frontpt = NULL; ! 319: } ! 320: ! 321: /* ! 322: ** RNGOLD -- find least recently used vble entry ! 323: ** ! 324: ** Trace Flags: ! 325: ** rngold ~~ 67.9 ! 326: */ ! 327: int ! 328: rngold() ! 329: { ! 330: # ifdef xPTR2 ! 331: tTfp(67, 9, "rngold %d.\n", Rngback - (PARRNG *) Parrng); ! 332: # endif ! 333: ! 334: return(Rngback - (PARRNG *) Parrng); ! 335: } ! 336: ! 337: /* ! 338: ** RNGRESET ! 339: ** reset the used marks to '0' ! 340: ** ! 341: ** Trace Flags: ! 342: ** rngreset ~~ 67.10 ! 343: */ ! 344: rngreset() ! 345: { ! 346: register int i; ! 347: register RANGEV *rangevptr; ! 348: ! 349: # ifdef xPTR2 ! 350: tTfp(67, 10, "rngreset().\n"); ! 351: # endif ! 352: ! 353: rangevptr = Qt.qt_rangev; ! 354: ! 355: for (i = 0; i < MAXVAR; i++, rangevptr++) /* only do external ones */ ! 356: rangevptr->rngvmark = 0; ! 357: } ! 358: ! 359: /* ! 360: ** CHECKUPD ! 361: ** checks to make sure that the user can update the relation 'name1' ! 362: ** the 'open' parameter is set if 'Reldesc' contains the openr info ! 363: ** for the relation in question. ! 364: ** ! 365: ** Trace Flags: ! 366: ** checkupd ~~ 67.11 ! 367: */ ! 368: checkupd(entnum) ! 369: int entnum; ! 370: { ! 371: extern int Noupdt; ! 372: extern PARRNG Parrng[]; ! 373: register PARRNG *rptr; ! 374: ! 375: # ifdef xPTR2 ! 376: tTfp(67, 11, "checkupd(%d).\n", entnum); ! 377: # endif ! 378: ! 379: rptr = &Parrng[entnum]; ! 380: ! 381: if (!Noupdt) ! 382: return; ! 383: if (rptr->vardesc.reldum.relstat & S_NOUPDT) ! 384: /* no updates allowed on this relation */ ! 385: par_error(CANTUPDATE, WARN, trim_relname(rptr->vardesc.reldum.relid), 0); ! 386: } ! 387: ! 388: /* ! 389: ** RNGFRESH -- check the range table relstat information for accuracy ! 390: ** ! 391: ** If the command specified could have changed the relstat info ! 392: ** make the appropriate adjustments to the range table ! 393: */ ! 394: rngfresh(op) ! 395: int op; ! 396: { ! 397: register PARRNG *rptr; ! 398: register int slot; ! 399: DESC desc; ! 400: ! 401: # ifdef xPTR2 ! 402: tTfp(67, 11, "rngfresh %d.\n", op); ! 403: # endif ! 404: ! 405: /* search the entire table! */ ! 406: for (slot = 0, rptr = Parrng; slot <= MAXVAR; slot++, rptr++) ! 407: { ! 408: if (!(rptr->relvused)) ! 409: continue; ! 410: ! 411: switch (op) ! 412: { ! 413: case mdDESTROY: ! 414: if ((rptr->vardesc.reldum.relstat & (S_VBASE | S_INTEG | S_PROTUPS | S_INDEX)) != 0) ! 415: { ! 416: fixordel: ! 417: /* ! 418: ** openr the relation, if it doesn't exist make ! 419: ** sure that all range table entries are gone ! 420: */ ! 421: if (!openr(&desc, -1, rptr->vardesc.reldum.relid)) ! 422: rptr->vardesc.reldum.relstat = desc.reldum.relstat; ! 423: else ! 424: { ! 425: /* relation not there, purge table */ ! 426: rngdel(rptr->vardesc.reldum.relid); ! 427: } ! 428: } ! 429: break; ! 430: ! 431: case mdVIEW: ! 432: if ((rptr->vardesc.reldum.relstat & S_VBASE) == 0) ! 433: { ! 434: fixorerr: ! 435: /* ! 436: ** if the relation doesn't exist then it is ! 437: ** a syserr, otherwise, copy the bits. ! 438: */ ! 439: if (!openr(&desc, -1, rptr->vardesc.reldum.relid)) ! 440: rptr->vardesc.reldum.relstat = desc.reldum.relstat; ! 441: else ! 442: { ! 443: /* not there, syserr */ ! 444: syserr("RNGFRESH: extra entry: %s", rptr->vardesc.reldum.relid); ! 445: } ! 446: } ! 447: break; ! 448: ! 449: case mdPROT: ! 450: if ((rptr->vardesc.reldum.relstat & S_PROTUPS) == 0) ! 451: goto fixorerr; ! 452: break; ! 453: ! 454: case mdINTEG: ! 455: if ((rptr->vardesc.reldum.relstat & S_INTEG) == 0) ! 456: goto fixorerr; ! 457: break; ! 458: ! 459: case mdMODIFY: ! 460: if ((rptr->vardesc.reldum.relstat & S_INDEX) != 0) ! 461: goto fixordel; ! 462: break; ! 463: ! 464: default: ! 465: return; /* command ok, dont waste time on rest of table */ ! 466: } ! 467: } ! 468: } ! 469: ! 470: printtable() ! 471: { ! 472: register PARRNG *rptr; ! 473: int slot[MAXRANGE]; ! 474: int i; ! 475: ! 476: printf("Range table:\n"); ! 477: ! 478: for (i = 0; i < MAXRANGE; i++) ! 479: slot[i] = 0; ! 480: ! 481: for (rptr = Rngfront; rptr != NULL; rptr = rptr->backpt) ! 482: { ! 483: i = rptr - (PARRNG *) Parrng; ! 484: slot[i] = 1; ! 485: printslot(i); ! 486: } ! 487: printf("\nEntries not in list:\n"); ! 488: for (i = 0; i < MAXRANGE; i++) ! 489: { ! 490: if (!slot[i]) ! 491: { ! 492: printslot(i); ! 493: } ! 494: } ! 495: } ! 496: ! 497: printslot(slot) ! 498: int slot; ! 499: { ! 500: register RANGEV *rptr; ! 501: register PARRNG *auxptr; ! 502: ! 503: rptr = &Qt.qt_rangev[slot]; ! 504: auxptr = &Parrng[slot]; ! 505: ! 506: printf("slot:\t%d\n{\trvar:\t%.12s,\trelnm:\t%.12s.\n", ! 507: slot, auxptr->vardesc.relvname, ! 508: auxptr->vardesc.reldum.relid); ! 509: printf("\tRELVUSED: %d, RELVSEND %d.\n", ! 510: auxptr->relvused, ! 511: rptr->rngvmark); ! 512: ! 513: ! 514: printf("\tratts: %d, attlist: %d.\n}\n", auxptr->vardesc.reldum.relatts, auxptr->attlist); ! 515: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.