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