|
|
1.1 root 1: # include <ingres.h>
2: # include <aux.h>
3: # include <tree.h>
4: # include <symbol.h>
5: # include "globs.h"
6: # include <sccs.h>
7:
8: SCCSID(@(#)decomp.c 7.2 2/9/83)
9:
10: /*
11: ** DECOMP -- Process a query given a query tree and range table.
12: **
13: ** Decomp processes any arbitrary query by converting it into
14: ** a sequence of "one variable queries"; eg. queries involving
15: ** at most one source relation. This file and decision.c contain
16: ** the principle decision making routines.
17: **
18: ** Decomp() is called with a pointer to a query tree, the mode
19: ** of the query (retrieve, append, etc.), and the internal name
20: ** of the result relation (if any). The routines included are:
21: **
22: ** Decomp -- Opens the source relations and decides whether the
23: ** query is multi-variable or single/zero variable.
24: **
25: ** Decompx -- Takes a multivariable query, removes and executes any
26: ** one-var restrictions and passes the remaining query
27: ** to decompz (if one/zero variable) or decision().
28: **
29: ** Decompy -- Performs "tuple substitution" on a multi-var query,
30: ** does any new one-var restrictions and passes the
31: ** remaining query to decompz (if one/zero variable)
32: ** or decision().
33: **
34: ** Decompz -- Executes a one/zero variable query by calling call_ovqp().
35: */
36: /*
37: ** Process query by calling either decompx for multivar
38: ** or decompz for 0 or 1 var query. Decomp() must guarantee
39: ** that the range table is the same upon exiting as it was
40: ** when entered. Newquery() and endquery() perform that function.
41: **
42: ** Trace Flags:
43: ** 30
44: */
45:
46: decomp(q, qmode, result_num)
47: QTREE *q;
48: int qmode;
49: int result_num;
50: {
51: register QTREE *root;
52: register int vc, i;
53: int locrange[MAXRANGE];
54:
55: root = q;
56: vc = root->sym.value.sym_root.tvarc;
57: # ifdef xDTR1
58: if (tTf(30, 0))
59: printf("DECOMP: %d-var query, result_num=%d\n", vc, result_num);
60: if (tTf(30, 1))
61: {
62: printf("DECOMP\n");
63: treepr(root);
64: }
65: # endif
66:
67: openrs(root);
68:
69: if (vc > 1)
70: {
71: newquery(locrange);
72: i = decompx(root, qmode, result_num);
73: endquery(locrange, FALSE); /* don't reopen previous range */
74: }
75: else
76: {
77: De.de_newq = 1;
78: De.de_sourcevar = -1;
79: i = decompz(root, qmode, result_num);
80: }
81:
82: /*
83: ** remove the range variables that the view subsystem
84: ** might have placed in.
85: */
86: clrrange();
87:
88: return (i);
89: }
90: /*
91: ** Decompx -- Initialize for multi-variable query.
92: ** All one-variable subqueries are run.
93: ** If the remaining query is still multi-var
94: ** then decision() is called; else decompz()
95: ** is called. The range table is restored
96: ** after the query is complete.
97: ** The tempvars from the exec_sq() are left on the
98: ** tree since it is presumed that the tree will be discarded
99: ** anyway.
100: **
101: ** Trace Flags:
102: ** 31
103: */
104:
105: decompx(root, qmode, result_num)
106: QTREE *root;
107: int qmode;
108: int result_num;
109: {
110: register int i, vc;
111: int disj;
112: char sqbuf[SQSIZ];
113: QTREE *sqlist[MAXRANGE];
114: int locrang[MAXRANGE], sqrange[MAXRANGE];
115: extern int derror();
116:
117: vc = root->sym.value.sym_root.tvarc;
118: initbuf(sqbuf, SQSIZ, SQBUFFULL, derror);
119: pull_sq(root, sqlist, locrang, sqrange, sqbuf);
120: if ((i = exec_sq(sqlist, sqrange, &disj)) != -1)
121: {
122: undo_sq(sqlist, locrang, sqrange, i, i, FALSE);
123: return (FALSE);
124: }
125: vc -= disj;
126: tempvar(root, sqlist, sqbuf);
127: if (pull_const(root, sqbuf) == 0)
128: return (FALSE);
129: if (vc <= 1)
130: {
131: De.de_sourcevar = -1;
132: De.de_newq = 1;
133: return (decompz(root, qmode, result_num));
134: }
135: i = decision(root, qmode, result_num, sqbuf);
136: undo_sq(sqlist, locrang, sqrange, MAXRANGE, MAXRANGE, FALSE);
137: return (i);
138: }
139: /*
140: ** Decompy -- decompose a multi-variable query by tuple substitution.
141: ** First a variable is selected
142: ** for substitution. Then for each tuple in the
143: ** selected variable, all one variable restrictions
144: ** are done (exec_sq) and the remaining query is
145: ** solved by calling either decompz() or recursively
146: ** decision().
147: **
148: ** The original tree and range table are guaranteed to
149: ** be the same on entry and exit (modulo the effects of
150: ** reformat()).
151: **
152: ** Trace Flags:
153: ** 32
154: */
155:
156: decompy(q, qmode, result_num, sqbuf)
157: QTREE *q;
158: int qmode;
159: int result_num;
160: char *sqbuf;
161: {
162: register QTREE *root;
163: register int j, vc;
164: DESC *d;
165: QTREE *newroot;
166: int constl, sqcnt, var, srcvar, maxsqcnt;
167: int disj, tc, qtrue;
168: TID tid, hitid;
169: char *tuple;
170: QTREE *sqlist[MAXRANGE];
171: int sqmark, sqmark1;
172: int locrang[MAXRANGE], sqrange[MAXRANGE];
173: extern DESC *readopen();
174: extern char *need(), *rangename();
175: extern QTREE *copy_ands();
176:
177: root = q;
178: vc = root->sym.value.sym_root.tvarc;
179:
180: # ifdef xDTR1
181: if (tTf(32, -1))
182: printf("DECOMPY:%x,vc=%d\n", root, vc);
183: # endif
184:
185: sqmark = markbuf(sqbuf);
186: constl = !root->sym.value.sym_root.lvarc;
187: qtrue = FALSE;
188:
189: if ((var = selectv(root)) < 0)
190: return (qtrue);
191: d = readopen(var); /* gets full descriptor for setvar & get */
192: tuple = need(sqbuf, d->reldum.relwid);
193: setvar(root, var, &tid, tuple);
194: pull_sq(root, sqlist, locrang, sqrange, sqbuf);
195: tempvar(root, sqlist, sqbuf);
196: reformat(var, sqlist, locrang, sqbuf, root);
197: vc--;
198: # ifdef xDTR2
199: if (tTf(32, 0))
200: {
201: printf("DECOMPY: &tup=%x, ", tuple);
202: printdesc(d);
203: }
204: # endif xDTR2
205:
206: /* HERE FOR MULTI-VAR SUBSTITUTION */
207: sqmark1 = markbuf(sqbuf);
208: De.de_newq = 1;
209: tc = 0;
210: sqcnt = maxsqcnt = 0;
211: srcvar = -1;
212: De.de_sourcevar = -1;
213: find(readopen(var), NOKEY, &tid, &hitid);
214: while (!(j=get(readopen(var), &tid, &hitid, tuple, NXTTUP)))
215: {
216: # ifdef xDTR1
217: if (tTf(32, 2))
218: {
219: printf("Subst:");
220: printup(readopen(var), tuple);
221: }
222: # endif
223: tc++;
224: if (vc > 1)
225: {
226: reset_sq(sqlist, locrang, sqcnt);
227: if ((sqcnt = exec_sq(sqlist, sqrange, &disj)) != -1)
228: continue;
229:
230: maxsqcnt = sqcnt;
231: vc -= disj;
232: if (vc <= 1)
233: {
234: De.de_sourcevar = srcvar;
235: qtrue |= decompz(root, qmode, result_num);
236: srcvar = De.de_sourcevar;
237: }
238: else
239: {
240: freebuf(sqbuf, sqmark1);
241: newroot = copy_ands(root, sqbuf);
242: qtrue |= decision(newroot, qmode, result_num, sqbuf);
243: }
244: vc += disj;
245: }
246: else
247: qtrue |= decompz(root, qmode, result_num);
248:
249: /* check for early termination on constant Target list */
250: if (constl && qtrue)
251: break;
252: }
253: if (j < 0)
254: syserr("decompy: bad get %d on %.12s", j, readopen(var)->reldum.relid);
255:
256: /* undo the effect of pulling the sub queries */
257: origvar(root, sqlist);
258: undo_sq(sqlist, locrang, sqrange, sqcnt, maxsqcnt, TRUE);
259:
260: /* undo the setvar on the main tree and all subtrees */
261: clearvar(root, var);
262: for (j = 0; j < MAXRANGE; j++)
263: clearvar(sqlist[j], var);
264:
265: /* return any used buffer space */
266: freebuf(sqbuf, sqmark);
267:
268: # ifdef xDTR1
269: if (tTf(32, 2))
270: printf("tc[%.12s]=%d,qtrue=%d\n", rangename(var), tc, qtrue);
271: # endif
272:
273: return (qtrue);
274: }
275: /*
276: ** Decompz processes a one variable query
277: ** by calling call_ovqp().
278: **
279: ** Trace Flags:
280: ** 33
281: */
282:
283: decompz(q, qmode, result_num)
284: QTREE *q;
285: int qmode;
286: int result_num;
287: {
288: register QTREE *root;
289: register int qualfound;
290:
291: root = q;
292: if (root->sym.value.sym_root.tvarc)
293: {
294: if (De.de_sourcevar < 0)
295: {
296: if ((De.de_sourcevar = selectv(root)) < 0)
297: return (FALSE);
298: }
299: }
300: else
301: {
302: De.de_sourcevar = -1;
303: }
304:
305: qualfound = call_ovqp(root, qmode, result_num);
306: De.de_newq = 0;
307: return (qualfound);
308: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.