|
|
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.