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.SqlWrapperException; 29 import org.xquark.xquery.parser.XQueryExpression; 30 31 public final class RemoveProjectVisitor extends DefaultAlgebraVisitor { 32 private static final String RCSRevision = "$Revision: 1.5 $"; 33 private static final String RCSName = "$Name: $"; 34 35 private RemoveProjectReplaceVisitor _rprv; 36 private RemoveProjectGoUpVisitor _rpguv; 37 38 private Stack _scopeStack = new Stack(); 39 40 public void reinit() { 41 _scopeStack.clear(); 42 createScope(); 43 } 44 45 public RemoveProjectVisitor() { 46 } 47 48 52 57 public RemoveProjectGoUpVisitor getGoUpVisitor() { 58 if (null == _rpguv) { 59 _rpguv = new RemoveProjectGoUpVisitor(); 60 } 61 return _rpguv; 62 } 63 64 69 public void setGoUpVisitor(RemoveProjectGoUpVisitor rpguv) { 70 _rpguv = rpguv; 71 } 72 73 private boolean isDeletePermitted() { 74 boolean retVal = ((Scope) _scopeStack.peek())._deletePermited; 76 return retVal; 78 } 79 80 private void permitDelete(Expression node, boolean permit) { 81 Scope currentScope = (Scope) _scopeStack.peek(); 83 currentScope._deletePermited = permit; 84 currentScope._node = node; 85 } 87 88 private Expression currentPermiter() { 89 Scope currentScope = (Scope) _scopeStack.peek(); 91 Debug.assertTrue(currentScope._deletePermited, "currentScope._deletePermited"); 92 return currentScope._node; 94 } 95 96 private void createScope() { 97 _scopeStack.push(new Scope()); 98 } 99 100 private Scope currentScope() { 101 return (Scope) _scopeStack.peek(); 102 } 103 104 private void leaveScope() { 105 RenameRelation rr = currentScope()._unresolvedRenameRelation; 107 if (null != rr) { 108 if (null != rr.getFather() && !(rr.getOperand() instanceof Table)) { 109 110 112 HashMap map = new HashMap(); 113 Object tableInstance = null; 114 Set vtis = rr.visibleTableInstances(); 115 int visibleTableInstancesNumber = vtis.size(); 116 117 if (0 == visibleTableInstancesNumber) { 118 Debug.assertTrue(false, "internal logic error"); 119 } else if (1 == visibleTableInstancesNumber) { 120 tableInstance = (Expression) vtis.toArray()[0]; 121 if (!(tableInstance instanceof RenameRelation)) { 122 tableInstance = new NullPointer(); 123 } 124 map.put(rr, tableInstance); 125 } else { 126 Debug.nyi("remove RenameRelation"); 127 } 128 129 130 getGoUpVisitor().setMap(map); 131 getGoUpVisitor().setEndNode(currentPermiter()); 132 134 Expression father = rr.getFather(); 135 boolean replaced = father.replaceChild(rr, rr.getOperand()); 136 Debug.assertTrue(replaced, "replaced"); 137 rr.setFather(null); 138 father.accept(_rpguv); 140 } 141 } 142 143 _scopeStack.pop(); 144 } 146 147 149 154 public void visit(BinaryAlgebra arg) throws SqlWrapperException { 155 157 158 createScope(); 159 arg.getLeftOperand().accept(this); 160 leaveScope(); 161 162 createScope(); 163 arg.getRightOperand().accept(this); 164 leaveScope(); 165 166 } 168 169 public void visit(BinaryAtomicOp arg) throws SqlWrapperException { 170 172 createScope(); 173 arg.getLeftOperand().accept(this); 174 leaveScope(); 175 176 createScope(); 177 arg.getRightOperand().accept(this); 178 leaveScope(); 179 180 } 182 183 public void visit(BinOpOuterJoin arg) throws SqlWrapperException { 184 186 arg.getLeftOperand().accept(this); 187 arg.getRightOperand().accept(this); 188 189 } 191 192 public void visit(SortSpecification arg) throws SqlWrapperException { 193 Expression sortExpr = arg.getSortExpression(); 195 sortExpr.accept(this); 196 } 198 199 public void visit(RenameRelation arg) throws SqlWrapperException { 200 202 204 if (!(arg.getOperand() instanceof Table || arg.getOperand() instanceof UnOpProject)) { 205 208 currentScope()._unresolvedRenameRelation = arg; 209 } 211 212 Expression operand = arg.getOperand(); 213 operand.accept(this); 214 215 } 217 218 public void visit(Table arg) throws SqlWrapperException { 219 221 } 223 224 public void visit(Join arg) throws SqlWrapperException { 225 227 List list = arg.getPredicateList(); 228 if (null != list) { 229 Expression expr = null; 230 for (int i = 0; i < list.size(); i++) { 231 expr = (Expression) list.get(i); 232 createScope(); 233 expr.accept(this); 234 leaveScope(); 235 } 236 } 237 238 list = arg.getOperands(); 239 Debug.assertTrue(null != list, "null!=list"); 240 Expression expr = null; 241 for (int i = 0; i < list.size(); i++) { 242 expr = (Expression) list.get(i); 243 expr.accept(this); 244 } 245 246 } 248 249 public void visit(UnaryAlgebra arg) throws SqlWrapperException { 250 252 List list = arg.getParameterList(); 253 if (null != list) { 254 Expression expr = null; 255 for (int i = 0; i < list.size(); i++) { 256 expr = (Expression) list.get(i); 257 createScope(); 258 expr.accept(this); 259 leaveScope(); 260 } 261 } 262 263 Expression operand = arg.getOperand(); 264 if (isDeletePermitted()) { 265 266 List opposers = vote(arg); 267 if (null == opposers) { 268 269 } else { 270 permitDelete(arg, false); 271 } 272 } 273 operand.accept(this); 274 275 } 277 278 public void visit(UnaryAtomicOp arg) throws SqlWrapperException { 279 arg.getOperand().accept(this); 281 } 283 284 public void visit(UnOpAggregate arg) throws SqlWrapperException { 285 287 Expression operand = arg.getOperand(); 288 289 290 createScope(); 291 List opposers = vote(arg); 292 if (null == opposers) { 293 permitDelete(arg, true); 294 } 296 operand.accept(this); 297 leaveScope(); 298 299 List itemList = arg.getItemList(); 300 Expression item = null; 301 ; 302 for (int i = 0; i < itemList.size(); i++) { 303 createScope(); 304 item = (Expression) itemList.get(i); 305 item.accept(this); 306 leaveScope(); 307 } 308 309 } 311 312 public void visit(UnOpExists arg) throws SqlWrapperException { 313 createScope(); 315 permitDelete(arg, true); 316 arg.getOperand().accept(this); 317 leaveScope(); 318 } 320 321 public void visit(UnOpProject arg) throws SqlWrapperException { 322 324 Expression operand = arg.getOperand(); 325 326 327 createScope(); 329 330 List opposers = vote(arg); 331 if (null == opposers) { 332 permitDelete(arg, true); 333 } 335 operand.accept(this); 336 leaveScope(); 337 338 339 List itemList = arg.getItemList(); 341 Expression item = null; 342 ; 343 for (int i = 0; i < itemList.size(); i++) { 344 createScope(); 345 item = (Expression) itemList.get(i); 346 item.accept(this); 347 leaveScope(); 348 } 349 350 351 if (isDeletePermitted()) { 352 if (!arg.getDistinct()) { 353 removeProject(arg, currentPermiter()); 354 } else if (currentPermiter() instanceof UnOpAggregate) { 355 358 if (1 == arg.getItemList().size()) { 359 removeProject(arg, currentPermiter()); 360 ((UnOpAggregate) currentPermiter()).distinctAggregation(); 361 362 } else { 363 Debug.nyi("1 != arg.getItemList().size()"); 364 } 365 } 366 } 367 368 } 370 371 private void removeProject(UnOpProject project, Expression permittingNode) { 372 374 HashMap map = makeMap(project); 376 getGoUpVisitor().setMap(map); 377 getGoUpVisitor().setEndNode(permittingNode); 378 380 Expression father = project.getFather(); 381 382 boolean replaced = father.replaceChild(project, project.getOperand()); 383 Debug.assertTrue(replaced, "replaced"); 384 385 project.setFather(null); 386 father.accept(_rpguv); 388 389 } 391 392 private List vote(Expression arg) { 393 395 return null; 397 } 398 399 private List vote(UnOpProject arg) { 400 402 List retVal = null; 403 return retVal; 405 } 406 407 private HashMap makeMap(UnOpProject arg) { 408 410 HashMap retVal = new HashMap(); 411 List itemList = arg.getItemList(); 412 Expression item = null; 413 String attrName = null; 414 AttributeExpression attrExpr = null; 415 Expression replacer = null; 416 XQueryExpression originalXExpr = null; 417 418 for (int i = 0; i < itemList.size(); i++) { 419 item = (Expression) itemList.get(i); 420 attrName = item.getName(); 421 attrExpr = new AttributeExpression(null, attrName); 422 423 426 replacer = findReplacer(item); 427 retVal.put(attrExpr, replacer); 428 } 429 return retVal; 431 } 432 433 private Expression findReplacer(Expression item) { 434 436 Expression retVal = null; 437 438 if (item instanceof RenameItem) { 439 retVal = ((RenameItem) item).getOperand(); 440 retVal = findReplacer(retVal); 441 } 442 else { 451 retVal = item; 452 } 454 455 return retVal; 457 } 458 459 class Scope { 460 private static final String RCSRevision = "$Revision: 1.5 $"; 461 private static final String RCSName = "$Name: $"; 462 463 boolean _deletePermited = false; 464 Expression _node = null; 465 RenameRelation _unresolvedRenameRelation = null; 466 Scope() { 467 } 468 Scope(Expression node, boolean deletePermited) { 469 _node = node; 470 _deletePermited = deletePermited; 471 } 472 } 473 } 474 | Popular Tags |