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