|
|
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 7.1 2/5/81) ! 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: register i; ! 204: ! 205: # ifdef xZTR1 ! 206: if (tTf(52, 3)) ! 207: printf("pr_attname: rel %s attno %d\n", ! 208: rel, attno); ! 209: # endif ! 210: ! 211: if (attno == 0) ! 212: { ! 213: printf("tid"); ! 214: return; ! 215: } ! 216: opencatalog("attribute", 0); ! 217: clearkeys(&Attdes); ! 218: setkey(&Attdes, &key, rel, ATTRELID); ! 219: setkey(&Attdes, &key, &attno, ATTID); ! 220: i = getequal(&Attdes, &key, &tuple, &tid); ! 221: if (i) ! 222: syserr("pr_attname: bad getequal %d rel %s attno %d", ! 223: i, rel, attno); ! 224: printf("%s", pr_trim(tuple.attname, MAXNAME)); ! 225: } ! 226: /* ! 227: ** PR_EXPR ! 228: ** ! 229: ** expr: VAR ! 230: ** | expr BOP expr ! 231: ** | expr UOP ! 232: ** | AOP AGHEAD qual ! 233: ** \ ! 234: ** expr ! 235: ** | BYHEAD AGHEAD qual ! 236: ** / \ ! 237: ** tl_clause AOP ! 238: ** \ ! 239: ** expr ! 240: ** | INT ! 241: ** | FLOAT ! 242: ** | CHAR ! 243: */ ! 244: ! 245: pr_expr(e) ! 246: register QTREE *e; ! 247: { ! 248: register int op; ! 249: register int tl_elm; ! 250: ! 251: switch (e->sym.type) ! 252: { ! 253: case VAR: ! 254: pr_var(e); ! 255: break; ! 256: ! 257: case BOP: ! 258: if (e->sym.value.sym_op.opno == opCONCAT) ! 259: { ! 260: printf("concat("); ! 261: pr_expr(e->left); ! 262: printf(", "); ! 263: pr_expr(e->right); ! 264: putchar(')'); ! 265: } ! 266: else ! 267: { ! 268: putchar('('); ! 269: pr_expr(e->left); ! 270: pr_op(BOP, e->sym.value.sym_op.opno); ! 271: pr_expr(e->right); ! 272: putchar(')'); ! 273: } ! 274: break; ! 275: ! 276: case UOP: ! 277: if ((op = e->sym.value.sym_op.opno) == opMINUS || op == opPLUS || op == opNOT) ! 278: { ! 279: pr_op(UOP, e->sym.value.sym_op.opno); ! 280: pr_expr(e->left); ! 281: putchar(')'); ! 282: } ! 283: else ! 284: { ! 285: /* functional operators */ ! 286: pr_op(UOP, e->sym.value.sym_op.opno); ! 287: pr_expr(e->left); ! 288: putchar(')'); ! 289: } ! 290: break; ! 291: ! 292: case AGHEAD: ! 293: if (e->left->sym.type == AOP) ! 294: { ! 295: /* simple aggregate */ ! 296: pr_op(AOP, e->left->sym.value.sym_op.opno); ! 297: pr_expr(e->left->right); ! 298: if (e->right->sym.type != QLEND) ! 299: { ! 300: printf("\where "); ! 301: pr_qual(e->right); ! 302: } ! 303: putchar(')'); ! 304: } ! 305: else ! 306: { ! 307: /* aggregate function */ ! 308: pr_op(AOP, e->left->right->sym.value.sym_op.opno); ! 309: pr_expr(e->left->right->right); ! 310: printf(" by "); ! 311: /* avoid counting target list elements ! 312: * in determining wether to put out ! 313: * commas after list's elements ! 314: */ ! 315: tl_elm = Tl_elm; ! 316: Tl_elm = 0; ! 317: pr_tl_clause(e->left->left, FALSE); ! 318: Tl_elm = tl_elm; ! 319: if (e->right->sym.type != QLEND) ! 320: { ! 321: printf("\n\t\twhere "); ! 322: pr_qual(e->right); ! 323: } ! 324: putchar(')'); ! 325: } ! 326: break; ! 327: ! 328: case INT: ! 329: case FLOAT: ! 330: case CHAR: ! 331: pr_const(e); ! 332: break; ! 333: ! 334: default: ! 335: syserr("expr %d", e->sym.type); ! 336: } ! 337: } ! 338: /* ! 339: ** PR_CONST -- print constant ! 340: */ ! 341: ! 342: pr_const(c) ! 343: register QTREE *c; ! 344: { ! 345: register char *cp; ! 346: register int i; ! 347: char ch; ! 348: double d; ! 349: ! 350: switch (c->sym.type) ! 351: { ! 352: case INT: ! 353: if (c->sym.len == 1) ! 354: printf("%d", c->sym.value.sym_data.i1type); ! 355: else if (c->sym.len == 2) ! 356: printf("%d", c->sym.value.sym_data.i2type); ! 357: else /* i4 */ ! 358: printf("%D", c->sym.value.sym_data.i4type); ! 359: break; ! 360: ! 361: case FLOAT: ! 362: if (c->sym.len == 4) ! 363: d = c->sym.value.sym_data.f4type; ! 364: else ! 365: d = c->sym.value.sym_data.f8type; ! 366: printf("%-10.3f", c->sym.value.sym_data.f8type); ! 367: break; ! 368: ! 369: case CHAR: ! 370: printf("\""); ! 371: cp = c->sym.value.sym_data.c0type; ! 372: for (i = c->sym.len; i--; cp++) ! 373: { ! 374: if (any(*cp, "\"\\[]*?") == TRUE) ! 375: putchar('\\'); ! 376: ! 377: if (*cp >= ' ') ! 378: { ! 379: putchar(*cp); ! 380: continue; ! 381: } ! 382: /* perform pattern matching character replacement */ ! 383: switch (*cp) ! 384: { ! 385: case PAT_ANY: ! 386: ch = '*'; ! 387: break; ! 388: ! 389: case PAT_ONE: ! 390: ch = '?'; ! 391: break; ! 392: ! 393: case PAT_LBRAC: ! 394: ch = '['; ! 395: break; ! 396: ! 397: case PAT_RBRAC: ! 398: ch = ']'; ! 399: break; ! 400: ! 401: default: ! 402: ch = *cp; ! 403: } ! 404: putchar(ch); ! 405: } ! 406: putchar('"'); ! 407: break; ! 408: ! 409: default: ! 410: syserr("bad constant %d", c->sym.type); ! 411: } ! 412: } ! 413: /* ! 414: ** PR_OP -- print out operator of a certain type ! 415: */ ! 416: ! 417: pr_op(op_type, op_code) ! 418: int op_type; ! 419: register int op_code; ! 420: { ! 421: register struct tab *s; ! 422: ! 423: switch (op_type) ! 424: { ! 425: case UOP: ! 426: s = &Uop_tab[op_code]; ! 427: printf("%s(", s->t_string); ! 428: break; ! 429: ! 430: case BOP: ! 431: s = &Bop_tab[op_code]; ! 432: printf(" %s ", s->t_string); ! 433: break; ! 434: ! 435: case AOP: ! 436: s = &Aop_tab[op_code]; ! 437: printf("%s(", s->t_string); ! 438: break; ! 439: ! 440: case COP: ! 441: s = &Cop_tab[op_code]; ! 442: printf("%s", s->t_string); ! 443: break; ! 444: } ! 445: if (op_code != s->t_opcode) ! 446: syserr("pr_op: op in wrong place type %d, code %d", op_type, ! 447: s->t_opcode); ! 448: } ! 449: /* ! 450: ** PR_VAR ! 451: ** ! 452: ** print a VAR node: that is, a var.attno pair ! 453: ** at present the var part is the relation name over which var ! 454: ** ranges. ! 455: */ ! 456: ! 457: pr_var(var) ! 458: QTREE *var; ! 459: { ! 460: ! 461: # ifdef xZTR1 ! 462: if (tTf(52, 4)) ! 463: printf("pr_var(var=%d)\n", var); ! 464: # endif ! 465: pr_rv(var->sym.value.sym_var.varno); ! 466: putchar('.'); ! 467: pr_attname(Qt.qt_rangev[var->sym.value.sym_var.varno].rngvdesc->reldum.relid, var->sym.value.sym_var.attno); ! 468: } ! 469: /* ! 470: ** PR_QUAL ! 471: ** ! 472: ** qual: QLEND ! 473: ** | q_clause AND qual ! 474: ** ! 475: */ ! 476: ! 477: pr_qual(q) ! 478: register QTREE *q; ! 479: { ! 480: ! 481: pr_q_clause(q->left); ! 482: if (q->right->sym.type != QLEND) ! 483: { ! 484: printf(" and "); ! 485: pr_qual(q->right); ! 486: } ! 487: } ! 488: /* ! 489: ** PR_Q_CLAUSE ! 490: ** ! 491: ** q_clause: q_clause OR q_clause ! 492: ** | expr ! 493: */ ! 494: ! 495: pr_q_clause(q) ! 496: QTREE *q; ! 497: { ! 498: ! 499: if (q->sym.type == OR) ! 500: { ! 501: pr_q_clause(q->left); ! 502: printf(" or "); ! 503: pr_q_clause(q->right); ! 504: } ! 505: else ! 506: pr_expr(q); ! 507: } ! 508: /* ! 509: ** PR_TRIM ! 510: */ ! 511: ! 512: char * ! 513: pr_trim(s, l) ! 514: register char *s; ! 515: register int l; ! 516: { ! 517: static char buf[30]; ! 518: ! 519: bmove(s, buf, l); ! 520: for (s = buf; l && *s != ' ' && *s; --l) ! 521: s++; ! 522: *s = '\0'; ! 523: return (buf); ! 524: } ! 525: /* ! 526: ** PR_DOM_INIT ! 527: */ ! 528: ! 529: pr_dom_init() ! 530: { ! 531: Dom_num = 0; ! 532: } ! 533: ! 534: pr_ddom() ! 535: { ! 536: printf("d%d = ", Dom_num++); ! 537: } ! 538: /* ! 539: ** PR_RANGE -- print the range table ! 540: */ ! 541: ! 542: pr_range() ! 543: { ! 544: register int i; ! 545: ! 546: for (i = 0; i <= MAXVAR; i++) ! 547: { ! 548: if (Qt.qt_rangev[i].rngvdesc != NULL) ! 549: { ! 550: printf("range of "); ! 551: pr_rv(i); ! 552: printf(" is %s\n", ! 553: pr_trim(Qt.qt_rangev[i].rngvdesc->reldum.relid, MAXNAME)); ! 554: } ! 555: } ! 556: } ! 557: /* ! 558: ** PR_RV -- print range variable ! 559: */ ! 560: ! 561: pr_rv(re) ! 562: register int re; ! 563: { ! 564: register int j; ! 565: register char ch; ! 566: ! 567: ch = Qt.qt_rangev[re].rngvdesc->reldum.relid[0]; ! 568: ! 569: # ifdef xZTR1 ! 570: if (tTf(52, 6)) ! 571: printf("pr_rv(%d) ch '%c'\n", re, ch); ! 572: # endif ! 573: ! 574: for (j = 0; j <= MAXVAR; j++) ! 575: { ! 576: if (Qt.qt_rangev[j].rngvdesc == NULL) ! 577: continue; ! 578: if (ch == Qt.qt_rangev[j].rngvdesc->reldum.relid[0]) ! 579: break; ! 580: } ! 581: if (j < re) ! 582: printf("rv%d", re); ! 583: else ! 584: printf("%c", ch); ! 585: } ! 586: /* ! 587: ** RESULTRES ! 588: */ ! 589: ! 590: char * ! 591: resultres() ! 592: { ! 593: extern char *Resrel; ! 594: ! 595: # ifdef xZTR1 ! 596: if (tTf(52, 5)) ! 597: printf("resultres: Resultvar %d, Resrel %s\n", Qt.qt_resvar, Resrel); ! 598: # endif ! 599: if (Qt.qt_resvar > 0) ! 600: return (Qt.qt_rangev[Qt.qt_resvar].rngvdesc->reldum.relid); ! 601: if (Resrel == 0) ! 602: syserr("resultres: Resrel == 0"); ! 603: ! 604: return (Resrel); ! 605: } ! 606: ! 607: any(c, s) ! 608: register char c; ! 609: register char *s; ! 610: { ! 611: ! 612: while (*s != '\0') ! 613: if (*s++ == c) ! 614: return (TRUE); ! 615: return (FALSE); ! 616: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.