1: # include "../ingres.h" 2: # include "../catalog.h" 3: # include "../tree.h" 4: # include "../symbol.h" 5: # include "../pipes.h" 6: # include "qrymod.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: ** pipetrrd 19: ** relntrrd 20: ** gettree 21: ** Qmode 22: ** Resultvar 23: ** 24: ** Requires: 25: ** prtree.c 26: ** 27: ** Required By: 28: ** main.c 29: ** view.c 30: ** protect.c 31: ** integ.c 32: ** 33: ** Trace Flags: 34: ** 70 35: ** 36: ** History: 37: ** 2/14/79 -- version 6.2/0 release. 38: */ 39: 40: 41: extern struct pipfrmt Pipe, Outpipe; 42: 43: int Qmode; /* Query mode */ 44: int Resultvar; /* Result variable number */ 45: /* 46: ** READQRY 47: ** 48: ** Reads in query symbols from input pipe into core 49: ** locations and sets up information needed for later 50: ** processing. 51: ** 52: ** Returns ptr to root of querytree 53: ** 54: ** Locbuf is a 'struct srcid' since that is the largest node of 55: ** a QMODE, SOURCEID, or RESULTVAR node. 56: */ 57: 58: QTREE * 59: readqry(rdfn, initialize) 60: int (*rdfn)(); /* tree read function */ 61: int initialize; /* if set, initialize Qbuf */ 62: { 63: register struct symbol *s; 64: struct srcid locbuf; 65: register QTREE *rtval; 66: register char *p; 67: extern xerror(); 68: char *readtree(); 69: QTREE *trbuild(); 70: 71: # ifdef xQTR1 72: tTfp(70, 0, "READQRY:\n"); 73: # endif 74: 75: if (initialize) 76: { 77: /* initialize for new query block */ 78: initbuf(Qbuf, QBUFSIZ, QBUFFULL, &xerror); 79: clrrange(TRUE); 80: Resultvar = -1; 81: Qmode = -1; 82: } 83: else 84: clrrange(FALSE); 85: 86: s = (struct symbol *) &locbuf; 87: 88: /* read symbols from input */ 89: for (;;) 90: { 91: readsym(s, rdfn); 92: # ifdef xQTR1 93: if (tTf(70, 1)) 94: { 95: printf("%d, %d, %d/", s->type, s->len, s->value[0] & 0377); 96: if (s->type == SOURCEID) 97: printf("%.12s", ((struct srcid *)s)->srcname); 98: printf("\n"); 99: } 100: # endif 101: switch (s->type) 102: { 103: case QMODE: 104: if (Qmode != -1) 105: syserr("readqry: two Qmodes"); 106: Qmode = s->value[0]; 107: break; 108: 109: case RESULTVAR: 110: if (Resultvar != -1) 111: syserr("readqry: two Resultvars"); 112: Resultvar = s->value[0]; 113: break; 114: 115: case SOURCEID: 116: declare(((struct srcid *)s)->srcvar, 117: ((struct srcid *)s)->srcname, 118: ((struct srcid *)s)->srcown, 119: ((struct srcid *)s)->srcstat); 120: break; 121: 122: case TREE: /* beginning of tree, no more other stuff */ 123: p = readtree(s, rdfn); 124: rtval = trbuild(p); 125: if (rtval == NULL) 126: ferror(STACKFULL, -1, -1, 0); 127: return (rtval); 128: 129: default: 130: syserr("readq: bad symbol %d", s->type); 131: } 132: } 133: } 134: /* 135: ** readsym 136: ** reads in one symbol from pipe into symbol struct. 137: */ 138: readsym(dest, rdfn) 139: char *dest; /* if non-zero, pts to allocated space */ 140: int (*rdfn)(); /* tree read function */ 141: { 142: register int len, t; 143: register struct symbol *p; 144: char *need(); 145: 146: /* check if enough space for type and len of sym */ 147: p = (struct symbol *) ((dest != NULL) ? dest : need(Qbuf, 2)); 148: if ((*rdfn)(p, 2) < 2) 149: goto err3; 150: len = p->len & I1MASK; 151: t = p->type; 152: if (len) 153: { 154: if (dest == NULL) 155: { 156: /* this will be contiguous with above need call */ 157: need(Qbuf, len); 158: } 159: if ((*rdfn)(p->value, len) < len) 160: goto err3; 161: } 162: 163: return; 164: 165: err3: 166: syserr("readsym: read"); 167: } 168: /* 169: ** readtree 170: ** 171: ** reads in tree symbols into a buffer up to a root (end) symbol 172: ** 173: */ 174: 175: char *readtree(tresym, rdfn) 176: struct symbol *tresym; 177: int (*rdfn)(); 178: { 179: register QTREE *nod; 180: register char *rtval; 181: char *need(); 182: 183: rtval = need(Qbuf, 6); 184: bmove(tresym, &(((struct querytree *)rtval)->sym), 2); /* insert type and len of TREE node */ 185: for(;;) 186: { 187: /* space for left & right pointers */ 188: nod = (QTREE *) need(Qbuf, 4); 189: readsym(NULL, rdfn); 190: # ifdef xQTR1 191: if (tTf(70, 2)) 192: nodepr(nod, TRUE); 193: # endif 194: if (nod->sym.type == ROOT) 195: return (rtval); 196: } 197: } 198: /* 199: ** PIPETRRD -- read tree from R_up pipe 200: ** 201: ** This routine looks like a rdpipe with only the last two 202: ** parameters. 203: ** 204: ** Parameters: 205: ** ptr -- pointer to data area 206: ** cnt -- byte count 207: ** 208: ** Returns: 209: ** actual number of bytes read 210: ** 211: ** Side Effects: 212: ** as with rdpipe() 213: ** 214: ** Requires: 215: ** rdpipe() 216: ** 217: ** Called By: 218: ** readsym (indirectly via main) 219: ** 220: ** Diagnostics: 221: ** none 222: ** 223: ** Syserrs: 224: ** none 225: */ 226: 227: pipetrrd(ptr, cnt) 228: char *ptr; 229: int cnt; 230: { 231: return (rdpipe(P_NORM, &Pipe, R_up, ptr, cnt)); 232: } 233: /* 234: ** RELNTRRD -- read tree from 'tree' relation 235: ** 236: ** This looks exactly like the 'pipetrrd' call, except that info 237: ** comes from the 'tree' catalog instead of from the pipe. It 238: ** must be initialized by calling it with a NULL pointer and 239: ** the segment name wanted as 'treeid'. 240: ** 241: ** Parameters: 242: ** ptr -- NULL -- "initialize". 243: ** else -- pointer to read area. 244: ** cnt -- count of number of bytes to read. 245: ** treeid -- if ptr == NULL, this is the tree id, 246: ** otherwise this parameter is not supplied. 247: ** 248: ** Returns: 249: ** count of actual number of bytes read. 250: ** 251: ** Side Effects: 252: ** activity in database. 253: ** static variables are adjusted correctly. Note that 254: ** this routine can be used on only one tree 255: ** at one time. 256: ** 257: ** Requires: 258: ** Treedes -- a relation descriptor for the "tree" catalog 259: ** open for read. 260: ** clearkeys, setkey, getequal 261: ** 262: ** Called By: 263: ** readsym (indirectly via main) 264: ** 265: ** Diagnostics: 266: ** none 267: ** 268: ** Syserrs: 269: ** several access method error returns 270: ** on initialization if the specified treeid is not 271: ** in the catalog. 272: */ 273: 274: relntrrd(ptr, cnt, treerelid, treeowner, treetype, treeid) 275: char *ptr; 276: int cnt; 277: char *treerelid; 278: char *treeowner; 279: char treetype; 280: int treeid; 281: { 282: static struct tree trseg; 283: static char *trp; 284: static int seqno; 285: register char *p; 286: register int n; 287: register int i; 288: struct tree trkey; 289: struct tup_id tid; 290: 291: p = ptr; 292: n = cnt; 293: 294: if (p == NULL) 295: { 296: /* initialize -- make buffer appear empty */ 297: trp = &trseg.treetree[sizeof trseg.treetree]; 298: bmove(treerelid, trseg.treerelid, MAXNAME); 299: bmove(treeowner, trseg.treeowner, 2); 300: trseg.treetype = treetype; 301: trseg.treeid = treeid; 302: seqno = 0; 303: opencatalog("tree", 0); 304: 305: # ifdef xQTR2 306: if (tTf(70, 6)) 307: printf("relntrrd: n=%.12s o=%.2s t=%d i=%d\n", 308: treerelid, treeowner, treetype, treeid); 309: # endif 310: 311: return (0); 312: } 313: 314: /* fetch characters */ 315: while (n-- > 0) 316: { 317: /* check for segment empty */ 318: if (trp >= &trseg.treetree[sizeof trseg.treetree]) 319: { 320: /* then read new segment */ 321: clearkeys(&Treedes); 322: setkey(&Treedes, &trkey, &trseg.treerelid, TREERELID); 323: setkey(&Treedes, &trkey, &trseg.treeowner, TREEOWNER); 324: setkey(&Treedes, &trkey, &trseg.treetype, TREETYPE); 325: setkey(&Treedes, &trkey, &trseg.treeid, TREEID); 326: setkey(&Treedes, &trkey, &seqno, TREESEQ); 327: seqno++; 328: if ((i = getequal(&Treedes, &trkey, &trseg, &tid)) != 0) 329: syserr("relnrdtr: getequal %d", i); 330: trp = &trseg.treetree[0]; 331: } 332: 333: /* do actual character fetch */ 334: *p++ = *trp++; 335: } 336: 337: return (cnt); 338: } 339: /* 340: ** GETTREE -- get tree from 'tree' catalog 341: ** 342: ** This function, given an internal treeid, fetches and builds 343: ** that tree from the 'tree' catalog. There is nothing exciting 344: ** except the mapping of variables, done by mapvars(). 345: ** 346: ** Parameters: 347: ** treeid -- internal id of tree to fetch and build. 348: ** init -- passed to 'readqry' to tell whether or not 349: ** to initialize the query buffer. 350: ** 351: ** Returns: 352: ** Pointer to root of tree. 353: ** 354: ** Side Effects: 355: ** file activity. Space in Qbuf is used up. 356: ** 357: ** Requires: 358: ** relntrrd -- to initialize for readqry. 359: ** readqry -- to read and build the tree. 360: ** mapvars -- to change the varno's in the tree after 361: ** built to avoid conflicts with variables in 362: ** the original query. 363: ** 364: ** Called By: 365: ** view 366: ** integrity (???) 367: ** protect (???) 368: ** d_view 369: ** 370: ** Diagnostics: 371: ** none 372: ** 373: ** Syserrs: 374: ** none 375: */ 376: 377: QTREE * 378: gettree(treerelid, treeowner, treetype, treeid, init) 379: char *treerelid; 380: char *treeowner; 381: char treetype; 382: int treeid; 383: int init; 384: { 385: register QTREE *t; 386: extern int relntrrd(); 387: register int i; 388: 389: /* initialize relntrrd() for this treeid */ 390: relntrrd(NULL, 0, treerelid, treeowner, treetype, treeid); 391: 392: /* read and build query tree */ 393: t = readqry(&relntrrd, init); 394: 395: /* remap varno's to be unique */ 396: if (!init) 397: mapvars(t); 398: 399: return (t); 400: }