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