1: # include "ctlmod.h"
2: # include <ingres.h>
3: # include <aux.h>
4: # include <tree.h>
5: # include <symbol.h>
6: # include <sccs.h>
7: # include <errors.h>
8:
9: SCCSID(@(#)readqry.c 8.3 12/8/85)
10:
11:
12: /*
13: ** READQRY
14: **
15: ** Reads in query symbols from input pipe into core
16: ** locations and sets up information needed for later
17: ** processing.
18: **
19: ** Returns ptr to root of querytree
20: **
21: ** Locbuf is a 'struct srcid' since that is the largest node of
22: ** a QMODE, SOURCEID, or RESULTVAR node.
23: */
24:
25: QTREE *
26: readqry(rdfn, fnparam, initialize)
27: int (*rdfn)(); /* tree read function */
28: int fnparam; /* parameter to pass to rdfn */
29: bool initialize; /* if set, initialize Qbuf */
30: {
31: register QTREE *q;
32: register QTREE *rtval;
33: register DESC *d;
34: extern QTREE *readtree();
35: extern char *xalloc();
36: extern QTREE *trbuild();
37: int mark;
38: extern QTREE *readsym();
39: int i;
40: int j;
41:
42: # ifdef xCTR1
43: if (tTf(10, 8))
44: printf("READQRY:\n");
45: # endif
46:
47: if (initialize)
48: {
49: /* initialize for new query block */
50: clrrange();
51: Qt.qt_resvar = -1;
52: Qt.qt_qmode = -1;
53: }
54: for (i = 0; i < MAXRANGE; i++)
55: Qt.qt_remap[i] = i;
56:
57: mark = markbuf(Qbuf);
58:
59: /* read symbols from input */
60: for (;;)
61: {
62: freebuf(Qbuf, mark);
63: q = readsym(rdfn, fnparam);
64: switch (q->sym.type)
65: {
66: case QMODE:
67: if (Qt.qt_qmode != -1)
68: syserr("readqry: two qmodes");
69: Qt.qt_qmode = q->sym.value.sym_data.i2type;
70: break;
71:
72: case RESULTVAR:
73: if (Qt.qt_resvar != -1)
74: syserr("readqry: two resultvars");
75: Qt.qt_resvar = q->sym.value.sym_data.i2type;
76: break;
77:
78: case SOURCEID:
79: d = (DESC *) xalloc(sizeof *d);
80: bmove((char *) &q->sym.value.sym_srcid.srcdesc, (char *) d, sizeof *d);
81: i = q->sym.value.sym_srcid.srcvar;
82: j = declare(i, d);
83: if (j != i && initialize)
84: syserr("readqry: declare(%d)=%d", i, j);
85: Qt.qt_remap[i] = j;
86: break;
87:
88: case TREE: /* beginning of tree, no more other stuff */
89: q = readtree(q, rdfn, fnparam);
90: rtval = trbuild(q);
91: if (rtval == NULL)
92: error(STACKFULL, 0);
93: return (rtval);
94:
95: default:
96: syserr("readqry: bad symbol %d", q->sym.type);
97: }
98: }
99: }
100: /*
101: ** READSYM
102: ** reads in one symbol from pipe into symbol struct.
103: */
104:
105: QTREE *
106: readsym(rdfn, fnparam)
107: int (*rdfn)(); /* tree read function */
108: char *fnparam;
109: {
110: register int len;
111: register int t;
112: register QTREE *q;
113: extern char *need();
114: int rlen;
115:
116: q = (QTREE *) need(Qbuf, QT_HDR_SIZ);
117: if ((*rdfn)(fnparam, &q->sym, TYP_LEN_SIZ) < TYP_LEN_SIZ)
118: syserr("readsym: read sym");
119: rlen = len = q->sym.len & I1MASK;
120: t = q->sym.type;
121:
122: switch (t)
123: {
124: case AND:
125: if (len < 6)
126: len = 6;
127: break;
128:
129: case ROOT:
130: case AGHEAD:
131: if (len < 8)
132: len = 8;
133: break;
134: }
135:
136: q->sym.len = len;
137:
138:
139: if (len != 0)
140: {
141: /* this will be contiguous with above need call */
142: need(Qbuf, len);
143: }
144: if (rlen != 0)
145: {
146: if ((*rdfn)(fnparam, &q->sym.value, rlen) < rlen)
147: syserr("readsym: read val (sym=%d,%d)", t, rlen);
148: }
149:
150: switch (t)
151: {
152: case ROOT:
153: q->sym.value.sym_root.rootuser = TRUE;
154: break;
155: case AGHEAD:
156: q->sym.value.sym_root.rootuser = FALSE;
157: break;
158: }
159: # ifdef xCTR1
160: if (tTf(10, 9))
161: nodepr(q);
162: # endif xCTR1
163:
164: return (q);
165: }
166: /*
167: ** READTREE
168: **
169: ** reads in tree symbols into a buffer up to a root (end) symbol
170: **
171: */
172:
173: QTREE *
174: readtree(tresym, rdfn, fnparam)
175: QTREE *tresym;
176: int (*rdfn)();
177: char *fnparam;
178: {
179: register QTREE *q;
180: register QTREE *rtval;
181: extern char *need();
182:
183: rtval = tresym;
184:
185: for(;;)
186: {
187: /* space for left & right pointers */
188: q = readsym(rdfn, fnparam);
189: if (q->sym.type == ROOT)
190: return (rtval);
191: }
192: }
193: /*
194: ** TRBUILD -- Rebuild a tree in memory
195: **
196: ** Trbuild is called with a pointer to the TREE node of
197: ** a query already in memory. It rebuilds the pointer
198: ** structure assuming the querytree is in postfix order.
199: **
200: ** Parameters:
201: ** bufptr - a pointer to the TREE node
202: **
203: ** Returns:
204: ** NULL - Internal stack overflow (STACKSIZ)
205: ** pointer to the ROOT node
206: **
207: ** Side Effects:
208: ** All left & right pointers are rebuilt.
209: **
210: ** Called By:
211: ** readqry
212: **
213: ** Syserrs:
214: ** syserr if there are too many leaf nodes or too
215: ** few child nodes
216: */
217:
218:
219: QTREE *
220: trbuild(bufptr)
221: QTREE *bufptr;
222: {
223: register QTREE **stackptr;
224: register char *p;
225: register SYMBOL *s;
226: QTREE *treestack[STACKSIZ];
227: extern bool leaf();
228:
229:
230: stackptr = treestack;
231:
232: /*XXX*/ for (p = (char *) bufptr;; p += QT_HDR_SIZ + ((s->len + 3) & 0374))
233: {
234: s = &((QTREE *)p)->sym;
235: ((QTREE *)p)->left = ((QTREE *)p)->right = 0;
236:
237: /* reunite p with left and right children on stack, if any*/
238: if (!leaf((QTREE *) p)) /* this node has children */
239: {
240: if (s->type != UOP)
241: if (stackptr <= treestack)
242: {
243: err:
244: syserr("trbuild:too few nodes");
245: }
246: else
247: ((QTREE *)p)->right = *(--stackptr);
248: if (s->type != AOP)
249: if (stackptr <= treestack)
250: goto err;
251: else
252: ((QTREE *)p)->left = *(--stackptr);
253: }
254:
255: /*
256: ** If this is a ROOT node then the tree is complete.
257: ** verify that there are no extra nodes in the
258: ** treestack.
259: */
260: if (s->type == ROOT) /* root node */
261: {
262: if (stackptr != treestack)
263: syserr("trbuild:xtra nodes");
264: return ((QTREE *)p);
265: }
266:
267: /* stack p */
268: if (stackptr-treestack >= STACKSIZ)
269: return (NULL); /* error:stack full */
270: *(stackptr++) = (QTREE *) p;
271:
272: }
273: }
274:
275:
276: bool
277: leaf(p)
278: QTREE *p;
279: {
280: switch (p->sym.type)
281: {
282: case VAR:
283: case TREE:
284: case QLEND:
285: case INT:
286: case FLOAT:
287: case CHAR:
288: case COP:
289: return(TRUE);
290:
291: default:
292: return(FALSE);
293: }
294: }
Defined functions
leaf
defined in line
276; used 2 times