|
|
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(@(#)pull_sq.c 8.1 12/31/84)
9:
10: /*
11: ** DECOMP1.C
12: **
13: ** contains routines associated with setting up
14: ** detachable 1-variable sub-queries.
15: ** ptrs to these sq's are kept in the
16: ** array 'sqlist' declared in the main decomp routine.
17: **
18: ** Trace Flags:
19: ** 34
20: */
21:
22:
23: pull_sq(tree1, sqlist, locrang, sqrange, buf)
24: QTREE *tree1;
25: QTREE *sqlist[];
26: int locrang[];
27: int sqrange[];
28: char *buf;
29: {
30: register QTREE *q, *tree, *r;
31: QTREE *s;
32: int anysq, j, badvar;
33: extern QTREE *makroot();
34:
35: tree = tree1;
36:
37: # ifdef xDTR1
38: if (tTf(34, 0))
39: printf("PULL_SQ:tree=%x\n", tree);
40: # endif
41:
42: anysq = 0;
43: for (j = 0; j < MAXRANGE; j++)
44: sqlist[j] = 0;
45:
46: if (tree->sym.value.sym_root.tvarc == 1)
47: return;
48:
49: /* detach all one variable clauses except:
50: ** if the target list is one variable and
51: ** that variable is disjoint from the other
52: ** variables, then don't pull it.
53: **
54: ** It will be more efficient to process it
55: ** all at once in decompy
56: */
57:
58: badvar = 0;
59: if (tree->sym.value.sym_root.lvarc == 1)
60: {
61: badvar = tree->sym.value.sym_root.lvarm; /* get bit position of var */
62:
63: /* look for a two variable clause involving badvar */
64: for (r = tree->right; r->sym.type != QLEND; r = r->right)
65: {
66: if (r->sym.value.sym_root.lvarc > 1 && (r->sym.value.sym_root.lvarm & badvar))
67: {
68: badvar = 0;
69: break;
70: }
71: }
72: }
73: # ifdef xDTR1
74: if (tTf(34, 2))
75: printf("Detachable clauses: (badvar=%o)\n", badvar);
76: # endif
77: for (r=tree; r->right->sym.type!=QLEND; )
78: {
79: # ifdef xDTR1
80: if (tTf(34, 3))
81: nodepr(r);
82: # endif
83: q = r;
84: r = r->right;
85: if (r->sym.value.sym_root.lvarc == 1)
86: {
87: j = bitpos(r->sym.value.sym_root.lvarm);
88: # ifdef xDTR1
89: if (tTf(34, 4))
90: {
91: printf("\nvar=%d, clause\n", j);
92: treepr(r->left);
93: }
94: # endif
95: if (r->sym.value.sym_root.lvarm == badvar)
96: {
97: # ifdef xDTR1
98: if (tTf(34, 5))
99: printf("not detaching \n");
100: # endif
101: continue;
102: }
103: anysq++;
104:
105: if (!sqlist[j]) /* MAKE ROOT NODE FOR SUBQUERY */
106: sqlist[j] = makroot(buf);
107: s = sqlist[j];
108:
109: /* MODIFY MAIN QUERY */
110:
111: q->right = r->right;
112:
113: /* MODIFY `AND` NODE OF DETACHED CLAUSE */
114:
115: r->right = s->right;
116: r->sym.value.sym_root.rvarm = s->sym.value.sym_root.rvarm;
117: r->sym.value.sym_root.tvarc = 1;
118:
119: /* ADD CLAUSE TO SUB-QUERY */
120:
121: s->right = r;
122: s->sym.value.sym_root.rvarm = r->sym.value.sym_root.lvarm;
123: s->sym.value.sym_root.tvarc = 1;
124:
125: # ifdef xDTR1
126: if (tTf(34, 6))
127: {
128: printf("SQ\n");
129: treepr(s);
130: }
131: # endif
132:
133: r = q;
134: }
135: }
136:
137: /* NOW SET UP TARGET LIST FOR EACH SUBQUERY IN SQLIST */
138:
139: # ifdef xDTR1
140: if (tTf(34, 7))
141: printf("# sq clauses=%d\n", anysq);
142: # endif
143: if (anysq)
144: {
145: # ifdef xDTR1
146: if (tTf(34, 8))
147: printf("Dfind--\n");
148: # endif
149: dfind(tree, buf, sqlist);
150: mapvar(tree, 1);
151:
152: /* create the result relations */
153: for (j = 0; j < MAXRANGE; j++)
154: {
155: if (q = sqlist[j])
156: {
157: if (q->left->sym.type != TREE)
158: {
159: savrang(locrang, j);
160: sqrange[j] = mak_t_rel(q, "d", -1);
161: }
162: else
163: sqrange[j] = NORESULT;
164: }
165: }
166: }
167: }
168: /*
169: ** DFIND
170: */
171: dfind(tree, buf, sqlist)
172: register QTREE *tree;
173: char *buf;
174: QTREE *sqlist[];
175: {
176: register char varno;
177: register QTREE *sq;
178: extern QTREE *ckvar();
179:
180: if (tree == NULL)
181: return;
182: # ifdef xDTR1
183: if (tTf(34, 9))
184: nodepr(tree);
185: # endif
186: if (tree->sym.type == VAR)
187: {
188: tree = ckvar(tree);
189: varno = tree->sym.value.sym_var.varno;
190: if (sq = sqlist[varno])
191: maktl(tree, buf, sq, varno);
192: return;
193: }
194:
195: /* IF CURRENT NODE NOT A `VAR` WITH SQ, RECURSE THRU REST OF TREE */
196:
197: dfind(tree->left, buf, sqlist);
198: dfind(tree->right, buf, sqlist);
199: return;
200: }
201: /*
202: ** MAKTL
203: */
204:
205: maktl(node, buf, sq1, varno)
206: QTREE *node;
207: char *buf;
208: QTREE *sq1;
209: int varno;
210: {
211: register QTREE *resdom, *tree, *sq;
212: int domno, map;
213: extern QTREE *makresdom();
214: extern QTREE *copytree();
215:
216: sq = sq1;
217: domno = node->sym.value.sym_var.attno;
218:
219: # ifdef xDTR1
220: if (tTf(34, 12))
221: printf("\tVar=%d,Dom=%d ", varno, domno);
222: # endif
223: /* CHECK IF NODE ALREADY CREATED FOR THIS DOMAIN */
224:
225: for (tree = sq->left; tree->sym.type != TREE; tree = tree->left)
226: if (tree->right->sym.value.sym_var.attno == domno)
227: {
228: # ifdef xDTR1
229: if (tTf(34, 13))
230: printf("Domain found\n");
231: # endif
232: return;
233: }
234:
235: /* create a new resdom for domain */
236:
237: resdom = makresdom(buf, node);
238: resdom->sym.value.sym_resdom.resno = sq->left->sym.type == TREE? 1:
239: sq->left->sym.value.sym_resdom.resno + 1;
240: /* resdom->right is a copy of the var node in order to
241: ** protect against tempvar() changing the var node.
242: */
243: resdom->left = sq->left;
244: resdom->right = copytree(node, buf);
245:
246:
247: /* update ROOT node if necessary */
248:
249: sq->left = resdom;
250: map = 1 << varno;
251: if (!(sq->sym.value.sym_root.lvarm & map))
252: {
253: /* var not currently in tl */
254: sq->sym.value.sym_root.lvarm |= map;
255: sq->sym.value.sym_root.lvarc++;
256:
257: /* if var is not in qualification then update total count */
258: if (!(sq->sym.value.sym_root.rvarm & map))
259: sq->sym.value.sym_root.tvarc++;
260: # ifdef xDTR1
261: if (tTf(34, 15))
262: {
263: printf("new root ");
264: nodepr(sq);
265: }
266: # endif
267: }
268:
269: # ifdef xDTR1
270: if (tTf(34, 14))
271: {
272: printf("new dom ");
273: nodepr(resdom);
274: }
275: # endif
276: return;
277: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.