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