1 23 24 package org.xquark.mediator.algebra; 25 26 import java.util.*; 27 28 import org.xquark.mediator.decomposer.*; 29 import org.xquark.mediator.plan.*; 30 import org.xquark.mediator.runtime.MediatorException; 31 import org.xquark.xquery.normalize.GetBoundVariablesVisitor; 32 import org.xquark.xquery.parser.*; 33 import org.xquark.xquery.parser.hinttree.HintTree; 34 import org.xquark.xquery.parser.primitivefunctions.fnfunctions.FunctionCOLLECTION; 35 import org.xquark.xquery.parser.util.Constants; 36 37 41 public class AlgFLWR extends Algebra { 42 private static final String RCSRevision = "$Revision: 1.27 $"; 46 47 private static final String RCSName = "$Name: $"; 48 49 private ArrayList subDepFLWRs = null; 53 54 private AlgFLWR parentDepFLWR = null; 55 56 private boolean monoSource = false; 58 59 protected Set sources = null; 60 61 protected HintTree hinttree = null; 62 63 boolean hasInformation = false; 65 66 int subhandling = -1; 68 69 VariableDependencies vardependencies = null; 71 72 private HashMap varOrderMap = null; 77 78 private HashMap orderVarMap = null; 79 80 private ArrayList complexExprOrderList = null; 81 82 private ArrayList varOrderList = null; 83 84 private ArrayList varReOrderList = null; 85 86 private ArrayList varHintList = null; 87 88 private boolean hasCompulseryMerge = false; 90 91 private boolean hasCompulseryNested = false; 92 93 private IsolateWhereVisitor isolateVisitor = null; 94 95 104 public AlgFLWR(XQueryExpression expression, Variable var, AlgebraManager depmanager, boolean islet) throws MediatorException { 105 super(expression, var, depmanager, islet); 106 hinttree = ((FLWRExpression) expression).getHintTree(); 108 fillVarLists(); 110 } 111 112 public void setDependency(AlgFLWR parentDepFLWR) { 116 if (this.parentDepFLWR != null) 117 this.parentDepFLWR.getDependencyList().remove(this); 118 this.parentDepFLWR = parentDepFLWR; 119 ArrayList tmpList = parentDepFLWR.getDependencyList(); 120 if (tmpList == null) { 121 tmpList = new ArrayList(); 122 tmpList.add(this); 123 parentDepFLWR.setDependencyList(tmpList); 124 } else if (!tmpList.contains(this)) 125 tmpList.add(this); 126 } 127 128 public ArrayList getDependencyList() { 129 return subDepFLWRs; 130 } 131 132 public void setDependencyList(ArrayList subDepFLWRs) { 133 this.subDepFLWRs = subDepFLWRs; 134 } 135 136 public boolean isRootQDB() { 137 return (parentDepFLWR == null && parent == null); 138 } 139 140 public boolean isQDB() { 141 return (isRootQDB() || parent == null); 142 } 143 144 public boolean isMonoSource() { 145 return monoSource; 146 } 147 148 public void setMonoSource(boolean monoSource) { 149 this.monoSource = monoSource; 150 } 151 152 public HintTree getHintTree() { 153 return hinttree; 154 } 155 156 public void setHintTree(HintTree hinttree) { 157 this.hinttree = hinttree; 158 } 159 160 public int getSubHandling() { 161 return subhandling; 162 } 163 164 public void setSubHandling(int subhandling) { 165 this.subhandling = subhandling; 166 } 167 168 public boolean hasCompulseryMerge() { 169 return hasCompulseryMerge; 170 } 171 172 public boolean hasCompulseryNested() { 173 return hasCompulseryNested; 174 } 175 176 public void updateVarDependencyList(ArrayList dependVars) { 177 if (parentDepFLWR == null || dependVars == null || dependVars.isEmpty()) 178 return; 179 for (int i = 0; i < dependVars.size(); i++) { 180 Variable tmpvar = (Variable) dependVars.get(i); 181 if (!((FLWRExpression) parentDepFLWR.getExpression()).getVariables().contains(tmpvar)) 182 getParentDepFLWR().addDependSourceVariable(tmpvar); 183 else 184 dependVars.remove(tmpvar); 185 } 186 if (!dependVars.isEmpty()) 187 getParentDepFLWR().updateVarDependencyList(dependVars); 188 } 189 190 private AtomizeWhereVisitor awvisitor = null; 191 192 private void computeVarOrderList() throws MediatorException { 193 ArrayList orders = ((FLWRExpression) expression).getOrderBy(); 194 if (orders != null) { 195 varOrderList = new ArrayList(orders.size()); 196 complexExprOrderList = new ArrayList(1); 197 orderVarMap = new HashMap(); 198 varOrderMap = new HashMap(); 199 GetBoundVariablesVisitor gbvv = new GetBoundVariablesVisitor(true, false); 200 for (int i = 0; i < orders.size(); i++) { 201 XQueryExpression orderExpr = (XQueryExpression) orders.get(i); 202 gbvv.reset(); 205 try { 206 orderExpr.accept(gbvv); 207 } catch (XQueryException e) { 208 throw new MediatorException("Could not extract variables from expression : " + orderExpr, e); 209 } 210 ArrayList tmpList = gbvv.getAllVariables(); 211 orderVarMap.put(orderExpr, tmpList); 212 if (tmpList.size() > 1) { 213 complexExprOrderList.add(orderExpr); 214 if (varOrderList != null && !varOrderList.containsAll(tmpList)) 215 varOrderList = null; 216 ArrayList tmpOrders = (ArrayList) varOrderMap.get(tmpList); 217 if (tmpOrders == null) { 218 tmpOrders = new ArrayList(1); 219 varOrderMap.put(tmpList, tmpOrders); 220 } 221 tmpOrders.add(orderExpr); 222 } else { 223 Variable tmpVar = (Variable) tmpList.get(0); 224 if (((FLWRExpression) expression).getVariables().contains(tmpVar)) { 225 int pos = varOrderList.indexOf(tmpVar); 226 if (pos >= 0 && pos != varOrderList.size() - 1) 227 varOrderList = null; 228 else if (pos == -1) 229 varOrderList.add(tmpVar); 230 ArrayList tmpOrders = (ArrayList) varOrderMap.get(tmpVar); 231 if (tmpOrders == null) { 232 tmpOrders = new ArrayList(1); 233 varOrderMap.put(tmpVar, tmpOrders); 234 } 235 tmpOrders.add(orderExpr); 236 } 237 } 238 } 239 if (complexExprOrderList.isEmpty()) 240 complexExprOrderList = null; 241 } 242 } 243 244 247 private void updateVarListWithDependencies(ArrayList varlist, ArrayList rangelist, boolean reorder) { 248 if (varlist == null || varlist.isEmpty()) 249 return; 250 int i = 0; 251 while (i < varlist.size()) { 252 Variable tmpVari = (Variable) varlist.get(i); 253 Algebra tmpNode = algManager.getMapNode(tmpVari); 254 if (tmpNode != null) { 255 ArrayList tmpList = tmpNode.getVarsDependingOn(); 256 if (tmpList != null) { 257 for (int j = 0; j < tmpList.size(); j++) { 258 Variable tmpVarj = (Variable) tmpList.get(j); 259 if (rangelist != null && !rangelist.contains(tmpVarj)) 260 continue; 261 int posj = varlist.indexOf(tmpVarj); 262 if (posj > i) { 263 varlist.remove(tmpVarj); 264 varlist.add(i, tmpVarj); 265 if (reorder) { 266 if (!varReOrderList.contains(tmpVari)) 267 varReOrderList.add(tmpVari); 268 if (!varReOrderList.contains(tmpVarj)) 269 varReOrderList.add(tmpVarj); 270 } 271 i--; 272 break; 273 } else if (posj == -1) { 274 varlist.add(i, tmpVarj); 275 i--; 276 break; 277 } 278 } 279 } 280 } 281 i++; 282 } 283 } 284 285 private void verifyVarOrderList() { 286 if (varOrderList == null) { 287 varOrderList = ((FLWRExpression) expression).getVariables(); 288 if (((FLWRExpression) expression).getOrderBy() != null) 289 varReOrderList = ((FLWRExpression) expression).getVariables(); 290 } else { 291 varReOrderList = new ArrayList(); 292 int i = 0; 294 while (i < varOrderList.size()) { 295 Variable tmpVari = (Variable) varOrderList.get(i); 296 Algebra tmpNode = algManager.getMapNode(tmpVari); 297 ArrayList tmpList = tmpNode.getVarsDependingOn(); 298 if (tmpList != null) { 299 for (int j = 0; j < tmpList.size(); j++) { 300 Variable tmpVarj = (Variable) tmpList.get(j); 301 int posj = varOrderList.indexOf(tmpVarj); 302 if (posj > i) { 303 varOrderList.remove(tmpVarj); 304 varOrderList.add(i, tmpVarj); 305 if (!varReOrderList.contains(tmpVari)) 306 varReOrderList.add(tmpVari); 307 if (!varReOrderList.contains(tmpVarj)) 308 varReOrderList.add(tmpVarj); 309 i--; 310 break; 311 } else if (posj == -1) { 312 varOrderList.add(i, tmpVarj); 313 i--; 314 break; 315 } 316 } 317 } 318 i++; 319 } 320 if (varReOrderList.isEmpty()) 321 varReOrderList = null; 322 ArrayList varlist = ((FLWRExpression) expression).getVariables(); 324 if (varOrderList.size() < varlist.size()) { 325 for (i = 0; i < varlist.size(); i++) { 326 if (!varOrderList.contains(varlist.get(i))) { 327 varOrderList.add(varlist.get(i)); 328 } 329 } 330 } 331 } 332 } 333 334 private void fillList(ArrayList varlist, ArrayList allvars) { 335 if (varlist.containsAll(allvars)) 336 return; 337 for (int i = 0; i < allvars.size(); i++) { 338 if (!varlist.contains(allvars.get(i))) { 339 varlist.add(allvars.get(i)); 340 } 341 } 342 } 343 344 348 349 private boolean verifyVarHintList() { 350 if (varHintList == null) 351 return false; 352 ArrayList vars = ((FLWRExpression) expression).getVariables(); 353 if (!vars.containsAll(varHintList)) 355 return false; 356 for (int i = 0; i < varHintList.size(); i++) { 358 if (varHintList.lastIndexOf(varHintList.get(i)) != i) 359 return false; 360 } 361 ArrayList remainvars = (ArrayList) vars.clone(); 363 remainvars.removeAll(varHintList); 364 if (!remainvars.isEmpty()) { 365 updateVarListWithDependencies(remainvars, remainvars, false); 366 } 367 for (int i = 0; i < varHintList.size(); i++) { 369 Variable vari = (Variable) vars.get(i); 370 if (vari.getBindingType() != Constants.FOR_BINDINGTYPE) 371 return false; 372 XQueryExpression expri = vari.getExpression(); 373 if (expri instanceof LocatedExpression) 374 expri = ((LocatedExpression) expri).getExpression(); 375 if (!(expri instanceof FunctionCOLLECTION)) 376 return false; 377 } 378 379 382 return true; 383 } 384 385 private boolean updateVarHintList(HintTree hinttree) { 386 if (hinttree == null) 387 return false; 388 ArrayList vars = ((FLWRExpression) expression).getVariables(); 389 392 updateVarListWithDependencies(hinttree.getVarList(), vars, false); 393 return true; 394 } 395 396 private void compeReOrdering(boolean hasMerge, ArrayList varList) { 397 if (hasMerge) 398 varReOrderList = (ArrayList) ((FLWRExpression) expression).getVariables().clone(); 400 else { 401 if (varOrderList == null || varOrderList.isEmpty()) 402 return; 403 ArrayList tmplist = (ArrayList) ((FLWRExpression) expression).getVariables().clone(); 404 tmplist.removeAll(varList); 405 tmplist.addAll(0, varList); 406 if (varReOrderList == null) 407 varReOrderList = new ArrayList(); 408 else 409 varReOrderList.clear(); 410 int pos = -1; 411 for (int j = 0; j < tmplist.size(); j++) { 412 Variable tmpVarj = (Variable) tmplist.get(j); 413 int posj = varOrderList.indexOf(tmpVarj); 414 if (posj > pos) 415 pos = posj; 416 else 417 for (int i = 0; i < tmplist.size(); i++) { 418 Variable tmpVari = (Variable) tmplist.get(i); 419 if (!varReOrderList.contains(tmpVari)) 420 varReOrderList.add(tmpVari); 421 } 422 } 423 if (varReOrderList.isEmpty()) 424 varReOrderList = null; 425 } 426 } 427 428 431 432 public void makeInformation() throws MediatorException { 433 if (hasInformation) 434 return; 435 hasInformation = true; 436 if (!isMonoSource()) { 438 if (algChildren != null) { 439 for (int i = 0; i < algChildren.size(); i++) 440 if (((Algebra) algChildren.get(i)).getVariables().size() != 1) 441 throw new MediatorException("Found DepNode of more than one variable as child of DepFLWR"); 442 } 443 } else { 444 if (hinttree != null) { 445 if (hinttree.getOuterType() != HintTree.NO_TYPE) 446 hinttree.setType(HintTree.NO_TYPE); 447 } 448 } 449 451 XQueryExpression wexpr = ((FLWRExpression) expression).getWhereClause(); 452 if (wexpr != null) { 453 vardependencies = new VariableDependencies(wexpr); 454 } 465 if (hinttree != null && hinttree.getType() != HintTree.NO_TYPE) { 467 varHintList = hinttree.getVarList(); 468 if (updateVarHintList(hinttree)) { 469 if (verifyVarHintList()) { 470 } else { 471 hinttree = null; 472 } 473 } else { 474 hinttree = null; 475 } 476 } 477 computeVarOrderList(); 478 if (hinttree != null) 479 compeReOrdering(hinttree.hasMerge(), hinttree.getVarList()); 480 else 481 compeReOrdering(algManager.getPlan().getDefaultSubHandling() == HintTree.MERGE_TYPE, ((FLWRExpression) expression).getVariables()); 482 } 483 484 public XQueryExpression getWhereClause() { 485 return ((FLWRExpression) expression).getWhereClause(); 486 } 487 488 public VariableDependencies getVarDependencies() { 489 return vardependencies; 490 } 491 492 503 504 private Operator createVarsOperator(ExecutionPlan plan, Operator operator, List varlist, List vars) throws MediatorException { 508 for (int i = 0; i < vars.size(); i++) { 512 operator = createVarOperator(plan, operator, varlist, (Variable) vars.get(i)); 513 } 514 return operator; 515 } 516 517 private Operator createVarOperator(ExecutionPlan plan, Operator operator, List varlist, Variable var) throws MediatorException { 521 Algebra depchildi = algManager.getMapNode(var); 526 XQueryExpression depchildiexpr = depchildi.getExpression(); 527 Variable vari = (Variable) depchildi.getVariables().get(0); 529 if (!isMonoSource()) 530 algManager.addVarToScope(vari); 531 else 532 algManager.addVarsToScope(depchildi.getVariables()); 533 boolean isleti = depchildi.isLet(); 534 varlist.add(vari); 535 if (vardependencies != null) { 551 ArrayList tmplist = vardependencies.getAllAssociatedVariables(vari); 552 if (tmplist != null) { 553 for (int i = 0; i < tmplist.size(); i++) { 554 Variable tmpvari = (Variable) tmplist.get(i); 555 if (algManager.getScopeVariables().contains(tmpvari)) { 556 if (depchildiexpr instanceof FLWRExpression && ((FLWRExpression) depchildiexpr).getVariables().contains(tmpvari)) { 557 if (!depchildi.getVarsWhereOn().contains(tmpvari)) 558 depchildi.getVarsWhereOn().add(tmpvari); 559 } else { 560 if (!depchildi.getVarsDependingOn().contains(tmpvari)) 561 depchildi.getVarsDependingOn().add(tmpvari); 562 } 563 } 564 565 } 566 } 567 } 568 boolean doSort = false; 569 if (operator == null) { 570 if (depchildi instanceof AlgLocated || depchildi instanceof AlgVar || depchildi instanceof AlgArithFunction) 571 operator = new OpNotSource(plan, depchildi); 573 else 574 operator = (Operator) depchildi.createOperator(plan); 575 doSort = true; 576 } else { 577 if (!depchildi.getDepends()) { 578 Operator tmpOp = depchildi.createOperator(plan); 579 if (!(depchildi instanceof AlgSource) && varOrderMap != null) { 581 ArrayList orders = (ArrayList) varOrderMap.get(vari); 582 if (orders != null) 583 tmpOp = new OpSort(plan, tmpOp, orders); 584 } 585 if (isleti) { 586 operator = new OpMerge(plan, depchildiexpr, operator, tmpOp); 587 } else { 588 operator = new OpCartesian(plan, depchildiexpr, operator, tmpOp); 589 } 590 } else { if (depchildi instanceof AlgLocated || depchildi instanceof AlgVar || depchildi instanceof AlgArithFunction) { 592 operator = new OpSimpleMerge(plan, depchildi, operator); 594 doSort = true; 595 } else if (depchildi instanceof AlgFunction && depchildi.getChildren() == null) { 596 operator = new OpSimpleMerge(plan, depchildiexpr, vari, operator, depchildi.isLet()); 597 doSort = true; 598 } else { 599 Operator[] tmplist = new Operator[2]; 600 tmplist[0] = operator; 601 Operator tmpOp = depchildi.createOperator(plan); 602 if (!(depchildi instanceof AlgSource) && varOrderMap != null) { 604 ArrayList orders = (ArrayList) varOrderMap.get(vari); 605 if (orders != null) 606 tmpOp = new OpSort(plan, tmpOp, orders); 607 } 608 tmpOp.setDepends(depchildi); 609 tmplist[1] = tmpOp; 610 operator = new OpSubQuery(plan, depchildiexpr, tmplist, true, false); 611 } 612 613 } 614 } 615 617 XQueryExpression tmpExpr = ((FLWRExpression) expression).getWhereClause(); 618 if (tmpExpr != null) { 619 if (operator instanceof OpSource || operator instanceof OpSubQuery) { 620 if (isolateVisitor == null) 621 isolateVisitor = new IsolateWhereVisitor(algManager.getScopeVariables()); 622 else 623 isolateVisitor.reset(algManager.getScopeVariables()); 624 isolateVisitor.putVar(true); 625 try { 626 tmpExpr.accept(isolateVisitor); 627 } catch (XQueryException e) { 628 throw new MediatorException("Can't isolate where expression : " + tmpExpr, e); 629 } 630 631 tmpExpr = isolateVisitor.getIsolatedExpression(); 632 if (tmpExpr != null) { 633 operator = operator.addCondition(plan, tmpExpr); 634 } 636 ((FLWRExpression) expression).setWhereClause(isolateVisitor.getRemainingExpression()); 637 } else { 638 639 if (isolateVisitor == null) 640 isolateVisitor = new IsolateWhereVisitor(algManager.getScopeVariables()); 641 else 642 isolateVisitor.reset(algManager.getScopeVariables()); 643 isolateVisitor.putVar(true); 644 try { 645 tmpExpr.accept(isolateVisitor); 646 } catch (XQueryException e) { 647 throw new MediatorException("Can't isolate where expression : " + tmpExpr, e); 648 } 649 650 tmpExpr = isolateVisitor.getIsolatedExpression(); 651 if (tmpExpr != null) { 652 operator = operator.addCondition(plan, tmpExpr); 653 } 655 ((FLWRExpression) expression).setWhereClause(isolateVisitor.getRemainingExpression()); 656 657 } 658 } 659 if (doSort && !(depchildi instanceof AlgSource) && varOrderMap != null) { 661 ArrayList orders = (ArrayList) varOrderMap.get(vari); 662 if (orders != null) 663 operator = new OpSort(plan, operator, orders); 664 } 665 return operator; 666 } 667 668 private boolean extractConditionsfromMap(VariableDependencies dep, List varListLeft, List varListRight, ArrayList leftExpressions, ArrayList rightExpressions, ArrayList mergeRestrictions, ArrayList otherRestrictions) { 670 boolean hasnoteq = false; 671 for (int il = 0; il < varListLeft.size(); il++) { 672 Variable leftvar = (Variable) varListLeft.get(il); 673 if (vardependencies != null) { 674 HashMap tmpmap = vardependencies.getJoinMap(leftvar); 675 if (tmpmap != null) { 676 for (int ir = 0; ir < varListRight.size(); ir++) { 678 Variable rightvar = (Variable) varListRight.get(ir); 679 ArrayList tmplist = (ArrayList) tmpmap.get(rightvar); 680 if (tmplist != null) { 681 for (int i = 0; i < tmplist.size(); i++) { 682 XQueryExpression tmpexpr = (XQueryExpression) tmplist.get(i); 683 if (tmpexpr instanceof ListOpCompExpression) { 684 ListOpCompExpression listopcomp = (ListOpCompExpression) tmpexpr; 685 XQueryExpression expr1 = listopcomp.getExpression1(); 686 XQueryExpression expr2 = listopcomp.getExpression2(); 687 if ((expr1 instanceof LocatedExpression || expr1 instanceof Variable) && (expr2 instanceof LocatedExpression || expr2 instanceof Variable)) { 688 if (listopcomp.getOperator() == Constants.EQ_COMPOP) { 689 if (((expr1 instanceof LocatedExpression && ((LocatedExpression) expr1).startsWith(rightvar)) || expr1 == rightvar) && ((expr2 instanceof LocatedExpression && ((LocatedExpression) expr2).startsWith(leftvar)) || expr2 == leftvar)) { 692 XQueryExpression bufexpr = expr2; 693 try { 694 listopcomp.setExpression2(expr1); 695 listopcomp.setExpression1(bufexpr); 696 } catch (XQueryException e) { 697 } 698 } 699 if (hasnoteq) { 700 leftExpressions.add(mergeRestrictions.size() - 1, listopcomp.getExpression1()); 701 rightExpressions.add(mergeRestrictions.size() - 1, listopcomp.getExpression2()); 702 mergeRestrictions.add(mergeRestrictions.size() - 1, listopcomp); 703 } else { 704 leftExpressions.add(listopcomp.getExpression1()); 705 rightExpressions.add(listopcomp.getExpression2()); 706 mergeRestrictions.add(listopcomp); 707 } 708 } else if (!hasnoteq && (listopcomp.getOperator() == Constants.GEQ_COMPOP || listopcomp.getOperator() == Constants.GT_COMPOP || listopcomp.getOperator() == Constants.LEQ_COMPOP || listopcomp.getOperator() == Constants.LT_COMPOP)) { 709 hasnoteq = true; 710 if (((expr1 instanceof LocatedExpression && ((LocatedExpression) expr1).startsWith(rightvar)) || expr1 == rightvar) && ((expr2 instanceof LocatedExpression && ((LocatedExpression) expr2).startsWith(leftvar)) || expr2 == leftvar)) { 713 XQueryExpression bufexpr = expr2; 714 try { 715 listopcomp.setExpression2(expr1); 716 listopcomp.setExpression1(bufexpr); 717 if (listopcomp.getOperator() == Constants.GEQ_COMPOP) 718 listopcomp.setOperator(Constants.LEQ_COMPOP); 719 else if (listopcomp.getOperator() == Constants.GT_COMPOP) 720 listopcomp.setOperator(Constants.LT_COMPOP); 721 else if (listopcomp.getOperator() == Constants.LEQ_COMPOP) 722 listopcomp.setOperator(Constants.GEQ_COMPOP); 723 else if (listopcomp.getOperator() == Constants.LT_COMPOP) 724 listopcomp.setOperator(Constants.GT_COMPOP); 725 } catch (XQueryException e) { 726 } 727 } 728 leftExpressions.add(listopcomp.getExpression1()); 729 rightExpressions.add(listopcomp.getExpression2()); 730 mergeRestrictions.add(listopcomp); 731 } else if (otherRestrictions != null) 732 otherRestrictions.add(listopcomp); 733 734 } else if (otherRestrictions != null) 735 otherRestrictions.add(listopcomp); 736 } else if (otherRestrictions != null) 737 otherRestrictions.add(tmpexpr); 738 } 739 } 740 } 741 } 742 ArrayList conds = vardependencies.getAllComplexConditionsWithVar(leftvar); 744 if (conds != null) 745 for (int i = 0; i < conds.size(); i++) 746 if (!otherRestrictions.contains(conds.get(i))) 747 otherRestrictions.add(conds.get(i)); 748 } 749 } 750 return hasnoteq; 751 } 752 753 private ArrayList getMainDependVars(Variable var) { 757 ArrayList reslist = null; 758 ArrayList tmplist = algManager.getMapNode(var).getVarsDependingOn(); 759 if (tmplist != null) { 760 reslist = new ArrayList(1); 761 for (int i = 0; i < tmplist.size(); i++) { 762 ArrayList list = getMainDependVars((Variable) tmplist.get(i)); 763 if (list != null) 764 reslist.addAll(list); 765 else 766 reslist.add(tmplist.get(i)); 767 } 768 if (reslist.isEmpty()) 769 reslist = null; 770 } 771 return reslist; 772 } 773 774 private Operator createOperator(ExecutionPlan plan, HintTree hint, List vars) throws MediatorException { 775 return createOperator(plan, hint, plan.getDefaultSubHandling(), vars); 776 } 777 778 private Operator createOperator(ExecutionPlan plan, HintTree hint, byte defaultHintType, List vars) throws MediatorException { 779 783 byte hintType = defaultHintType; 785 Object left = null; 786 Object right = null; 787 List varListLeft = null; 788 List varListRight = null; 789 boolean hasLeftloop = false; 790 boolean hasRightLoop = false; 791 if (hint != null && hint.getType() != HintTree.NO_TYPE) { 792 hintType = hint.getType(); 793 left = hint.getLeftHint(); 794 right = hint.getRightHint(); 795 796 if (left instanceof Variable) { 797 varListLeft = new ArrayList(1); 798 varListLeft.add(left); 799 } else 800 varListLeft = ((HintTree) left).getVarList(); 801 802 if (right instanceof Variable) { 803 varListRight = new ArrayList(1); 804 varListRight.add(right); 805 } else 806 varListRight = ((HintTree) right).getVarList(); 807 } else if (vars != null) { 808 if (vars.size() < 2) 809 return null; 810 else { 811 817 boolean hasJoinMap = (vardependencies != null && vardependencies.getJoinsMap() != null && !vardependencies.getJoinsMap().isEmpty()); 818 819 varListLeft = new ArrayList(); 820 for (int i = 0; i < vars.size(); i++) { 821 Variable vari = (Variable) vars.get(i); 822 if (varListRight == null) { 823 varListLeft.add(vari); 824 if (!hasLeftloop && vari.getBindingType() == Constants.FOR_BINDINGTYPE) 825 hasLeftloop = true; 826 if (hasJoinMap) { 827 Map tmpmap = vardependencies.getJoinMap(vari); 828 if (tmpmap != null) { 829 boolean found = false; 830 for (Iterator it = tmpmap.keySet().iterator(); it.hasNext();) { 831 if (vars.contains(it.next())) { 832 found = true; 833 break; 834 } 835 } 836 if (found) 837 varListRight = new ArrayList(); 838 } 839 } 840 } else { 841 ArrayList depends = getMainDependVars(vari); 842 if (depends != null) { 843 if (varListLeft.containsAll(depends)) { 844 varListLeft.add(vari); 845 if (!hasLeftloop && vari.getBindingType() == Constants.FOR_BINDINGTYPE) 846 hasLeftloop = true; 847 } else if (varListRight.containsAll(depends)) { 848 varListRight.add(vari); 849 if (!hasRightLoop && vari.getBindingType() == Constants.FOR_BINDINGTYPE) 850 hasRightLoop = true; 851 } else 852 return null; 853 } else { 854 varListRight.add(vari); 855 if (!hasRightLoop && vari.getBindingType() == Constants.FOR_BINDINGTYPE) 856 hasRightLoop = true; 857 } 858 } 859 } 860 if (varListRight == null || varListRight.isEmpty()) 861 return null; 862 if (hintType == HintTree.MERGE_TYPE) { 863 if (!hasLeftloop || !hasRightLoop) { 864 hintType = HintTree.NESTED_LOOP_TYPE; 865 } 866 } 867 if (hintType == HintTree.NESTED_LOOP_TYPE) { 869 if (hasLeftloop || !hasRightLoop) { 870 List tmpVarList = varListRight; 871 varListRight = varListLeft; 872 varListLeft = tmpVarList; 873 } 874 } 875 } 928 } else 929 return null; 930 931 if (hintType == HintTree.MERGE_TYPE) { 932 ArrayList mergeRestrictions = new ArrayList(1); 933 ArrayList otherRestrictions = new ArrayList(1); 934 ArrayList leftExpressions = new ArrayList(1); 935 ArrayList rightExpressions = new ArrayList(1); 936 boolean hasnoteq = false; 937 if (hint != null || vars.size() >= 2) 938 hasnoteq = extractConditionsfromMap(vardependencies, varListLeft, varListRight, leftExpressions, rightExpressions, mergeRestrictions, otherRestrictions); 939 940 if (mergeRestrictions.isEmpty() && otherRestrictions.isEmpty()) { 941 ArrayList varlist = new ArrayList(); 943 Operator leftAlg = null; 944 if (varListLeft.size() == 1) 945 leftAlg = createVarOperator(plan, null, varlist, (Variable) varListLeft.get(0)); 946 else { 947 leftAlg = createOperator(plan, (HintTree) hint.getLeftHint(), null); 948 if (leftAlg == null) 949 leftAlg = createVarsOperator(plan, null, varlist, varListLeft); 950 } 951 varlist.removeAll(varListLeft); 952 algManager.removeVarsFromScope(varListLeft); 953 Operator rightAlg = null; 954 if (varListRight.size() == 1) 955 rightAlg = createVarOperator(plan, null, varlist, (Variable) varListRight.get(0)); 956 else { 957 rightAlg = createOperator(plan, null, varListRight); 958 if (rightAlg == null) 959 rightAlg = createVarsOperator(plan, null, varlist, varListRight); 960 } 961 algManager.addVarsToScope(varListLeft); 962 algManager.addVarsToScope(varListRight); 963 return new OpCartesian(plan, expression, leftAlg, rightAlg); 964 } 965 966 for (int i = 0; i < otherRestrictions.size(); i++) { 968 XQueryExpression otheri = (XQueryExpression) otherRestrictions.get(i); 969 ArrayList tmplist = vardependencies.getVarsOfCond(otheri); 970 for (int j = 0; j < tmplist.size(); j++) { 971 Variable varj = (Variable) tmplist.get(j); 972 ArrayList varjlist = vardependencies.getAllComplexConditionsWithVar(varj); 974 if (varjlist != null) 975 varjlist.remove(otheri); 976 } 977 } 978 979 if (mergeRestrictions.isEmpty()) { 980 } 981 if (hasnoteq) { 982 ListOpCompExpression listopcomp = (ListOpCompExpression) mergeRestrictions.get(mergeRestrictions.size() - 1); 983 if (listopcomp.getOperator() == Constants.LT_COMPOP || listopcomp.getOperator() == Constants.LEQ_COMPOP) { 984 ((XQueryExpression) leftExpressions.get(mergeRestrictions.size() - 1)).setOrder(Constants.DESCENDING_ORDER); 985 ((XQueryExpression) rightExpressions.get(mergeRestrictions.size() - 1)).setOrder(Constants.DESCENDING_ORDER); 986 } 987 } 988 989 ArrayList varlist = new ArrayList(); 990 Operator leftAlg = null; 991 if (hint == null) { 992 leftAlg = createOperator(plan, null, defaultHintType, varListLeft); 998 if (leftAlg == null) { 999 leftAlg = createVarsOperator(plan, null, varlist, varListLeft); 1000 varlist.removeAll(varListLeft); 1001 } 1002 algManager.removeVarsFromScope(varListLeft); 1003 } else if (left instanceof Variable) { 1004 leftAlg = createVarOperator(plan, null, varlist, (Variable) left); 1005 varlist.remove(left); 1006 algManager.removeVarFromScope((Variable) left); 1007 } else { 1008 leftAlg = createOperator(plan, (HintTree) left, null); 1009 if (leftAlg == null) 1010 leftAlg = createVarsOperator(plan, null, varlist, varListLeft); 1011 algManager.removeVarsFromScope(((HintTree) left).getVarList()); 1012 } 1014 if (!leftExpressions.isEmpty()) { 1015 if (!(leftAlg instanceof OpSort)) 1016 leftAlg = new OpSort(plan, leftAlg, leftExpressions); 1017 leftAlg.addIndexSpec(leftExpressions); 1018 } 1019 Operator rightAlg = null; 1020 if (hint == null) { 1021 rightAlg = createOperator(plan, null, hintType, varListRight); 1029 if (rightAlg == null) { 1030 rightAlg = createVarsOperator(plan, null, varlist, varListRight); 1031 varlist.removeAll(varListRight); 1032 } 1033 algManager.removeVarsFromScope(varListRight); 1034 } else if (right instanceof Variable) { 1035 rightAlg = createVarOperator(plan, null, varlist, (Variable) right); 1036 } else { 1039 rightAlg = createOperator(plan, (HintTree) right, null); 1040 if (rightAlg == null) 1041 rightAlg = createVarsOperator(plan, null, varlist, varListRight); 1042 algManager.removeVarsFromScope(((HintTree) right).getVarList()); 1043 } 1045 if (!rightExpressions.isEmpty()) { 1046 if (!(rightAlg instanceof OpSort)) 1047 rightAlg = new OpSort(plan, rightAlg, rightExpressions); 1048 rightAlg.addIndexSpec(rightExpressions); 1049 } 1050 Operator operator = null; 1051 if (mergeRestrictions.isEmpty()) 1052 operator = new OpCartesian(plan, expression, leftAlg, rightAlg); 1053 else { 1054 operator = new OpSortMerge(plan, leftAlg, rightAlg, mergeRestrictions); 1055 } 1056 if (!otherRestrictions.isEmpty()) { 1058 XQueryExpression tmpexpr = null; 1059 if (otherRestrictions.size() == 1) 1060 tmpexpr = (XQueryExpression) otherRestrictions.get(0); 1061 else { 1062 try { 1063 tmpexpr = new BinOpANDExpression((XQueryExpression) otherRestrictions.get(0), (XQueryExpression) otherRestrictions.get(1), expression.getParentModule()); 1064 for (int i = 2; i < otherRestrictions.size(); i++) 1065 tmpexpr = new BinOpANDExpression(tmpexpr, (XQueryExpression) otherRestrictions.get(i), expression.getParentModule()); 1066 } catch (XQueryException e) { 1067 throw new MediatorException("Could not build where clause", e); 1068 } 1069 } 1070 operator = operator.addCondition(plan, tmpexpr); 1071 } 1073 algManager.addVarsToScope((hint != null) ? hint.getVarList() : vars); 1075 return operator; 1079 } 1080 if (hintType == HintTree.NESTED_LOOP_TYPE) { 1081 Operator leftOp = null; 1083 ArrayList varlist = new ArrayList(); 1084 if (hint == null) { 1085 leftOp = createOperator(plan, null, defaultHintType, varListLeft); 1086 if (leftOp == null) 1087 leftOp = createVarsOperator(plan, null, varlist, varListLeft); 1088 varlist.addAll(varListLeft); 1089 algManager.addVarsToScope(varListLeft); 1090 } else if (left instanceof Variable) { 1091 leftOp = createOperator(plan, null, hintType, varListLeft); 1093 if (leftOp == null) 1094 leftOp = createVarsOperator(plan, null, varlist, varListLeft); 1095 varlist.addAll(varListLeft); 1096 algManager.addVarToScope((Variable) left); 1097 } else { 1098 leftOp = createOperator(plan, (HintTree) left, null); 1099 if (leftOp == null) 1100 leftOp = createVarsOperator(plan, null, varlist, varListLeft); 1101 algManager.addVarsToScope(((HintTree) left).getVarList()); 1102 varlist.addAll(((HintTree) left).getVarList()); 1103 } 1104 Operator rightOp = null; 1105 if (hint == null) { 1106 rightOp = createOperator(plan, null, defaultHintType, varListRight); 1107 if (rightOp == null) 1108 rightOp = createVarsOperator(plan, null, varlist, varListRight); 1109 varlist.addAll(varListRight); 1110 algManager.addVarsToScope(varListRight); 1111 } else if (right instanceof Variable) { 1112 rightOp = createOperator(plan, null, hintType, varListRight); 1114 if (rightOp == null) 1115 rightOp = createVarsOperator(plan, null, varlist, varListRight); 1116 varlist.addAll(varListRight); 1117 algManager.addVarToScope((Variable) right); 1118 } else { 1119 rightOp = createOperator(plan, (HintTree) right, null); 1120 if (rightOp == null) 1121 rightOp = createVarsOperator(plan, null, varlist, varListRight); 1122 algManager.addVarsToScope(((HintTree) right).getVarList()); 1123 } 1124 rightOp.setValueDepends(true); 1126 Operator[] tmplistalg = new Operator[2]; 1127 tmplistalg[0] = leftOp; 1128 tmplistalg[1] = rightOp; 1129 return new OpSubQuery(plan, expression, tmplistalg, true, false); 1130 } else { 1131 throw new MediatorException("Unsupported type of hint : " + hintType); 1132 } 1133 } 1134 1135 private void verifySubElements() throws MediatorException { 1136 if (subDepFLWRs == null || subDepFLWRs.isEmpty()) 1141 return; 1142 boolean hasMerge = false; 1143 boolean hasNested = false; 1144 subhandling = HintTree.NO_TYPE; for (int i = 0; i < subDepFLWRs.size(); i++) { 1146 ((AlgFLWR) subDepFLWRs.get(i)).verifySubElements(); 1147 } 1148 if (subhandling != HintTree.NESTED_TYPE) { 1149 for (int i = 0; i < subDepFLWRs.size(); i++) { 1150 AlgFLWR subdepi = (AlgFLWR) subDepFLWRs.get(i); 1151 HintTree ht = ((FLWRExpression) subdepi.getExpression()).getHintTree(); 1152 if (ht != null) { 1153 if (!hasNested && ht.getOuterType() == HintTree.NESTED_TYPE) { 1154 subhandling = HintTree.NESTED_TYPE; 1155 hasNested = true; 1156 break; 1157 } 1158 if (!hasMerge && ht.getOuterType() == HintTree.MERGE_TYPE) 1159 hasMerge = true; 1160 } 1161 } 1162 } else 1163 hasNested = true; 1164 1165 if (hasNested) 1167 subhandling = HintTree.NESTED_TYPE; 1168 else if (hasMerge) 1169 subhandling = HintTree.MERGE_TYPE; 1170 else 1171 subhandling = getAlgebraManager().getPlan().getDefaultSubHandling(); 1172 1173 algManager.addVarsToScope(getVariables()); 1174 for (int i = 0; i < subDepFLWRs.size(); i++) { 1175 AlgFLWR depi = (AlgFLWR) subDepFLWRs.get(i); 1176 depi.makeInformation(); 1177 } 1178 IsolateWhereVisitor visitor = new IsolateWhereVisitor(); 1180 ArrayList varListLeft = ((FLWRExpression) expression).getVariables(); 1181 for (int i = 0; i < subDepFLWRs.size(); i++) { 1182 AlgFLWR depi = (AlgFLWR) subDepFLWRs.get(i); 1183 varListLeft.addAll(((FLWRExpression) depi.getExpression()).getVariables()); 1184 visitor.reset(varListLeft); 1185 if (((FLWRExpression) depi.getExpression()).getWhereClause() != null) { 1186 try { 1187 ((FLWRExpression) depi.getExpression()).getWhereClause().accept(visitor); 1188 } catch (XQueryException e) { 1189 throw new MediatorException("Could not isolated expression : " + ((FLWRExpression) depi.getExpression()).getWhereClause()); 1190 } 1191 } 1192 varListLeft.removeAll(((FLWRExpression) depi.getExpression()).getVariables()); 1193 1194 if (visitor.getRemainingExpression() != null) { 1195 if (getParentDepFLWR() != null) 1196 getParentDepFLWR().setSubHandling(HintTree.NESTED_TYPE); 1197 break; 1198 } 1199 } 1200 1201 algManager.removeVarsFromScope(getVariables()); 1202 } 1203 1204 private Operator createOperator(ExecutionPlan plan, ArrayList indexSpecs, ArrayList subRestrictions, ArrayList outsideRestrictions) throws MediatorException { 1208 Operator retval = null; 1212 if (dependDefinitionVars.isEmpty()) 1213 retval = createOperator(plan); 1214 else if (((FLWRExpression) expression).getWhereClause() == null) 1215 retval = createOperator(plan); 1216 else if (vardependencies.hasJoins()) 1217 retval = createOperator(plan); 1218 else { 1219 ArrayList varListLeft = ((FLWRExpression) getParentDepFLWR().getExpression()).getVariables(); 1220 ArrayList varListRight = ((FLWRExpression) getExpression()).getVariables(); 1221 ArrayList mergeRestrictions = new ArrayList(); 1222 ArrayList otherRestrictions = new ArrayList(); 1223 ArrayList leftExpressions = new ArrayList(); 1224 ArrayList rightExpressions = new ArrayList(); 1225 1226 boolean hasnoteq = extractConditionsfromMap(vardependencies, varListLeft, varListRight, leftExpressions, rightExpressions, mergeRestrictions, otherRestrictions); 1227 if (mergeRestrictions.isEmpty()) { 1228 retval = createOperator(plan); 1229 } else { 1230 if (hasnoteq) { 1231 ListOpCompExpression listopcomp = (ListOpCompExpression) mergeRestrictions.get(mergeRestrictions.size() - 1); 1232 if (listopcomp.getOperator() == Constants.LT_COMPOP || listopcomp.getOperator() == Constants.LEQ_COMPOP) { 1233 ((XQueryExpression) leftExpressions.get(mergeRestrictions.size() - 1)).setOrder(Constants.DESCENDING_ORDER); 1234 ((XQueryExpression) rightExpressions.get(mergeRestrictions.size() - 1)).setOrder(Constants.DESCENDING_ORDER); 1235 } 1236 } 1237 for (int i = 0; i < varListLeft.size(); i++) { 1239 Variable vari = (Variable) varListLeft.get(i); 1240 HashMap tmpmap = (HashMap) vardependencies.getJoinsMap().get(vari); 1241 for (Iterator it = tmpmap.values().iterator(); it.hasNext();) { 1242 ArrayList tmplist = (ArrayList) it.next(); 1243 for (int j = 0; j < tmplist.size(); j++) { 1244 if (!mergeRestrictions.contains(tmplist.get(j)) && !otherRestrictions.contains(tmplist.get(j))) 1245 otherRestrictions.add(tmplist.get(j)); 1246 } 1247 } 1248 } 1249 1250 indexSpecs.add(leftExpressions); 1252 1253 XQueryExpression whereExpr = ((FLWRExpression) expression).getWhereClause(); 1256 try { 1257 for (int i = 0; i < mergeRestrictions.size(); i++) { 1258 whereExpr = whereExpr.erasePart((XQueryExpression) mergeRestrictions.get(i)); 1259 } 1260 for (int i = 0; i < otherRestrictions.size(); i++) { 1261 whereExpr = whereExpr.erasePart((XQueryExpression) otherRestrictions.get(i)); 1262 } 1263 } catch (XQueryException e) { 1264 throw new MediatorException("Could not erase part from expression : " + whereExpr); 1265 } 1266 ((FLWRExpression) expression).setWhereClause(whereExpr); 1267 if (otherRestrictions.isEmpty()) { 1269 outsideRestrictions.add(null); 1270 } else { 1271 if (otherRestrictions.size() == 1) 1272 outsideRestrictions.add(otherRestrictions.get(0)); 1273 else { 1274 try { 1275 BinOpANDExpression tmpBinOp = new BinOpANDExpression((XQueryExpression) otherRestrictions.get(0), (XQueryExpression) otherRestrictions.get(1), expression.getParentModule()); 1276 for (int i = 2; i < otherRestrictions.size(); i++) 1277 tmpBinOp = new BinOpANDExpression(tmpBinOp, (XQueryExpression) otherRestrictions.get(i), expression.getParentModule()); 1278 outsideRestrictions.add(tmpBinOp); 1279 } catch (XQueryException e) { 1280 throw new MediatorException("Could not aggregate list of expressions : " + otherRestrictions); 1281 } 1282 } 1283 } 1284 1285 1303 retval = createOperator(plan); 1304 retval.addIndexSpec(rightExpressions); 1305 subRestrictions.add(mergeRestrictions); 1306 } 1307 } 1308 return retval; 1309 } 1310 1311 public Operator createOperator(ExecutionPlan plan) throws MediatorException { 1312 Operator operator = null; 1314 makeInformation(); 1316 if (getParentDepFLWR() == null) 1318 verifySubElements(); 1319 1320 Operator[] subOperators = null; 1321 ArrayList subRestrictions = null; 1322 ArrayList outsideExpressions = null; 1323 ArrayList indexSpecs = null; 1324 1325 if (subDepFLWRs != null && !subDepFLWRs.isEmpty()) { 1326 1327 algManager.addVarsToScope(((FLWRExpression) expression).getVariables()); 1328 1329 if (subhandling == HintTree.NESTED_TYPE) { 1330 subOperators = new Operator[subDepFLWRs.size() + 1]; 1331 for (int i = 0; i < subDepFLWRs.size(); i++) { 1334 AlgFLWR depi = (AlgFLWR) subDepFLWRs.get(i); 1335 ArrayList varsi = ((FLWRExpression) depi.getExpression()).getVariables(); 1336 Operator subAlg = depi.createOperator(plan); 1348 if (!depi.getVarsDependingOn().isEmpty()) subAlg.setValueDepends(true); 1350 if (!depi.getVarsWhereOn().isEmpty()) subAlg.setWhereDepends(true); 1352 subOperators[i + 1] = subAlg; 1353 } 1355 } 1356 if (subhandling == HintTree.MERGE_TYPE) { 1357 subOperators = new Operator[subDepFLWRs.size() + 1]; 1358 if (outsideExpressions == null) 1360 outsideExpressions = new ArrayList(); 1361 if (indexSpecs == null) 1362 indexSpecs = new ArrayList(); 1363 subRestrictions = new ArrayList(); 1364 for (int i = 0; i < subDepFLWRs.size(); i++) { 1365 AlgFLWR depi = (AlgFLWR) subDepFLWRs.get(i); 1366 ArrayList varsi = ((FLWRExpression) depi.getExpression()).getVariables(); 1367 Operator subAlg = depi.createOperator(plan, indexSpecs, subRestrictions, outsideExpressions); 1379 if (!depi.getVarsDependingOn().isEmpty()) subAlg.setValueDepends(true); 1381 if (!depi.getVarsWhereOn().isEmpty()) subAlg.setWhereDepends(true); 1383 subOperators[i + 1] = subAlg; 1384 } 1385 1386 } 1387 algManager.removeVarsFromScope(((FLWRExpression) expression).getVariables()); 1388 } 1389 1390 operator = createOperator(plan, hinttree, ((FLWRExpression) expression).getVariables()); 1392 if (operator != null) { 1393 if (hinttree != null) { 1395 ArrayList othervars = (ArrayList) ((FLWRExpression) expression).getVariables(); 1396 if (!varHintList.containsAll(othervars)) { 1397 othervars.removeAll(varHintList); 1398 operator = createVarsOperator(plan, operator, varHintList, othervars); 1399 } 1400 } 1401 } 1402 if (operator == null) { 1403 if (!isMonoSource()) { 1405 computeVarOrderList(); 1406 verifyVarOrderList(); 1407 } else { 1408 varOrderList = new ArrayList(); 1409 varOrderList.add(((FLWRExpression) expression).getVariables().get(0)); 1410 } 1411 ArrayList varlist = new ArrayList(varOrderList.size()); 1422 for (int i = 0; i < varOrderList.size(); i++) { 1423 operator = createVarOperator(plan, operator, varlist, (Variable) varOrderList.get(i)); 1424 algManager.getScopeVariables().add(varOrderList.get(i)); 1425 } 1426 algManager.getScopeVariables().removeAll(varOrderList); 1427 } 1428 1429 if (subOperators != null) { 1430 subOperators[0] = operator; 1431 if (subhandling == HintTree.NESTED_TYPE) 1432 operator = new OpSubQuery(plan, expression, subOperators, true, true); 1433 if (subhandling == HintTree.MERGE_TYPE) { 1434 if (subRestrictions.isEmpty()) 1435 operator = new OpSubQuery(plan, expression, subOperators, true, true); 1436 else { 1437 operator.addIndexSpecs(indexSpecs); 1438 operator = new OpSubQuery(plan, expression, subOperators, true, true, subRestrictions, outsideExpressions); 1439 } 1440 } 1441 } 1442 1443 if (parentDepFLWR == null) { 1445 if (parent != null && (variables != null && !variables.isEmpty())) { 1446 boolean retvalue = false; 1448 XQueryExpression retexpr = ((FLWRExpression) expression).getReturnClause(); 1449 while (!retvalue) { 1450 if (retexpr instanceof LocatedExpression || retexpr instanceof Variable) 1451 retvalue = true; 1452 else { 1453 if (retexpr instanceof XQueryExpressionSequence) { 1454 XQueryExpressionSequence retseq = (XQueryExpressionSequence) retexpr; 1455 if (retseq.getSubExpressions().size() == 1) 1456 retexpr = (XQueryExpression) retseq.getSubExpressions().get(0); 1457 else 1458 break; 1459 } else 1460 break; 1461 } 1462 } 1463 if (retvalue) 1464 operator = new OpNotSource(plan, retexpr, (Variable) variables.get(0), operator, islet); 1465 else 1466 operator = new OpNotSource(plan, null, (Variable) variables.get(0), operator, islet); 1468 } 1469 } 1470 if (varReOrderList != null && !varReOrderList.isEmpty()) { 1471 ArrayList neworders = new ArrayList(); 1472 ArrayList orders = ((FLWRExpression) expression).getOrderBy(); 1473 boolean doit = false; 1474 if (orders != null) 1475 for (int i = 0; i < orders.size(); i++) { 1476 Variable tmpvar = null; 1477 XQueryExpression tmpexpr = null; 1478 if (orders.get(i) instanceof Variable) { 1479 tmpvar = (Variable) orders.get(i); 1480 tmpexpr = tmpvar; 1481 } else { 1482 tmpexpr = (XQueryExpression) orders.get(i); 1483 tmpvar = (Variable) ((LocatedExpression) tmpexpr).getExpression(); 1484 } 1485 if (doit || varReOrderList.contains(tmpvar)) { 1486 if (!doit) 1487 doit = true; 1488 neworders.add(tmpexpr); 1489 } 1490 } 1491 if (!neworders.isEmpty()) 1492 operator = new OpSort(plan, operator, neworders); 1493 } 1494 if (!isQDB()) 1495 operator.isLet(islet); 1496 return operator; 1497 } 1498 1499 public Object clone() throws CloneNotSupportedException { 1500 AlgFLWR newobj = (AlgFLWR) super.clone(); 1501 newobj.parentDepFLWR = parentDepFLWR; 1502 if (subDepFLWRs == null) 1503 newobj.subDepFLWRs = null; 1504 else { 1505 newobj.subDepFLWRs = new ArrayList(); 1506 for (int i = 0; i < subDepFLWRs.size(); i++) 1507 newobj.subDepFLWRs.add(((AlgFLWR) subDepFLWRs.get(i)).clone()); 1508 } 1509 return newobj; 1510 } 1512 1518 public ArrayList getPaths() { 1519 if (paths == null) 1520 paths = new ArrayList(); 1521 if (paths.isEmpty()) { 1522 if (algChildren != null) { 1523 for (int i = 0; i < algChildren.size(); i++) { 1524 ArrayList tmplist = ((Algebra) algChildren.get(i)).getPaths(); 1525 if (tmplist != null) 1526 paths.addAll(tmplist); 1527 } 1528 } 1529 if (subDepFLWRs != null) { 1530 for (int i = 0; i < subDepFLWRs.size(); i++) { 1531 ArrayList tmplist = ((AlgFLWR) subDepFLWRs.get(i)).getPaths(); 1532 if (tmplist != null) 1533 paths.addAll(tmplist); 1534 } 1535 } 1536 } 1537 return paths; 1538 } 1539 1540 1543 1544 public ArrayList getAllVariables() { 1545 ArrayList res = (ArrayList) ((FLWRExpression) expression).getVariables().clone(); 1546 if (subDepFLWRs != null) 1547 for (int i = 0; i < subDepFLWRs.size(); i++) 1548 res.addAll(((AlgFLWR) subDepFLWRs.get(i)).getAllVariables()); 1549 return res; 1550 } 1551 1552 public AlgFLWR getParentDepFLWR() { 1553 return parentDepFLWR; 1554 } 1555 1556 public ArrayList getAllOrderBys() { 1557 ArrayList parentres = ((FLWRExpression) expression).getOrderBy(); 1558 if (subDepFLWRs == null) 1559 return parentres; 1560 ArrayList res = new ArrayList(); 1561 for (int i = 0; i < subDepFLWRs.size(); i++) { 1562 ArrayList tmpres = ((AlgFLWR) subDepFLWRs.get(i)).getAllOrderBys(); 1563 if (tmpres != null) { 1564 res.addAll(tmpres); 1565 if (parentres != null) 1566 res.removeAll(parentres); 1567 } 1568 } 1569 if (parentres != null) 1570 res.addAll(0, parentres); 1571 if (res.isEmpty()) 1572 return null; 1573 return res; 1574 } 1576 public String toCompleteString() { 1579 return toCompleteString(0); 1580 } 1581 1582 public String toCompleteString(int indent) { 1583 StringBuffer buf = new StringBuffer (); 1584 buf.append(Utils.makeIndent(indent) + "<" + getClass().getName() + ">\n"); 1585 buf.append(Utils.makeIndent(indent + 1) + "<variables> " + variables + " </variables>\n"); 1586 buf.append(Utils.makeIndent(indent + 1) + "<sources> " + getSources() + " </sources>\n"); 1587 buf.append(Utils.makeIndent(indent + 1) + "<isLet> " + islet + " </isLet>\n"); 1588 buf.append(Utils.makeIndent(indent + 1) + "<monosource> " + isMonoSource() + " </monosource>\n"); 1589 buf.append(Utils.makeIndent(indent + 1) + "<hasIdentifier> " + hasIdentifier + " </hasIdentifier>\n"); 1590 if (hinttree != null) { 1591 buf.append(Utils.makeIndent(indent + 1) + "<HintTree>\n"); 1592 buf.append(Utils.makeIndent(indent + 2) + hinttree.toString() + "\n"); 1593 buf.append(Utils.makeIndent(indent + 1) + "</HintTree>\n"); 1594 } 1595 buf.append(Utils.makeIndent(indent + 1) + "<Expression type=\"" + expression.getClass() + "\">\n"); 1596 buf.append(Utils.makeIndent(indent + 2) + expression + "\n"); 1597 buf.append(Utils.makeIndent(indent + 1) + "</Expression>\n"); 1598 if (algChildren != null && !algChildren.isEmpty()) { 1599 buf.append(Utils.makeIndent(indent + 1) + "<Leaves>\n"); 1600 for (int i = 0; i < algChildren.size(); i++) { 1601 buf.append(Utils.makeIndent(indent + 2) + "<Leave>\n"); 1602 Algebra depchild = (Algebra) algChildren.get(i); 1603 buf.append(depchild.toCompleteString(indent + 3)); 1604 buf.append(Utils.makeIndent(indent + 2) + "</Leave>\n"); 1605 } 1606 buf.append(Utils.makeIndent(indent + 1) + "</Leaves>\n"); 1607 } 1608 if (referenceDefinitionVars != null && !referenceDefinitionVars.isEmpty()) { 1609 buf.append(Utils.makeIndent(indent + 1) + "<referenceDefinitionVars>\n"); 1610 for (int i = 0; i < referenceDefinitionVars.size(); i++) { 1611 buf.append(Utils.makeIndent(indent + 2) + "<Variables>" + referenceDefinitionVars.get(i) + "</Variables>\n"); 1612 } 1613 buf.append(Utils.makeIndent(indent + 1) + "</referenceDefinitionVars>\n"); 1614 } 1615 if (dependDefinitionVars != null && !dependDefinitionVars.isEmpty()) { 1616 buf.append(Utils.makeIndent(indent + 1) + "<dependDefinitionVars>\n"); 1617 for (int i = 0; i < dependDefinitionVars.size(); i++) { 1618 buf.append(Utils.makeIndent(indent + 2) + "<Variables>" + dependDefinitionVars.get(i) + "</Variables>\n"); 1619 } 1620 buf.append(Utils.makeIndent(indent + 1) + "</dependDefinitionVars>\n"); 1621 } 1622 if (paths != null && !paths.isEmpty()) { 1623 buf.append(Utils.makeIndent(indent + 1) + "<Paths>\n"); 1624 for (int i = 0; i < paths.size(); i++) 1625 buf.append(Utils.makeIndent(indent + 2) + "<Path>" + paths.get(i) + "</Path>\n"); 1626 buf.append(Utils.makeIndent(indent + 1) + "</Paths>\n"); 1627 } 1628 if (subDepFLWRs != null) { 1629 buf.append(Utils.makeIndent(indent + 1) + "<subDepFLWRs>\n"); 1630 for (int i = 0; i < subDepFLWRs.size(); i++) 1631 buf.append(Utils.makeIndent(indent + 2) + "<depmem>" + ((AlgFLWR) subDepFLWRs.get(i)).getVariables() + "</depmem>\n"); 1632 buf.append(Utils.makeIndent(indent + 1) + "</subDepFLWRs>\n"); 1633 } 1634 buf.append(Utils.makeIndent(indent) + "</" + getClass().getName() + ">\n"); 1635 return buf.toString(); 1636 } 1637 1638 public void execute(ExecutionPlan plan) throws MediatorException { 1639 } 1640 1641} | Popular Tags |