1 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 RCSRevision = "$Revision: 1.4 $"; 34 private static final String 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 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 62 for (int i = list.size() - 1; i >=0 ; i--) { 63 expr = (Expression)list.get(i); 64 referredTI = expr.getReferredTableInstances(); 65 if (visibleTI != null && !visibleTI.containsAll(referredTI)) { 66 notSatisfiedPredicateList.add(expr); 69 list.remove(i); 70 } 71 } 72 73 Expression father = null; 74 if (! notSatisfiedPredicateList.isEmpty()) { 75 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 } 89 90 private void resolveDistinct( Expression origine, List predicateList) { 91 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 109 father.replaceChild(origine, join); 110 111 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 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 } 150 151 152 private Set getNotVisibleTableInstances(List exprList, Collection visibleTableInstances) { 153 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 return retVal; 164 } 165 166 private Set getNotVisibleAttributeExpressions(List exprList, Collection visibleTableInstances) { 167 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 [] 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 return retVal; 186 } 187 188 private Expression findBreakPoint(Expression startNode, Collection tableInstances) { 189 Expression retVal = startNode; 191 while (!((Relation)retVal).visibleTableInstances().containsAll(tableInstances)) { 192 retVal = ((Expression)retVal).getFather(); 193 } 194 195 return retVal; 197 } 198 199 private Expression findBlockingBranch(Expression startNode, Collection notVisibleTableInstances) { 200 Expression retVal = startNode; 202 while (!((Relation)startNode).visibleTableInstances().containsAll(notVisibleTableInstances)) { 203 retVal = startNode; 204 startNode = ((Expression)startNode).getFather(); 205 } 206 207 return retVal; 209 } 210 211 private Expression extractMainBranch(Expression breakPoint, Collection concernedTableInstances) { 212 Expression retVal = null; 214 if (breakPoint instanceof Join) { 215 retVal = extractJoin((Join)breakPoint, concernedTableInstances); 216 } 217 else { 218 Debug.nyi(""); 219 } 220 221 return retVal; 223 } 224 225 private Expression extractJoin(Join breakPoint, Collection concernedTableInstances) { 226 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 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 return retVal; 275 } 276 277 private void upDateMirror(AttributeExpression[] mirror, Expression start, Expression end) { 278 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 { 293 Debug.nyi("upDateMirror()"); 294 } 295 cursor = cursor.getFather(); 296 } while (cursor != end); 297 298 } 300 } 301 | Popular Tags |