1: # 2: 3: /* 4: ** PR_TREE.C -- Query tree printing routines 5: ** 6: ** Defines: 7: ** pr_tree() -- print out query tree 8: ** pr_qual() -- print out qualofocation tree 9: ** pr_attname() -- print out attribute name of domain 10: ** 11: ** Required By: 12: ** display DBU --[display.c] 13: ** 14: ** Trace Flags: 15: ** 10 16: ** 17: ** History: 18: ** 11/15/78 -- (marc) written 19: */ 20: 21: 22: 23: # include "../symbol.h" 24: # include "../ingres.h" 25: # include "../tree.h" 26: # include "../aux.h" 27: 28: char *pr_trim(); 29: char *resultres(); 30: 31: struct tab 32: { 33: char t_opcode; 34: char *t_string; 35: }; 36: 37: 38: struct tab Uop_tab[] = 39: { 40: opPLUS, "+ ", 41: opMINUS, "- ", 42: opNOT, "not[ERROR]", 43: opATAN, "atan", 44: opCOS, "cos", 45: opGAMMA, "gamma", 46: opLOG, "log", 47: opASCII, "ascii", 48: opSIN, "sin", 49: opSQRT, "sqrt", 50: opABS, "abs", 51: opEXP, "exp", 52: opINT1, "int1", 53: opINT2, "int2", 54: opINT4, "int4", 55: opFLOAT4, "float4", 56: opFLOAT8, "float8", 57: }; 58: struct tab Bop_tab[] = 59: { 60: opADD, "+", 61: opSUB, "-", 62: opMUL, "*", 63: opDIV, "/", 64: opPOW, "**", 65: opEQ, "=", 66: opNE, "!=", 67: opLT, "<", 68: opLE, "<=", 69: opGT, ">", 70: opGE, ">=", 71: opMOD, "%", 72: }; 73: 74: struct tab Cop_tab[] = 75: { 76: opDBA, "dba", 77: opUSERCODE, "usercode", 78: opDATE, "date", 79: opTIME, "time", 80: }; 81: 82: struct tab Aop_tab[] = 83: { 84: opCOUNT, "count", 85: opCOUNTU, "countu", 86: opSUM, "sum", 87: opSUMU, "sumu", 88: opAVG, "avg", 89: opAVGU, "avgu", 90: opMIN, "min", 91: opMAX, "max", 92: opANY, "any", 93: }; 94: 95: /* 96: * This structure must be IDENTICAL to that in readtree.c 97: */ 98: struct rngtab 99: { 100: char relid[MAXNAME]; 101: char rowner[2]; 102: char rused; 103: }; 104: 105: extern struct rngtab Rangev[]; 106: int Resultvar; 107: struct descriptor Attdes; 108: int Tl_elm; 109: int Dom_num; 110: char *Resrel; 111: 112: 113: /* 114: ** tree: tl_clause ROOT tl_clause 115: ** 116: ** prints out a tree assuming a mdVIEW-like mode 117: ** 118: */ 119: 120: pr_tree(root) 121: struct querytree *root; 122: { 123: 124: # ifdef xZTR1 125: if (tTf(10, -1)) 126: printf("pr_tree: root %u Resultvar %d Resrel %s\n", 127: root, Resultvar, Resrel); 128: # endif 129: 130: printf("%s ", pr_trim(resultres(), 131: MAXNAME)); 132: 133: pr_dom_init(); 134: Tl_elm = 0; 135: 136: /* print target list */ 137: printf("(\n"); 138: pr_tl_clause(root->left, TRUE); 139: putchar(')'); 140: 141: /* print qualification */ 142: if (root->right->sym.type != QLEND) 143: { 144: printf("\nwhere "); 145: pr_qual(root->right); 146: } 147: putchar('\n'); 148: } 149: 150: /* 151: ** tl_clause: TREE 152: ** | tl_clause RESDOM expr 153: ** 154: ** target_flag = "in a target list (as opposed to in a by list)" 155: */ 156: 157: pr_tl_clause(t_l, target_flag) 158: struct querytree *t_l; 159: int target_flag; 160: { 161: register fl; 162: 163: fl = target_flag; 164: 165: # ifdef xZTR1 166: if (tTf(10, 1)) 167: printf("tl_clause target %d Tl_elm %d\n", fl, Tl_elm); 168: # endif 169: 170: if (t_l->sym.type != TREE) 171: { 172: pr_tl_clause(t_l->left, fl); 173: if (Tl_elm) 174: { 175: printf(", "); 176: if (fl) 177: putchar('\n'); 178: } 179: /* print out info on result variable */ 180: pr_resdom(t_l, fl); 181: pr_expr(t_l->right); 182: Tl_elm++; 183: } 184: } 185: 186: /* 187: ** print out info on a result attribute. 188: ** this will be done only if the RESDOM node 189: ** is inside a target_list and if the Resultvar >= 0. 190: ** Resultvar == -1 inside a target list indicates that this is 191: ** a retrieve to terminal. 192: */ 193: 194: pr_resdom(resdom, target_flag) 195: struct querytree *resdom; 196: int target_flag; 197: { 198: 199: # ifdef xZTR1 200: if (tTf(10, 2)) 201: printf("pr_resdom: target_flag %d\n", target_flag); 202: # endif 203: 204: if (target_flag) 205: { 206: printf("\t"); 207: pr_attname(resultres(), ((struct qt_res *)resdom)->resno); 208: printf(" = "); 209: } 210: } 211: 212: /* 213: ** give a relation name, and the attribute number of that 214: ** relation, looks in the attribute relation for the name of the 215: ** attribute. 216: */ 217: 218: 219: pr_attname(rel, attno) 220: char *rel; 221: int attno; 222: { 223: struct tup_id tid; 224: struct attribute key, tuple; 225: register i; 226: 227: # ifdef xZTR1 228: if (tTf(10, 3)) 229: printf("pr_attname: rel %s attno %d\n", 230: rel, attno); 231: # endif 232: 233: if (attno == 0) 234: { 235: printf("tid"); 236: return; 237: } 238: opencatalog("attribute", 0); 239: clearkeys(&Attdes); 240: setkey(&Attdes, &key, rel, ATTRELID); 241: setkey(&Attdes, &key, &attno, ATTID); 242: i = getequal(&Attdes, &key, &tuple, &tid); 243: if (i) 244: syserr("pr_attname: bad getequal %d rel %s attno %d", 245: i, rel, attno); 246: printf("%s", pr_trim(tuple.attname, MAXNAME)); 247: } 248: 249: /* 250: ** expr: VAR 251: ** | expr BOP expr 252: ** | expr UOP 253: ** | AOP AGHEAD qual 254: ** \ 255: ** expr 256: ** | BYHEAD AGHEAD qual 257: ** / \ 258: ** tl_clause AOP 259: ** \ 260: ** expr 261: ** | INT 262: ** | FLOAT 263: ** | CHAR 264: ** | COP 265: ** 266: */ 267: 268: pr_expr(ex) 269: struct querytree *ex; 270: { 271: register op; 272: register tl_elm; 273: register struct querytree *e; 274: 275: e = ex; 276: switch (e->sym.type) 277: { 278: case VAR: 279: pr_var(e); 280: break; 281: 282: case BOP: 283: if (((struct qt_op *)e)->opno == opCONCAT) 284: { 285: printf("concat("); 286: pr_expr(e->left); 287: printf(", "); 288: pr_expr(e->right); 289: putchar(')'); 290: } 291: else 292: { 293: putchar('('); 294: pr_expr(e->left); 295: pr_op(BOP, ((struct qt_op *)e)->opno); 296: pr_expr(e->right); 297: putchar(')'); 298: } 299: break; 300: 301: case UOP: 302: if ((op = ((struct qt_op *)e)->opno) == opMINUS || op == opPLUS || op == opNOT) 303: { 304: pr_op(UOP, ((struct qt_op *)e)->opno); 305: pr_expr(e->left); 306: putchar(')'); 307: } 308: else 309: { 310: /* functional operators */ 311: pr_op(UOP, ((struct qt_op *)e)->opno); 312: pr_expr(e->left); 313: putchar(')'); 314: } 315: break; 316: 317: case AGHEAD: 318: if (e->left->sym.type == AOP) 319: { 320: /* simple aggregate */ 321: pr_op(AOP, ((struct qt_op *)e->left)->opno); 322: pr_expr(e->left->right); 323: if (e->right->sym.type != QLEND) 324: { 325: printf("\where "); 326: pr_qual(e->right); 327: } 328: putchar(')'); 329: } 330: else 331: { 332: /* aggregate function */ 333: pr_op(AOP, ((struct qt_op *)e->left->right)->opno); 334: pr_expr(e->left->right->right); 335: printf(" by "); 336: /* avoid counting target list elements 337: * in determining wether to put out 338: * commas after list's elements 339: */ 340: tl_elm = Tl_elm; 341: Tl_elm = 0; 342: pr_tl_clause(e->left->left, FALSE); 343: Tl_elm = tl_elm; 344: if (e->right->sym.type != QLEND) 345: { 346: printf("\n\t\twhere "); 347: pr_qual(e->right); 348: } 349: putchar(')'); 350: } 351: break; 352: 353: case INT: 354: case FLOAT: 355: case CHAR: 356: pr_const(e); 357: break; 358: 359: case COP: 360: pr_op(COP, ((struct qt_op *)e)->opno); 361: break; 362: 363: default: 364: syserr("expr %d", e->sym.type); 365: } 366: } 367: pr_const(ct) 368: struct querytree *ct; 369: { 370: register struct querytree *c; 371: register char *cp; 372: register i; 373: char ch; 374: double d; 375: 376: c = ct; 377: switch (c->sym.type) 378: { 379: case INT: 380: if (c->sym.len == 1) 381: printf("%d", i1deref(c->sym.value)); 382: else if (c->sym.len == 2) 383: printf("%d", i2deref(c->sym.value)); 384: else /* i4 */ 385: printf("%d", i4deref(c->sym.value)); 386: break; 387: 388: case FLOAT: 389: if (c->sym.len == 4) 390: d = f4deref(c->sym.value); 391: else 392: d = f8deref(c->sym.value); 393: printf("%-10.3f", f8deref(c->sym.value)); 394: break; 395: 396: case CHAR: 397: printf("\""); 398: cp = (char *) c->sym.value; 399: for (i = c->sym.len; i--; cp++) 400: { 401: if (any(*cp, "\"\\[]*?") == TRUE) 402: putchar('\\'); 403: 404: if (*cp >= ' ') 405: { 406: putchar(*cp); 407: continue; 408: } 409: /* perform pattern matching character replacement */ 410: switch (*cp) 411: { 412: case PAT_ANY: 413: ch = '*'; 414: break; 415: 416: case PAT_ONE: 417: ch = '?'; 418: break; 419: 420: case PAT_LBRAC: 421: ch = '['; 422: break; 423: 424: case PAT_RBRAC: 425: ch = ']'; 426: break; 427: 428: default: 429: ch = *cp; 430: } 431: putchar(ch); 432: } 433: putchar('"'); 434: break; 435: 436: default: 437: syserr("bad constant %d", c->sym.type); 438: } 439: } 440: 441: 442: /* 443: ** pr_op: print out operator of a certain type 444: */ 445: 446: pr_op(op_type, op_code) 447: int op_type, op_code; 448: { 449: register struct tab *s; 450: register int opc; 451: 452: opc = op_code; 453: switch (op_type) 454: { 455: case UOP: 456: s = &Uop_tab[opc]; 457: printf("%s(", s->t_string); 458: break; 459: 460: case BOP: 461: s = &Bop_tab[opc]; 462: printf(" %s ", s->t_string); 463: break; 464: 465: case AOP: 466: s = &Aop_tab[opc]; 467: printf("%s(", s->t_string); 468: break; 469: 470: case COP: 471: s = &Cop_tab[opc]; 472: printf("%s", s->t_string); 473: break; 474: } 475: if (opc != s->t_opcode) 476: syserr("pr_op: op in wrong place type %d, code %d", op_type, 477: s->t_opcode); 478: } 479: 480: /* 481: ** print a VAR node: that is, a var.attno pair 482: ** at present the var part is the relation name over which var 483: ** ranges. 484: */ 485: 486: pr_var(var) 487: struct querytree *var; 488: { 489: register struct querytree *v; 490: 491: # ifdef xZTR1 492: if (tTf(10, 4)) 493: printf("pr_var(var=%d)\n", var); 494: # endif 495: v = var; 496: pr_rv(((struct qt_var *)v)->varno); 497: putchar('.'); 498: pr_attname(Rangev[((struct qt_var *)v)->varno].relid, ((struct qt_var *)v)->attno); 499: } 500: 501: /* 502: ** qual: QLEND 503: ** | q_clause AND qual 504: ** 505: */ 506: 507: pr_qual(ql) 508: struct querytree *ql; 509: { 510: register struct querytree *q; 511: 512: 513: q = ql; 514: pr_q_clause(q->left); 515: if (q->right->sym.type != QLEND) 516: { 517: printf(" and "); 518: pr_qual(q->right); 519: } 520: } 521: 522: /* 523: ** q_clause: q_clause OR q_clause 524: ** | expr 525: */ 526: 527: pr_q_clause(qc) 528: struct querytree *qc; 529: { 530: register struct querytree *q; 531: 532: 533: q = qc; 534: if (q->sym.type == OR) 535: { 536: pr_q_clause(q->left); 537: printf(" or "); 538: pr_q_clause(q->right); 539: } 540: else 541: pr_expr(q); 542: } 543: 544: 545: char *pr_trim(string, len) 546: char *string; 547: int len; 548: { 549: static char buf[30]; 550: register l; 551: register char *s; 552: 553: s = string; 554: l = len; 555: bmove(s, buf, l); 556: for (s = buf; l && *s != ' ' && *s; --l) 557: s++; 558: *s = '\0'; 559: return (buf); 560: } 561: 562: pr_dom_init() 563: { 564: Dom_num = 0; 565: } 566: 567: pr_ddom() 568: { 569: printf("d%d = ", Dom_num++); 570: } 571: 572: pr_range() 573: { 574: register int i; 575: 576: for (i = 0; i <= MAXVAR; i++) 577: { 578: if (Rangev[i].rused) 579: { 580: printf("range of "); 581: pr_rv(i); 582: printf(" is %s\n", 583: pr_trim(Rangev[i].relid, MAXNAME)); 584: } 585: } 586: } 587: 588: pr_rv(re) 589: int re; 590: { 591: register i, j; 592: register char ch; 593: 594: i = re; 595: ch = Rangev[i].relid[0]; 596: 597: # ifdef xZTR1 598: if (tTf(10, 6)) 599: printf("pr_rv(%d) ch '%c'\n", i, ch); 600: # endif 601: 602: for (j = 0; j <= MAXVAR; j++) 603: { 604: if (!Rangev[j].rused) 605: continue; 606: if (ch == Rangev[j].relid[0]) 607: break; 608: } 609: if (j < i) 610: printf("rv%d", i); 611: else 612: printf("%c", ch); 613: } 614: 615: 616: char *resultres() 617: { 618: extern char *Resrel; 619: 620: # ifdef xZTR1 621: if (tTf(10, 5)) 622: printf("resultres : Resultvar %d, Resrel %s\n", 623: Resultvar, Resrel); 624: # endif 625: if (Resultvar > 0) 626: return (Rangev[Resultvar].relid); 627: if (Resrel == 0) 628: syserr("resultres: Resrel == 0"); 629: 630: return (Resrel); 631: } 632: 633: any(ch, st) 634: char ch; 635: char *st; 636: { 637: register char *s; 638: register char c; 639: 640: for (s = st, c = ch; *s; ) 641: if (*s++ == c) 642: return (TRUE); 643: return (FALSE); 644: }