1 21 22 package org.apache.derby.impl.sql.compile; 23 24 import org.apache.derby.iapi.services.context.ContextManager; 25 26 import org.apache.derby.iapi.services.sanity.SanityManager; 27 28 import org.apache.derby.iapi.error.StandardException; 29 30 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; 31 import org.apache.derby.iapi.sql.compile.CompilerContext; 32 import org.apache.derby.iapi.sql.compile.Optimizable; 33 import org.apache.derby.iapi.sql.compile.Visitable; 34 import org.apache.derby.iapi.sql.compile.Visitor; 35 import org.apache.derby.iapi.sql.compile.Optimizer; 36 import org.apache.derby.iapi.sql.compile.OptimizableList; 37 import org.apache.derby.iapi.sql.compile.CostEstimate; 38 import org.apache.derby.iapi.sql.compile.OptimizerFactory; 39 import org.apache.derby.iapi.sql.compile.RequiredRowOrdering; 40 import org.apache.derby.iapi.sql.compile.C_NodeTypes; 41 42 import org.apache.derby.iapi.sql.dictionary.DataDictionary; 43 import org.apache.derby.iapi.sql.dictionary.TableDescriptor; 44 45 import org.apache.derby.iapi.util.JBitSet; 46 47 import java.util.Properties ; 48 49 60 61 abstract class TableOperatorNode extends FromTable 62 { 63 ResultSetNode leftResultSet; 64 ResultSetNode rightResultSet; 65 Optimizer leftOptimizer; 66 Optimizer rightOptimizer; 67 private boolean leftModifyAccessPathsDone; 68 private boolean rightModifyAccessPathsDone; 69 70 79 public void init(Object leftResultSet, 80 Object rightResultSet, 81 Object tableProperties) 82 throws StandardException 83 { 84 85 init(null, tableProperties); 86 this.leftResultSet = (ResultSetNode) leftResultSet; 87 this.rightResultSet = (ResultSetNode) rightResultSet; 88 } 89 90 95 public Optimizable modifyAccessPath(JBitSet outerTables) throws StandardException 96 { 97 boolean callModifyAccessPaths = false; 98 99 if (leftResultSet instanceof FromTable) 100 { 101 if (leftOptimizer != null) 102 leftOptimizer.modifyAccessPaths(); 103 else 104 { 105 leftResultSet = 106 (ResultSetNode) 107 ((FromTable) leftResultSet).modifyAccessPath(outerTables); 108 } 109 leftModifyAccessPathsDone = true; 110 } 111 else 112 { 113 callModifyAccessPaths = true; 114 } 115 116 if (rightResultSet instanceof FromTable) 117 { 118 if (rightOptimizer != null) 119 rightOptimizer.modifyAccessPaths(); 120 else 121 { 122 rightResultSet = 123 (ResultSetNode) 124 ((FromTable) rightResultSet).modifyAccessPath(outerTables); 125 } 126 rightModifyAccessPathsDone = true; 127 } 128 else 129 { 130 callModifyAccessPaths = true; 131 } 132 133 if (callModifyAccessPaths) 134 { 135 return (Optimizable) modifyAccessPaths(); 136 } 137 return this; 138 } 139 140 143 public void verifyProperties(DataDictionary dDictionary) 144 throws StandardException 145 { 146 if (leftResultSet instanceof Optimizable) 147 { 148 ((Optimizable) leftResultSet).verifyProperties(dDictionary); 149 } 150 if (rightResultSet instanceof Optimizable) 151 { 152 ((Optimizable) rightResultSet).verifyProperties(dDictionary); 153 } 154 155 super.verifyProperties(dDictionary); 156 } 157 158 166 public void updateBestPlanMap(short action, 167 Object planKey) throws StandardException 168 { 169 super.updateBestPlanMap(action, planKey); 170 171 177 if (leftResultSet instanceof Optimizable) 178 { 179 ((Optimizable)leftResultSet). 180 updateBestPlanMap(action, planKey); 181 } 182 else if (leftResultSet.getOptimizerImpl() != null) 183 { 184 leftResultSet.getOptimizerImpl(). 185 updateBestPlanMaps(action, planKey); 186 } 187 188 if (rightResultSet instanceof Optimizable) 189 { 190 ((Optimizable)rightResultSet). 191 updateBestPlanMap(action, planKey); 192 } 193 else if (rightResultSet.getOptimizerImpl() != null) 194 { 195 rightResultSet.getOptimizerImpl(). 196 updateBestPlanMaps(action, planKey); 197 } 198 } 199 200 206 207 public String toString() 208 { 209 if (SanityManager.DEBUG) 210 { 211 return "nestedInParens: " + false + "\n" + 212 leftResultSet.toString() + "\n" + 213 rightResultSet.toString() + "\n" + 214 super.toString(); 215 } 216 else 217 { 218 return ""; 219 } 220 } 221 222 228 229 public void printSubNodes(int depth) 230 { 231 if (SanityManager.DEBUG) 232 { 233 super.printSubNodes(depth); 234 235 if (leftResultSet != null) 236 { 237 printLabel(depth, "leftResultSet: "); 238 leftResultSet.printSubNodes(depth + 1); 239 } 240 241 if (rightResultSet != null) 242 { 243 printLabel(depth, "rightResultSet: "); 244 rightResultSet.printSubNodes(depth + 1); 245 } 246 } 247 } 248 249 254 public ResultSetNode getLeftResultSet() 255 { 256 return leftResultSet; 257 } 258 259 264 public ResultSetNode getRightResultSet() 265 { 266 return rightResultSet; 267 } 268 269 public ResultSetNode getLeftmostResultSet() 270 { 271 if (leftResultSet instanceof TableOperatorNode) 272 { 273 return ((TableOperatorNode) leftResultSet).getLeftmostResultSet(); 274 } 275 else 276 { 277 return leftResultSet; 278 } 279 } 280 281 public void setLeftmostResultSet(ResultSetNode newLeftResultSet) 282 { 283 if (leftResultSet instanceof TableOperatorNode) 284 { 285 ((TableOperatorNode) leftResultSet).setLeftmostResultSet(newLeftResultSet); 286 } 287 else 288 { 289 this.leftResultSet = newLeftResultSet; 290 } 291 } 292 293 298 public void setLevel(int level) 299 { 300 super.setLevel(level); 301 if (leftResultSet instanceof FromTable) 302 { 303 ((FromTable) leftResultSet).setLevel(level); 304 } 305 if (rightResultSet instanceof FromTable) 306 { 307 ((FromTable) rightResultSet).setLevel(level); 308 } 309 } 310 311 317 318 public String getExposedName() 319 { 320 return null; 321 } 322 323 333 public void setNestedInParens(boolean nestedInParens) 334 { 335 } 336 337 338 352 353 public ResultSetNode bindNonVTITables(DataDictionary dataDictionary, 354 FromList fromListParam) 355 throws StandardException 356 { 357 leftResultSet = leftResultSet.bindNonVTITables(dataDictionary, fromListParam); 358 rightResultSet = rightResultSet.bindNonVTITables(dataDictionary, fromListParam); 359 360 if (tableNumber == -1) tableNumber = getCompilerContext().getNextTableNumber(); 362 363 return this; 364 } 365 366 379 380 public ResultSetNode bindVTITables(FromList fromListParam) 381 throws StandardException 382 { 383 leftResultSet = leftResultSet.bindVTITables(fromListParam); 384 rightResultSet = rightResultSet.bindVTITables(fromListParam); 385 386 return this; 387 } 388 389 396 397 public void bindExpressions(FromList fromListParam) 398 throws StandardException 399 { 400 404 if ( ! (this instanceof UnionNode) || 405 ! ((UnionNode) this).tableConstructor()) 406 { 407 leftResultSet.rejectParameters(); 408 rightResultSet.rejectParameters(); 409 } 410 411 leftResultSet.bindExpressions(fromListParam); 412 rightResultSet.bindExpressions(fromListParam); 413 } 414 415 423 424 public void rejectParameters() throws StandardException 425 { 426 leftResultSet.rejectParameters(); 427 rightResultSet.rejectParameters(); 428 } 429 430 439 public void bindExpressionsWithTables(FromList fromListParam) 440 throws StandardException 441 { 442 446 if ( ! (this instanceof UnionNode) || 447 ! ((UnionNode) this).tableConstructor()) 448 { 449 leftResultSet.rejectParameters(); 450 rightResultSet.rejectParameters(); 451 } 452 453 leftResultSet.bindExpressionsWithTables(fromListParam); 454 rightResultSet.bindExpressionsWithTables(fromListParam); 455 } 456 457 467 public void bindResultColumns(FromList fromListParam) 468 throws StandardException 469 { 470 leftResultSet.bindResultColumns(fromListParam); 471 rightResultSet.bindResultColumns(fromListParam); 472 } 473 474 500 501 public void bindResultColumns(TableDescriptor targetTableDescriptor, 502 FromVTI targetVTI, 503 ResultColumnList targetColumnList, 504 DMLStatementNode statement, 505 FromList fromListParam) 506 throws StandardException 507 { 508 leftResultSet.bindResultColumns(targetTableDescriptor, 509 targetVTI, 510 targetColumnList, 511 statement, fromListParam); 512 rightResultSet.bindResultColumns(targetTableDescriptor, 513 targetVTI, 514 targetColumnList, 515 statement, fromListParam); 516 } 517 518 531 protected FromTable getFromTableByName(String name, String schemaName, boolean exactMatch) 532 throws StandardException 533 { 534 FromTable result = leftResultSet.getFromTableByName(name, schemaName, exactMatch); 535 536 539 if (result == null) 540 { 541 result = rightResultSet.getFromTableByName(name, schemaName, exactMatch); 542 } 543 return result; 544 } 545 546 570 571 public ResultSetNode preprocess(int numTables, 572 GroupByList gbl, 573 FromList fromList) 574 throws StandardException 575 { 576 leftResultSet = leftResultSet.preprocess(numTables, gbl, fromList); 577 581 if (leftResultSet instanceof FromSubquery) 582 { 583 leftResultSet = ((FromSubquery) leftResultSet).extractSubquery(numTables); 584 } 585 rightResultSet = rightResultSet.preprocess(numTables, gbl, fromList); 586 590 if (rightResultSet instanceof FromSubquery) 591 { 592 rightResultSet = ((FromSubquery) rightResultSet).extractSubquery(numTables); 593 } 594 595 596 referencedTableMap = (JBitSet) leftResultSet.getReferencedTableMap().clone(); 597 referencedTableMap.or((JBitSet) rightResultSet.getReferencedTableMap()); 598 referencedTableMap.set(tableNumber); 599 600 601 if (isFlattenableJoinNode()) 602 { 603 return this; 604 } 605 else 606 { 607 613 projectResultColumns(); 614 return genProjectRestrict(numTables); 615 } 616 } 617 618 622 void projectResultColumns() throws StandardException 623 { 624 resultColumns.doProjection(); 625 } 626 627 630 void setReferencedColumns() 631 {} 632 633 643 public ResultSetNode optimize(DataDictionary dataDictionary, 644 PredicateList predicateList, 645 double outerRows) 646 throws StandardException 647 { 648 649 Optimizer optimizer = 650 getOptimizer( 651 (FromList) getNodeFactory().getNode( 652 C_NodeTypes.FROM_LIST, 653 getNodeFactory().doJoinOrderOptimization(), 654 this, 655 getContextManager()), 656 predicateList, 657 dataDictionary, 658 (RequiredRowOrdering) null); 659 660 costEstimate = optimizer.newCostEstimate(); 661 662 663 leftResultSet = leftResultSet.optimize( 664 dataDictionary, 665 predicateList, 666 outerRows); 667 rightResultSet = rightResultSet.optimize( 668 dataDictionary, 669 predicateList, 670 outerRows); 671 672 673 costEstimate.setCost(leftResultSet.getCostEstimate().getEstimatedCost(), 674 leftResultSet.getCostEstimate().rowCount(), 675 leftResultSet.getCostEstimate().singleScanRowCount() + 676 rightResultSet.getCostEstimate().singleScanRowCount()); 677 678 costEstimate.add(rightResultSet.costEstimate, costEstimate); 679 680 return this; 681 } 682 683 688 public ResultSetNode modifyAccessPaths() throws StandardException 689 { 690 694 if (!leftModifyAccessPathsDone) 695 { 696 if (leftOptimizer != null) 697 leftOptimizer.modifyAccessPaths(); 698 else 699 { 700 if (this instanceof SetOperatorNode) 706 { 707 SetOperatorNode setOp = (SetOperatorNode)this; 708 leftResultSet = leftResultSet.modifyAccessPaths( 709 setOp.getLeftOptPredicateList()); 710 } 711 else 712 leftResultSet = leftResultSet.modifyAccessPaths(); 713 } 714 } 715 if (!rightModifyAccessPathsDone) 716 { 717 if (rightOptimizer != null) 718 rightOptimizer.modifyAccessPaths(); 719 else 720 { 721 if (this instanceof SetOperatorNode) { 722 SetOperatorNode setOp = (SetOperatorNode)this; 723 rightResultSet = rightResultSet.modifyAccessPaths( 724 setOp.getRightOptPredicateList()); 725 } 726 else 727 rightResultSet = rightResultSet.modifyAccessPaths(); 728 } 729 } 730 return this; 731 } 732 733 743 public boolean referencesTarget(String name, boolean baseTable) 744 throws StandardException 745 { 746 return leftResultSet.referencesTarget(name, baseTable) || 747 rightResultSet.referencesTarget(name, baseTable); 748 } 749 750 757 public boolean referencesSessionSchema() 758 throws StandardException 759 { 760 return leftResultSet.referencesSessionSchema() || 761 rightResultSet.referencesSessionSchema(); 762 } 763 764 769 protected ResultSetNode optimizeSource( 770 Optimizer optimizer, 771 ResultSetNode sourceResultSet, 772 PredicateList predList, 773 CostEstimate outerCost) 774 throws StandardException 775 { 776 ResultSetNode retval; 777 778 if (sourceResultSet instanceof FromTable) 779 { 780 FromList optList = (FromList) getNodeFactory().getNode( 781 C_NodeTypes.FROM_LIST, 782 getNodeFactory().doJoinOrderOptimization(), 783 sourceResultSet, 784 getContextManager()); 785 786 787 if (predList == null) 788 predList = (PredicateList) getNodeFactory().getNode( 789 C_NodeTypes.PREDICATE_LIST, 790 getContextManager()); 791 792 LanguageConnectionContext lcc = getLanguageConnectionContext(); 793 OptimizerFactory optimizerFactory = lcc.getOptimizerFactory(); 794 optimizer = optimizerFactory.getOptimizer(optList, 795 predList, 796 getDataDictionary(), 797 (RequiredRowOrdering) null, 798 getCompilerContext().getNumTables(), 799 lcc); 800 optimizer.prepForNextRound(); 801 802 if (sourceResultSet == leftResultSet) 803 { 804 leftOptimizer = optimizer; 805 } 806 else if (sourceResultSet == rightResultSet) 807 { 808 rightOptimizer = optimizer; 809 } 810 else 811 { 812 if (SanityManager.DEBUG) 813 SanityManager.THROWASSERT("Result set being optimized is neither left nor right"); 814 } 815 816 820 optimizer.setOuterRows(outerCost.rowCount()); 821 822 823 while (optimizer.getNextPermutation()) 824 { 825 while (optimizer.getNextDecoratedPermutation()) 826 { 827 optimizer.costPermutation(); 828 } 829 } 830 831 retval = sourceResultSet; 832 } 833 else 834 { 835 retval = sourceResultSet.optimize( 836 optimizer.getDataDictionary(), 837 predList, 838 outerCost.rowCount()); 839 } 840 841 return retval; 842 } 843 844 851 void decrementLevel(int decrement) 852 { 853 leftResultSet.decrementLevel(decrement); 854 rightResultSet.decrementLevel(decrement); 855 } 856 857 865 void replaceDefaults(TableDescriptor ttd, ResultColumnList tcl) 866 throws StandardException 867 { 868 leftResultSet.replaceDefaults(ttd, tcl); 869 rightResultSet.replaceDefaults(ttd, tcl); 870 } 871 872 877 void markOrderingDependent() 878 { 879 leftResultSet.markOrderingDependent(); 880 rightResultSet.markOrderingDependent(); 881 } 882 883 891 public Visitable accept(Visitor v) 892 throws StandardException 893 { 894 if (v.skipChildren(this)) 895 { 896 return v.visit(this); 897 } 898 899 Visitable returnNode = super.accept(v); 900 901 if (leftResultSet != null && !v.stopTraversal()) 902 { 903 leftResultSet = (ResultSetNode)leftResultSet.accept(v); 904 } 905 if (rightResultSet != null && !v.stopTraversal()) 906 { 907 rightResultSet = (ResultSetNode)rightResultSet.accept(v); 908 } 909 return returnNode; 910 } 911 912 915 public boolean needsSpecialRCLBinding() 916 { 917 return true; 918 } 919 } 920 | Popular Tags |