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