1: # 2: # include "../ingres.h" 3: # include "../catalog.h" 4: # include "../tree.h" 5: # include "../symbol.h" 6: # include "../pipes.h" 7: 8: /* 9: ** READTREE.C -- query tree input procedures 10: ** 11: ** This file contains routines to read trees from pipes and 12: ** catalogs. 13: ** 14: ** Defines: 15: ** readqry 16: ** readsym 17: ** readtree 18: ** relntrrd 19: ** gettree 20: ** declare 21: ** clrrange 22: ** 23: ** Required By: 24: ** display.c 25: ** 26: ** Errors: 27: ** 5410 -- Query buffer full 28: ** 5411 -- Tree stack overflow 29: ** 30: ** History: 31: ** 8/23/78 (eric) -- release 6.2/0 32: ** 11/15/78 (marc) -- modified for DBU 33: ** 1/18/79 (rse) -- moved trbuild to iutil lib 34: */ 35: 36: 37: extern struct pipfrmt Pipe, Outpipe; 38: 39: /* if DBU's other than DISPLAY choose to use readtree.c, 40: * QBUFFULL should be passed to gettree() as a parameter 41: */ 42: 43: # define QBUFFULL 5410 44: # define STACKFULL 5411 45: # define QTREE struct querytree 46: 47: /* this structure should be identical to the one in pr_prot.c */ 48: struct rngtab 49: { 50: char relid [MAXNAME]; 51: char rowner [2]; 52: char rused; 53: }; 54: 55: extern struct rngtab Rangev []; 56: extern int Resultvar; 57: 58: 59: /* check out match for these two in decomp.h */ 60: # define QBUFSIZ 2000 /* query buffer */ 61: 62: 63: 64: char Qbuf[QBUFSIZ]; /* tree buffer space */ 65: int Qmode; /* type of query */ 66: 67: 68: extern struct descriptor Treedes; 69: 70: 71: /* 72: ** READQRY 73: ** 74: ** Reads in query symbols from input pipe into core 75: ** locations and sets up information needed for later 76: ** processing. 77: ** 78: ** Returns ptr to root of querytree 79: ** 80: ** Locbuf is a 'struct srcid' since that is the largest node of 81: ** a QMODE, SOURCEID, or RESULTVAR node. 82: ** 83: ** Trace Flags: 84: ** 12, 0 85: ** 86: */ 87: 88: QTREE * 89: readqry(rdfn) 90: int (*rdfn)(); /* tree read function */ 91: { 92: register struct symbol *s; 93: struct srcid locbuf; 94: register QTREE *rtval; 95: register char *p; 96: int berror(); 97: char *readtree(); 98: QTREE *trbuild(); 99: 100: /* initialize for new query block */ 101: initbuf(Qbuf, QBUFSIZ, QBUFFULL, berror); 102: clrrange(); 103: Resultvar = -1; 104: Qmode = -1; 105: 106: s = (struct symbol *) &locbuf; 107: 108: /* read symbols from input */ 109: for (;;) 110: { 111: readsym(s, rdfn); 112: # ifdef xZTR1 113: if (tTf(12, 0)) 114: printf("readqry symbol: type %o==%d\n", s->type); 115: # endif 116: switch (s->type) 117: { 118: case QMODE: 119: if (Qmode != -1) 120: syserr("readqry: two Qmodes"); 121: Qmode = s->value[0]; 122: break; 123: 124: case RESULTVAR: 125: if (Resultvar != -1) 126: syserr("readqry: two Resultvars"); 127: Resultvar = s->value[0]; 128: break; 129: 130: case SOURCEID: 131: declare(((struct srcid *)s)->srcvar, 132: ((struct srcid *)s)->srcname, 133: ((struct srcid *)s)->srcown); 134: break; 135: 136: case TREE: /* beginning of tree, no more other stuff */ 137: p = readtree(s, rdfn); 138: rtval = trbuild(p); 139: if (rtval == NULL) 140: berror(STACKFULL); 141: return (rtval); 142: 143: default: 144: syserr("readq: bad symbol %d", s->type); 145: } 146: } 147: } 148: 149: 150: /* 151: ** readsym 152: ** reads in one symbol from pipe into symbol struct. 153: */ 154: 155: 156: readsym(dest, rdfn) 157: char *dest; /* if non-zero, pts to allocated space */ 158: int (*rdfn)(); /* tree read function */ 159: { 160: register int len, t; 161: register struct symbol *p; 162: char *need(); 163: 164: /* check if enough space for type and len of sym */ 165: p = (struct symbol *) ((dest != NULL) ? dest : need(Qbuf, 2)); 166: if ((*rdfn)(p, 2) < 2) 167: goto err3; 168: len = p->len & I1MASK; 169: t = p->type; 170: if (len) 171: { 172: if (dest == NULL) 173: { 174: /* this will be contiguous with above need call */ 175: need(Qbuf, len); 176: } 177: if ((*rdfn)(p->value, len) < len) 178: goto err3; 179: } 180: 181: return; 182: 183: err3: 184: syserr("readsym: read"); 185: } 186: 187: 188: 189: /* 190: ** readtree 191: ** 192: ** reads in tree symbols into a buffer up to a root (end) symbol 193: ** 194: */ 195: 196: char *readtree(tresym, rdfn) 197: struct symbol *tresym; 198: int (*rdfn)(); 199: { 200: register QTREE *nod; 201: register char *rtval; 202: char *need(); 203: 204: rtval = need(Qbuf, 6); 205: bmove(tresym, &(((struct querytree *)rtval)->sym), 2); /* insert type and len of TREE node */ 206: for(;;) 207: { 208: /* space for left & right pointers */ 209: nod = (QTREE *) need(Qbuf, 4); 210: readsym(NULL, rdfn); 211: if (nod->sym.type == ROOT) 212: return (rtval); 213: } 214: } 215: 216: /* 217: ** RELNTRRD -- read tree from 'tree' relation 218: ** 219: ** This looks exactly like the 'pipetrrd' call, except that info 220: ** comes from the 'tree' catalog instead of from the pipe. It 221: ** must be initialized by calling it with a NULL pointer and 222: ** the segment name wanted as 'treeid'. 223: ** 224: ** Parameters: 225: ** ptr -- NULL -- "initialize". 226: ** else -- pointer to read area. 227: ** cnt -- count of number of bytes to read. 228: ** treeid -- if ptr == NULL, this is the tree id, 229: ** otherwise this parameter is not supplied. 230: ** 231: ** Returns: 232: ** count of actual number of bytes read. 233: ** 234: ** Side Effects: 235: ** activity in database. 236: ** static variables are adjusted correctly. Note that 237: ** this routine can be used on only one tree 238: ** at one time. 239: ** 240: ** Requires: 241: ** Treedes -- a relation descriptor for the "tree" catalog 242: ** open for read. 243: ** clearkeys, setkey, getequal 244: ** 245: ** Called By: 246: ** readsym (indirectly via pr_def, pr_prot) 247: ** 248: ** Diagnostics: 249: ** none 250: ** 251: ** Syserrs: 252: ** several access method error returns 253: ** on initialization if the specified treeid is not 254: ** in the catalog. 255: ** 256: ** History: 257: ** 2/23/78 (eric) -- specified (not written) 258: */ 259: 260: relntrrd(ptr, cnt, treerelid, treeowner, treetype, treeid) 261: char *ptr; 262: int cnt; 263: char *treerelid; 264: char *treeowner; 265: char treetype; 266: int treeid; 267: { 268: static struct tree trseg; 269: static char *trp; 270: static int seqno; 271: register char *p; 272: register int n; 273: register int i; 274: struct tree trkey; 275: struct tup_id tid; 276: 277: p = ptr; 278: n = cnt; 279: 280: if (p == NULL) 281: { 282: /* initialize -- make buffer appear empty */ 283: trp = &trseg.treetree[sizeof trseg.treetree]; 284: bmove(treerelid, trseg.treerelid, MAXNAME); 285: bmove(treeowner, trseg.treeowner, 2); 286: trseg.treetype = treetype; 287: trseg.treeid = treeid; 288: seqno = 0; 289: opencatalog("tree", 0); 290: return (0); 291: } 292: 293: /* fetch characters */ 294: while (n-- > 0) 295: { 296: /* check for segment empty */ 297: if (trp >= &trseg.treetree[sizeof trseg.treetree]) 298: { 299: /* then read new segment */ 300: clearkeys(&Treedes); 301: setkey(&Treedes, &trkey, &trseg.treerelid, TREERELID); 302: setkey(&Treedes, &trkey, &trseg.treeowner, TREEOWNER); 303: setkey(&Treedes, &trkey, &trseg.treetype, TREETYPE); 304: setkey(&Treedes, &trkey, &trseg.treeid, TREEID); 305: setkey(&Treedes, &trkey, &seqno, TREESEQ); 306: seqno++; 307: if ((i = getequal(&Treedes, &trkey, &trseg, &tid)) != 0) 308: syserr("relnrdtr: getequal %d", i); 309: trp = &trseg.treetree[0]; 310: } 311: 312: /* do actual character fetch */ 313: *p++ = *trp++; 314: } 315: 316: return (cnt); 317: } 318: 319: 320: 321: 322: /* 323: ** GETTREE -- get tree from 'tree' catalog 324: ** 325: ** This function, given an internal treeid, fetches and builds 326: ** that tree from the 'tree' catalog. 327: ** 328: ** Parameters: 329: ** treeid -- internal id of tree to fetch and build. 330: ** init -- passed to 'readqry' to tell whether or not 331: ** to initialize the query buffer. 332: ** 333: ** Returns: 334: ** Pointer to root of tree. 335: ** 336: ** Side Effects: 337: ** file activity. Space in Qbuf is used up. 338: ** 339: ** Requires: 340: ** relntrrd -- to initialize for readqry. 341: ** readqry -- to read and build the tree. 342: ** 343: ** Diagnostics: 344: ** none 345: ** 346: ** Syserrs: 347: ** none 348: ** 349: ** History: 350: ** 3/2/78 (eric) -- 'init' parameter added (defaulted to 351: ** false before). 352: ** 2/25/78 (eric) -- written 353: */ 354: 355: QTREE * 356: gettree(treerelid, treeowner, treetype, treeid) 357: char *treerelid; 358: char *treeowner; 359: char treetype; 360: int treeid; 361: { 362: register QTREE *t; 363: extern int relntrrd(); 364: register int i; 365: 366: /* initialize relntrrd() for this treeid */ 367: relntrrd(NULL, 0, treerelid, treeowner, treetype, treeid); 368: 369: /* read and build query tree */ 370: t = readqry(&relntrrd); 371: 372: return (t); 373: } 374: 375: 376: 377: /* 378: ** BERROR -- Buffer overflow routine. 379: ** 380: ** Called on Tree buffer overflow; returns via reset() 381: ** to DBU controller after sending back an error to process 1. 382: ** 383: ** Trace flag 12, 1 384: */ 385: 386: berror(err) 387: int err; 388: { 389: # ifdef xZTR1 390: if (tTf(12, 1)) 391: printf("berror(%d)\n", err); 392: # endif 393: error(err, 0); 394: reset(); 395: } 396: 397: /* 398: ** declare -- declare a range table entry 399: ** 400: ** Trace flag 12, 2 401: ** 402: */ 403: 404: declare(var, name, owner) 405: int var; 406: char *name; 407: char *owner; 408: { 409: register struct rngtab *r; 410: register v; 411: 412: v = var; 413: if (v > MAXNAME) 414: syserr("declare: bad var number %d", v); 415: 416: # ifdef xZTR1 417: if (tTf(12, 2)) 418: printf("declare(var=%d, name=\"%s\", owner=\"%s\")\n", 419: var, name, owner); 420: # endif 421: 422: r = &Rangev [v]; 423: r->rused++; 424: bmove(name, r->relid, sizeof r->relid); 425: bmove(owner, r->rowner, sizeof r->rowner); 426: } 427: 428: /* 429: ** CLRRANGE -- clear range table entries 430: ** 431: ** Trace flag 12, 3 432: */ 433: 434: clrrange() 435: { 436: register i; 437: register struct rngtab *r; 438: 439: # ifdef xZTR1 440: if (tTf(12, 3)) 441: printf("clrrange()\n"); 442: # endif 443: 444: r = Rangev; 445: for (i = 0; i <= MAXVAR; ) 446: r [i++].rused = 0; 447: }