1: # include "../ingres.h" 2: # include "../aux.h" 3: # include "../pipes.h" 4: # include "../tree.h" 5: # include "parser.h" 6: # include "../symbol.h" 7: 8: 9: /* 10: ** TREE 11: ** FUNCTION TO ADD NODE TO QUERY TREE 12: ** RETURN VALUE IS POINTER TO NODE JUST CREATED 13: */ 14: struct querytree * 15: tree(lptr, rptr, typ, len, valu1, attnum1) 16: struct querytree *lptr; 17: struct querytree *rptr; 18: char typ; 19: int len; 20: int valu1; 21: struct atstash *attnum1; 22: { 23: register struct atstash *attnum; 24: register struct querytree *tptr; 25: register int valu; 26: extern char *need(); 27: extern struct querytree *norm(); 28: # ifdef xPTM 29: if (tTf(76, 2)) 30: timtrace(5); 31: # endif 32: 33: attnum = attnum1; 34: valu = valu1; 35: tptr = (struct querytree *) need(Qbuf, len + 6); 36: tptr->left = lptr; 37: tptr->right = rptr; 38: tptr->sym.type = typ; 39: tptr->sym.len = len; 40: switch (typ) 41: { 42: case VAR: 43: ((struct qt_var *)tptr)->varno = valu & I1MASK; 44: ((struct qt_var *)tptr)->attno = attnum->atbid; 45: ((struct qt_var *)tptr)->frmt = attnum->atbfrmt; 46: ((struct qt_var *)tptr)->frml = attnum->atbfrml; 47: ((struct qt_var *)tptr)->valptr = 0; 48: break; 49: 50: case ROOT: 51: case AGHEAD: 52: case BYHEAD: 53: case AND: 54: case OR: 55: case QLEND: 56: break; 57: 58: case UOP: 59: case BOP: 60: ((struct qt_op *)tptr)->opno = valu; 61: format(tptr); 62: break; 63: 64: case COP: 65: if ((((struct qt_op *)tptr)->opno = getcop(valu)) == BADCOP) 66: /* bad const operator */ 67: yyerror(BADCONSTOP, valu, 0); 68: break; 69: 70: case AOP: 71: format(tptr->right); 72: ((struct qt_ag *)tptr)->agfrmt = Trfrmt; 73: ((struct qt_ag *)tptr)->agfrml = Trfrml; 74: 75: case RESDOM: 76: ((struct qt_res *)tptr)->resno = valu; 77: format(tptr); 78: ((struct qt_var *)tptr)->frmt = Trfrmt; 79: ((struct qt_var *)tptr)->frml = Trfrml; 80: break; 81: 82: default: 83: /* INT, FLOAT, CHAR */ 84: bmove(valu, tptr->sym.value, len & I1MASK); 85: break; 86: } 87: # ifdef xPTM 88: if (tTf(76, 2)) 89: timtrace(6); 90: # endif 91: return (tptr); 92: } 93: 94: /* 95: ** TREEPR 96: ** TREE PRINT ROUTINE 97: ** CREATES STRING WHERE EACH TARGET LIST ELEMENT AND QUALIFICATION 98: ** CLAUSE IS IN POLISH POSTFIX FORM BUT OVERALL LIST IS IN INFIX 99: ** FORM 100: */ 101: treepr(p1) 102: struct querytree *p1; 103: { 104: register struct querytree *p; 105: register int l; 106: extern struct pipfrmt Pipebuf; 107: 108: p = p1; 109: if (p->sym.type == ROOT || p->sym.type == BYHEAD) 110: { 111: writesym(TREE, 0, 0); 112: # ifdef xPTR2 113: tTfp(26, 8, "TREE node\n"); 114: # endif 115: } 116: if (p->left) 117: treepr(p->left); 118: if (p->right) 119: treepr(p->right); 120: 121: if (p->sym.type <= CHAR) 122: { 123: # ifdef xPTR2 124: if (tTf(26, 9)) 125: nodewr(p); 126: # endif 127: l = p->sym.len & I1MASK; 128: wrpipe(P_NORM, &Pipebuf, W_down, &(p->sym), l+2); 129: return; 130: } 131: syserr("Unidentified token in treeprint"); 132: } 133: 134: # ifdef xPTR1 135: /* 136: ** NODEWR 137: ** printf a tree node for debugging purposes 138: */ 139: nodewr(p1) 140: struct querytree *p1; 141: { 142: register struct querytree *p; 143: char str[257]; 144: register char *ptr; 145: char *bmove(); 146: 147: p = p1; 148: printf("addr=%l, l=%l, r=%l, typ=%d, len=%d:\n", p, p->left, p->right, p->sym.type, p->sym.len); 149: switch (p->sym.type) 150: { 151: case VAR: 152: printf("\t\tvarno=%d, attno=%d, frmt=%d, frml=%d\n", 153: ((struct qt_var *)p)->varno, 154: ((struct qt_var *)p)->attno, 155: ((struct qt_var *)p)->frmt, 156: ((struct qt_var *)p)->frml); 157: break; 158: 159: case AOP: 160: printf("\t\taop=%d, frmt=%d, frml=%d\n", 161: ((struct qt_res *)p)->resno, 162: ((struct qt_var *)p)->frmt, 163: ((struct qt_var *)p)->frml); 164: break; 165: 166: case RESDOM: 167: printf("\t\trsdmno=%d, frmt=%d, frml=%d\n", 168: ((struct qt_res *)p)->resno, 169: ((struct qt_var *)p)->frmt, 170: ((struct qt_var *)p)->frml); 171: break; 172: 173: case CHAR: 174: ptr = bmove(p->sym.value, str, p->sym.len & I1MASK); 175: *ptr = 0; 176: printf("\t\tstring=%s\n", str); 177: break; 178: 179: case INT: 180: switch(p->sym.len) 181: { 182: case 2: 183: printf("\t\tvalue=%d\n", i2deref(p->sym.value)); 184: break; 185: 186: 187: case 4: 188: printf("\t\tvalue=%s\n", locv(i4deref(p->sym.value))); 189: break; 190: } 191: break; 192: 193: case FLOAT: 194: switch(p->sym.len) 195: { 196: case 4: 197: printf("\t\tvalue=%f\n", f4deref(p->sym.value)); 198: break; 199: 200: case 8: 201: printf("\t\tvalue=%f\n", f8deref(p->sym.value)); 202: break; 203: } 204: break; 205: 206: case UOP: 207: case BOP: 208: case COP: 209: printf("\t\top=%d\n", ((struct qt_op *)p)->opno); 210: break; 211: } 212: } 213: # endif 214: 215: /* 216: ** WINDUP 217: ** assign resno's to resdoms of an agg fcn 218: */ 219: windup(ptr) 220: struct querytree *ptr; 221: { 222: register int tot; 223: register int kk; 224: register struct querytree *t; 225: 226: /* COUNT THE RESDOM'S OF THIS TARGET LIST */ 227: kk = 1; 228: for (t = ptr; t; t = t->left) 229: kk++; 230: tot = 1; 231: for (t=ptr; t;t = t->left) 232: ((struct qt_res *)t)->resno = kk - tot++; 233: } 234: 235: /* 236: ** ADDRESDOM - makes a new entry for the target list 237: ** 238: ** Trname must contain the name of the resdom to 239: ** use for the header, create and Rsdmno for append, replace 240: ** 241: ** the parameters are pointers to the subtrees to be 242: ** suspended from the node 243: */ 244: struct querytree * 245: addresdom(lptr, rptr) 246: struct querytree *lptr, *rptr; 247: { 248: extern struct querytree *tree(); 249: register struct querytree *rtval; 250: register struct atstash *aptr; 251: char buf[10]; /* buffer type and length in ascii for dbu */ 252: struct atstash *attlookup(); 253: 254: switch (Opflag) 255: { 256: case mdRETR: 257: case mdRET_UNI: 258: case mdVIEW: 259: Rsdmno++; 260: if (Rsdmno >= MAXDOM) 261: /* too many resdoms */ 262: yyerror(RESXTRA, 0); 263: rtval = tree(lptr, rptr, RESDOM, 4, Rsdmno); 264: if (!Equel || Resrng) 265: { 266: /* buffer info for header or CREATE */ 267: setp(Trname); 268: buf[0] = Trfrmt & I1MASK; 269: smove(iocv(Trfrml & I1MASK), &buf[1]); 270: setp(buf); 271: } 272: break; 273: 274: default: 275: /* 276: ** for append and replace, the result domain 277: ** number is determined by the location of 278: ** the attribute in the result relation 279: */ 280: if (sequal(Trname, "tid")) 281: /* attrib not found */ 282: yyerror(NOATTRIN, Trname, Resrng->relnm, 0); 283: # ifdef DISTRIB 284: if (sequal(Trname, "sid")) 285: /* attrib not found */ 286: yyerror(NOATTRIN, Trname, Resrng->relnm, 0); 287: # endif 288: aptr = attlookup(Resrng, Trname); 289: Rsdmno = aptr->atbid; 290: rtval = tree(lptr, rptr, RESDOM, 4, Rsdmno); 291: if (Opflag != mdPROT) /* INTEGRITY not possible here */ 292: attcheck(aptr); 293: break; 294: } 295: return (rtval); 296: } 297: 298: /* 299: ** GETCOP 300: ** routine to lookup 'string' in constant operators table 301: ** constant table is declared in tables.y 302: ** structure is defined in ../parser.h 303: */ 304: getcop(string) 305: char *string; 306: { 307: register struct constop *cpt; 308: register char *sptr; 309: extern struct constop Coptab[]; 310: 311: sptr = string; 312: for (cpt = Coptab; cpt->copname; cpt++) 313: if (sequal(sptr, cpt->copname)) 314: return (cpt->copnum); 315: return (BADCOP); 316: }