KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xquark > extractor > algebra > AnalyzePredicateVisitor


1 /*
2  * This file belongs to the XQuark distribution.
3  * Copyright (C) 2003 Universite de Versailles Saint-Quentin.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307.
18  * You can also get it at http://www.gnu.org/licenses/lgpl.html
19  *
20  * For more information on this software, see http://www.xquark.org.
21  */

22
23 package org.xquark.extractor.algebra;
24
25 import java.util.*;
26
27 import org.xquark.extractor.common.Debug;
28 import org.xquark.extractor.common.MessageLibrary;
29 import org.xquark.extractor.common.SqlWrapperException;
30
31
32 public class AnalyzePredicateVisitor extends DefaultSimpleVisitor{
33     private static final String JavaDoc RCSRevision = "$Revision: 1.4 $";
34     private static final String JavaDoc RCSName = "$Name: $";
35
36     AnalyzePredicateHandUpVisitor _aphv = null;
37
38     public AnalyzePredicateVisitor() {
39     }
40
41     public void reinit() {
42         if (null != _aphv) {
43             _aphv.reinit();
44         }
45         else {
46             _aphv = new AnalyzePredicateHandUpVisitor();
47         }
48
49     }
50
51     public void visit(UnOpRestrict arg) throws SqlWrapperException {
52         //Trace.enter(this, "void visit(UnOpRestrict arg)", arg);
53
super.visit((UnaryOperator) arg);
54
55         Set visibleTI = arg.visibleTableInstances();
56         List notSatisfiedPredicateList = new ArrayList();
57         List list = arg.getPredicateList();
58         Expression expr = null;
59         Set referredTI = null;
60         if (null != list) {
61             /* find out not satisfied ( mal placé ) predicate */
62             for (int i = list.size() - 1; i >=0 ; i--) {
63                 expr = (Expression)list.get(i);
64                 referredTI = expr.getReferredTableInstances();
65                 if (visibleTI != null /** @todo */&& !visibleTI.containsAll(referredTI)) {
66                     //Trace.message(this, "visit(UnOpRestrict arg)", "predicat mal placé:");
67
//Trace.message(this, "visit(UnOpRestrict arg)", expr);
68
notSatisfiedPredicateList.add(expr);
69                     list.remove(i);
70                 }
71             }
72
73             Expression father = null;
74             if (! notSatisfiedPredicateList.isEmpty()) {
75                     /* try to hand up the predicates*/
76                     _aphv.reinit();
77                     _aphv.setPredicateList(notSatisfiedPredicateList);
78                     father = arg.getFather();
79                     father.accept(_aphv);
80
81                     if (_aphv.isBlocked()) {
82
83                         resolveDistinct(arg, _aphv.getUnresolvedPredicateList());
84                     }
85             }
86         }
87         //Trace.exit(this, "void visit(UnOpRestrict arg)", arg);
88
}
89
90     private void resolveDistinct( Expression origine, List predicateList) {
91         //Trace.enter(this, "resolveDistinct( Expression origine, List predicateList)");
92

93         Set visibleTableInstances = ((Relation)origine).visibleTableInstances();
94         Set notVisibleTableInstances = getNotVisibleTableInstances(predicateList, visibleTableInstances);
95
96         Expression breakPoint = findBreakPoint(origine, notVisibleTableInstances);
97         Expression blockingBranch = findBlockingBranch(origine,notVisibleTableInstances);
98         Expression mainBranch = extractMainBranch(breakPoint,notVisibleTableInstances);
99
100
101         /* */
102         Expression father = origine.getFather();
103
104         Join join = new Join();
105         join.setPredicateList(predicateList);
106         join.addOperand(mainBranch);
107         join.addOperand(origine);
108         /* insert the join in argebra tree just above origine */
109         father.replaceChild(origine, join);
110
111         /* add items to blocking project distinct when neccessary */
112         UnOpProject blockingNode = (UnOpProject)_aphv.getBlockingNode();
113
114         Set notVisibleAttributeExpressions = getNotVisibleAttributeExpressions(predicateList, visibleTableInstances);
115
116         AttributeExpression[] nVA = new AttributeExpression[notVisibleAttributeExpressions.size()];
117         notVisibleAttributeExpressions.toArray(nVA);
118         AttributeExpression[] mirror = new AttributeExpression[nVA.length];
119
120
121
122         AttributeExpression attr = null;
123         Expression addedExpr = null;
124         AttributeExpression newAttr = null;
125         for (int i = 0 ; i < nVA.length; i++ ) {
126             attr = (AttributeExpression)nVA[i];
127             addedExpr = blockingNode.addItem(attr);
128             newAttr = new AttributeExpression(null,addedExpr.getName());
129             newAttr.setUnderlyingExpr(addedExpr);
130             /** @todo newAttr.setOriginalXExpr() ?? */
131             mirror[i] = newAttr;
132         }
133
134         upDateMirror(mirror, blockingNode.getFather(), breakPoint);
135         /**/
136         father = breakPoint.getFather();
137
138         join = (Join)breakPoint;
139
140         Expression predicate = null;
141         for (int i = 0; i < mirror.length; i++) {
142             predicate = new BinOpCompare(Constants.EQ_COMPOP, nVA[i], mirror[i]);
143             join.addPredicate(predicate);
144         }
145
146         father.replaceChild(breakPoint,join);
147
148         //Trace.exit(this, "resolveDistinct( Expression origine, List predicateList)");
149
}
150
151
152     private Set getNotVisibleTableInstances(List exprList, Collection visibleTableInstances) {
153         //Trace.enter(this, "getNotVisibleTableInstances(List exprList, Collection visibleTableInstances)");
154
Set retVal = new HashSet();
155         Expression expr = null;
156         for (int i = 0; i < exprList.size(); i++) {
157             expr = (Expression)exprList.get(i);
158             retVal.addAll(expr.getReferredTableInstances());
159         }
160         retVal.removeAll(visibleTableInstances);
161
162         //Trace.exit(this, "getNotVisibleTableInstances(List exprList, Collection visibleTableInstances)");
163
return retVal;
164     }
165
166     private Set getNotVisibleAttributeExpressions(List exprList, Collection visibleTableInstances) {
167         //Trace.enter(this, "getNotVisibleAttributeExpressions(List exprList, Collection visibleTableInstances)");
168
Set retVal = new HashSet();
169         Expression expr = null;
170         for (int i = 0; i < exprList.size(); i++) {
171             expr = (Expression)exprList.get(i);
172             retVal.addAll(expr.getReferredAttributes());
173         }
174
175         AttributeExpression attr = null;
176         Object JavaDoc [] attrList = retVal.toArray();
177         for (int i = 0; i < attrList.length; i++) {
178             attr = (AttributeExpression)attrList[i];
179             if (visibleTableInstances.contains(attr.getTableInstance())) {
180                 retVal.remove(attr);
181             }
182         }
183
184         //Trace.exit(this, "getNotVisibleAttributeExpressions(List exprList, Collection visibleTableInstances)");
185
return retVal;
186     }
187
188     private Expression findBreakPoint(Expression startNode, Collection tableInstances) {
189         //Trace.enter(this, "findBreakPoint(Expression startNode, Collection tableInstances)");
190
Expression retVal = startNode;
191         while (!((Relation)retVal).visibleTableInstances().containsAll(tableInstances)) {
192             retVal = ((Expression)retVal).getFather();
193         }
194
195         //Trace.exit(this, "findBreakPoint(Expression startNode, Collection tableInstances)");
196
return retVal;
197     }
198
199     private Expression findBlockingBranch(Expression startNode, Collection notVisibleTableInstances) {
200         //Trace.enter(this, "findBlockingBranch(Expression startNode, Collection notVisibleTableInstances)");
201
Expression retVal = startNode;
202         while (!((Relation)startNode).visibleTableInstances().containsAll(notVisibleTableInstances)) {
203             retVal = startNode;
204             startNode = ((Expression)startNode).getFather();
205         }
206
207         //Trace.exit(this, "findBlockingBranch(Expression startNode, Collection notVisibleTableInstances)");
208
return retVal;
209     }
210
211     private Expression extractMainBranch(Expression breakPoint, Collection concernedTableInstances) {
212         //Trace.enter(this, "extractMainBranch(Expression breakPoint, Set concernedTableInstances)");
213
Expression retVal = null;
214         if (breakPoint instanceof Join) {
215             retVal = extractJoin((Join)breakPoint, concernedTableInstances);
216         }
217         else {
218             Debug.nyi("");
219         }
220
221         //Trace.exit(this, "extractMainBranch(Expression breakPoint, Set concernedTableInstances)");
222
return retVal;
223     }
224
225     private Expression extractJoin(Join breakPoint, Collection concernedTableInstances) {
226         //Trace.enter(this, "extractMainBranch(Join breakPoint, Collection concernedTableInstances)");
227
Expression retVal = null;
228         List predicateList = new ArrayList();
229         List operandList = new ArrayList();
230
231         try {
232             List list = null;
233             Expression expr = null;
234
235             list = breakPoint.getPredicateList();
236             if ( null != list) {
237                 for (int i = 0; i < list.size(); i++) {
238                     expr = (Expression)list.get(i);
239                     if (concernedTableInstances.contains(expr.getReferredTableInstances())) {
240                         predicateList.add(expr.clone());
241                     }
242                 }
243             }
244
245             list = breakPoint.getOperandList();
246             for (int i = 0; i < list.size(); i++) {
247                 expr = (Expression)list.get(i);
248                 if (concernedTableInstances.contains(expr)) {
249                     operandList.add(expr.clone());
250                 }
251             }
252
253         }
254         catch (java.lang.CloneNotSupportedException JavaDoc ex) {
255             throw new SqlWrapperException(MessageLibrary.getMessage("IE_ERR"),null);
256         }
257
258         if (1 < operandList.size()) {
259             retVal = new Join(operandList, predicateList);
260         }
261         else if (1 == operandList.size() ) {
262             if (0 < predicateList.size()) {
263                 retVal = new UnOpRestrict((Expression)operandList.get(0), predicateList);
264             }
265             else {
266                 retVal = (Expression)operandList.get(0);
267             }
268         }
269         else {
270             Debug.assertTrue(false, "Internal logic error");
271         }
272
273         //Trace.exit(this, "extractMainBranch(Join breakPoint, Collection concernedTableInstances)");
274
return retVal;
275     }
276
277     private void upDateMirror(AttributeExpression[] mirror, Expression start, Expression end) {
278         //Trace.enter(this, "upDateMirror(AttributeExpression[] mirror, Expression start, Expression end)");
279

280         Expression cursor = start;
281         AttributeExpression attr = null;
282         do {
283             if (cursor instanceof RenameRelation) {
284                 for (int i = 0; i < mirror.length; i++) {
285                     attr = (AttributeExpression)mirror[i];
286                     attr.setTableInstance((RenameRelation)cursor);
287                 }
288             }
289 // else if () {
290
//
291
// }
292
else {
293                 Debug.nyi("upDateMirror()");
294             }
295             cursor = cursor.getFather();
296         } while (cursor != end);
297
298         //Trace.exit(this, "upDateMirror(AttributeExpression[] mirror, Expression start, Expression end)");
299
}
300 }
301
Popular Tags