1 21 22 package org.apache.derby.impl.sql.compile; 23 24 import org.apache.derby.iapi.services.sanity.SanityManager; 25 26 import org.apache.derby.iapi.error.StandardException; 27 28 import org.apache.derby.iapi.sql.compile.AccessPath; 29 import org.apache.derby.iapi.sql.compile.C_NodeTypes; 30 import org.apache.derby.iapi.sql.compile.CostEstimate; 31 import org.apache.derby.iapi.sql.compile.Optimizable; 32 import org.apache.derby.iapi.sql.compile.OptimizablePredicate; 33 import org.apache.derby.iapi.sql.compile.OptimizablePredicateList; 34 35 import org.apache.derby.iapi.sql.dictionary.DataDictionary; 36 import org.apache.derby.iapi.sql.dictionary.TableDescriptor; 37 38 import org.apache.derby.iapi.reference.SQLState; 39 import org.apache.derby.iapi.types.DataTypeDescriptor; 40 41 import org.apache.derby.iapi.util.JBitSet; 42 43 import java.util.HashMap ; 44 45 54 55 abstract class SetOperatorNode extends TableOperatorNode 56 { 57 61 boolean all; 62 63 OrderByList orderByList; 64 65 private PredicateList leftOptPredicates; 67 private PredicateList rightOptPredicates; 68 69 private PredicateList pushedPredicates; 72 73 private HashMap leftScopedPreds; 76 private HashMap rightScopedPreds; 77 78 88 89 public void init( 90 Object leftResult, 91 Object rightResult, 92 Object all, 93 Object tableProperties) 94 throws StandardException 95 { 96 super.init(leftResult, rightResult, tableProperties); 97 98 this.all = ((Boolean ) all).booleanValue(); 99 100 105 resultColumns = leftResultSet.getResultColumns().copyListAndObjects(); 106 } 107 108 113 public Optimizable modifyAccessPath(JBitSet outerTables, 114 PredicateList predList) throws StandardException 115 { 116 if ((predList != null) && 126 !getTrulyTheBestAccessPath().getJoinStrategy().isHashJoin()) 127 { 128 for (int i = predList.size() - 1; i >= 0; i--) 129 if (pushOptPredicate(predList.getOptPredicate(i))) 130 predList.removeOptPredicate(i); 131 } 132 133 166 167 CostEstimate ce = getFinalCostEstimate(); 170 171 ResultSetNode topNode = (ResultSetNode)modifyAccessPath(outerTables); 173 174 181 if (hasUnPushedPredicates()) 182 { 183 ResultSetNode prnRSN = (ResultSetNode) getNodeFactory().getNode( 189 C_NodeTypes.PROJECT_RESTRICT_NODE, 190 topNode, topNode.getResultColumns(), null, pushedPredicates, null, null, null, getContextManager()); 198 prnRSN.costEstimate = ce.cloneMe(); 199 prnRSN.setReferencedTableMap(topNode.getReferencedTableMap()); 200 topNode = prnRSN; 201 } 202 203 return (Optimizable)topNode; 204 } 205 206 256 public boolean pushOptPredicate(OptimizablePredicate optimizablePredicate) 257 throws StandardException 258 { 259 if (!(this instanceof UnionNode)) 264 return false; 265 266 Predicate pred = (Predicate)optimizablePredicate; 269 if (!pred.pushableToSubqueries()) 270 return false; 271 272 boolean canPush = false; 276 277 JBitSet tableNums = new JBitSet(getReferencedTableMap().size()); 278 BaseTableNumbersVisitor btnVis = 279 new BaseTableNumbersVisitor(tableNums); 280 281 leftResultSet.accept(btnVis); 283 canPush = (tableNums.getFirstSetBit() != -1); 284 285 298 if (!canPush) 299 return false; 300 301 tableNums.clearAll(); 303 rightResultSet.accept(btnVis); 304 canPush = (tableNums.getFirstSetBit() != -1); 305 if (!canPush) 306 return false; 307 308 tableNums.clearAll(); 316 this.accept(btnVis); 317 318 334 335 int [] whichRC = new int[] { -1 }; 338 339 Predicate scopedPred = null; 342 if (leftScopedPreds == null) 343 leftScopedPreds = new HashMap (); 344 else 345 scopedPred = (Predicate)leftScopedPreds.get(pred); 346 if (scopedPred == null) 347 { 348 scopedPred = pred.getPredScopedForResultSet( 349 tableNums, leftResultSet, whichRC); 350 leftScopedPreds.put(pred, scopedPred); 351 } 352 353 getLeftOptPredicateList().addOptPredicate(scopedPred); 355 356 scopedPred = null; 357 if (rightScopedPreds == null) 358 rightScopedPreds = new HashMap (); 359 else 360 scopedPred = (Predicate)rightScopedPreds.get(pred); 361 if (scopedPred == null) 362 { 363 scopedPred = pred.getPredScopedForResultSet( 364 tableNums, rightResultSet, whichRC); 365 rightScopedPreds.put(pred, scopedPred); 366 } 367 368 getRightOptPredicateList().addOptPredicate(scopedPred); 370 371 if (pushedPredicates == null) 378 pushedPredicates = new PredicateList(); 379 380 pushedPredicates.addOptPredicate(pred); 381 return true; 382 } 383 384 389 public void pullOptPredicates( 390 OptimizablePredicateList optimizablePredicates) 391 throws StandardException 392 { 393 if (pushedPredicates == null) 394 return; 396 397 407 if (leftOptPredicates != null) 408 leftOptPredicates.removeAllElements(); 409 410 if (rightOptPredicates != null) 411 rightOptPredicates.removeAllElements(); 412 413 424 Predicate pred = null; 425 RemapCRsVisitor rcrv = new RemapCRsVisitor(false); 426 for (int i = 0; i < pushedPredicates.size(); i++) 427 { 428 pred = (Predicate)pushedPredicates.getOptPredicate(i); 429 if (pred.isScopedForPush()) 430 { 431 438 pred.getAndNode().accept(rcrv); 439 continue; 440 } 441 optimizablePredicates.addOptPredicate(pred); 442 } 443 444 pushedPredicates.removeAllElements(); 447 } 448 449 465 protected boolean hasUnPushedPredicates() 466 { 467 if (((leftOptPredicates != null) && (leftOptPredicates.size() > 0)) || 469 ((rightOptPredicates != null) && (rightOptPredicates.size() > 0))) 470 { 471 return true; 472 } 473 474 if ((leftResultSet instanceof SetOperatorNode) && 476 ((SetOperatorNode)leftResultSet).hasUnPushedPredicates()) 477 { 478 return true; 479 } 480 481 return ((rightResultSet instanceof SetOperatorNode) && 482 ((SetOperatorNode)rightResultSet).hasUnPushedPredicates()); 483 } 484 485 491 492 public String toString() 493 { 494 if (SanityManager.DEBUG) 495 { 496 return "all: " + all + "\n" + 497 "orderByList: " + 498 (orderByList != null ? orderByList.toString() : "null") + "\n" + 499 super.toString(); 500 } 501 else 502 { 503 return ""; 504 } 505 } 506 507 517 public void bindResultColumns(FromList fromListParam) 518 throws StandardException 519 { 520 super.bindResultColumns(fromListParam); 521 522 523 buildRCL(); 524 } 525 526 552 553 public void bindResultColumns(TableDescriptor targetTableDescriptor, 554 FromVTI targetVTI, 555 ResultColumnList targetColumnList, 556 DMLStatementNode statement, 557 FromList fromListParam) 558 throws StandardException 559 { 560 super.bindResultColumns(targetTableDescriptor, 561 targetVTI, 562 targetColumnList, statement, 563 fromListParam); 564 565 566 buildRCL(); 567 } 568 569 575 576 private void buildRCL() throws StandardException 577 { 578 581 if (leftResultSet.getResultColumns().size() != 582 rightResultSet.getResultColumns().size()) 583 { 584 throw StandardException.newException(SQLState.LANG_UNION_UNMATCHED_COLUMNS, 585 getOperatorName()); 586 } 587 588 591 resultColumns = leftResultSet.getResultColumns().copyListAndObjects(); 592 593 596 resultColumns.setUnionResultExpression(rightResultSet.getResultColumns(), tableNumber, level, getOperatorName()); 597 } 598 599 608 public void bindUntypedNullsToResultColumns(ResultColumnList rcl) 609 throws StandardException 610 { 611 617 if (rcl == null) 618 { 619 ResultColumnList lrcl = rightResultSet.getResultColumns(); 620 ResultColumnList rrcl = leftResultSet.getResultColumns(); 621 622 leftResultSet.bindUntypedNullsToResultColumns(rrcl); 623 rightResultSet.bindUntypedNullsToResultColumns(lrcl); 624 } 625 else 626 { 627 leftResultSet.bindUntypedNullsToResultColumns(rcl); 628 rightResultSet.bindUntypedNullsToResultColumns(rcl); 629 } 630 } 631 632 642 int getParamColumnTypes(DataTypeDescriptor[] types, RowResultSetNode rrsn) 643 throws StandardException 644 { 645 int numTypes = 0; 646 647 648 for (int i = 0; i < types.length; i++) 649 { 650 if (types[i] == null) 651 { 652 ResultColumn rc = 653 (ResultColumn) rrsn.getResultColumns().elementAt(i); 654 if ( ! (rc.getExpression().requiresTypeFromContext())) 655 { 656 types[i] = rc.getExpressionType(); 657 numTypes++; 658 } 659 } 660 } 661 662 return numTypes; 663 } 664 665 676 void setParamColumnTypes(DataTypeDescriptor[] types, RowResultSetNode rrsn) 677 throws StandardException 678 { 679 683 ResultColumnList rrcl = rrsn.getResultColumns(); 684 int rrclSize = rrcl.size(); 685 for (int index = 0; index < rrclSize; index++) 686 { 687 ResultColumn rc = (ResultColumn) rrcl.elementAt(index); 688 689 if (rc.getExpression().requiresTypeFromContext()) 690 { 691 695 rc.getExpression().setType(types[index]); 696 } 697 } 698 } 699 700 709 710 public void bindTargetExpressions(FromList fromListParam) 711 throws StandardException 712 { 713 leftResultSet.bindTargetExpressions(fromListParam); 714 rightResultSet.bindTargetExpressions(fromListParam); 715 } 716 717 725 void pushOrderByList(OrderByList orderByList) 726 { 727 this.orderByList = orderByList; 728 } 729 730 754 755 public ResultSetNode preprocess(int numTables, 756 GroupByList gbl, 757 FromList fromList) 758 throws StandardException 759 { 760 ResultSetNode newTop = this; 761 762 763 leftResultSet = leftResultSet.preprocess(numTables, gbl, fromList); 764 rightResultSet = rightResultSet.preprocess(numTables, gbl, fromList); 765 766 767 referencedTableMap = (JBitSet) leftResultSet.getReferencedTableMap().clone(); 768 referencedTableMap.or((JBitSet) rightResultSet.getReferencedTableMap()); 769 770 785 if ((! all) && orderByList != null && orderByList.allAscending()) 786 { 787 790 if (orderByList.isInOrderPrefix(resultColumns)) 791 { 792 orderByList = null; 793 } 794 806 } 807 808 return newTop; 809 } 810 811 819 public ResultSetNode ensurePredicateList(int numTables) 820 throws StandardException 821 { 822 return genProjectRestrict(numTables); 823 } 824 825 833 public void verifySelectStarSubquery(FromList outerFromList, int subqueryType) 834 throws StandardException 835 { 836 837 leftResultSet.verifySelectStarSubquery(outerFromList, subqueryType); 838 rightResultSet.verifySelectStarSubquery(outerFromList, subqueryType); 839 } 840 841 854 protected FromTable getFromTableByName(String name, String schemaName, boolean exactMatch) 855 throws StandardException 856 { 857 860 return leftResultSet.getFromTableByName(name, schemaName, exactMatch); 861 } 862 863 878 public void setResultToBooleanTrueNode(boolean onlyConvertAlls) 879 throws StandardException 880 { 881 super.setResultToBooleanTrueNode(onlyConvertAlls); 882 leftResultSet.setResultToBooleanTrueNode(onlyConvertAlls); 883 rightResultSet.setResultToBooleanTrueNode(onlyConvertAlls); 884 } 885 886 907 public ResultSetNode enhanceRCLForInsert(int numTargetColumns, int[] colMap, 908 DataDictionary dataDictionary, 909 TableDescriptor targetTD, 910 FromVTI targetVTI) 911 throws StandardException 912 { 913 ResultColumnList newResultCols = 915 (ResultColumnList) getNodeFactory().getNode( 916 C_NodeTypes.RESULT_COLUMN_LIST, 917 getContextManager()); 918 int numResultSetColumns = resultColumns.size(); 919 920 924 for (int index = 0; index < numTargetColumns; index++) 925 { 926 ResultColumn newResultColumn; 927 ResultColumn oldResultColumn; 928 ColumnReference newColumnReference; 929 930 if (colMap[index] != -1) 931 { 932 oldResultColumn = resultColumns.getResultColumn(colMap[index]+1); 934 935 newColumnReference = (ColumnReference) getNodeFactory().getNode( 936 C_NodeTypes.COLUMN_REFERENCE, 937 oldResultColumn.getName(), 938 null, 939 getContextManager()); 940 941 newColumnReference.setSource(oldResultColumn); 942 newColumnReference.setType(oldResultColumn.getExpressionType()); 944 945 newColumnReference.setNestingLevel(0); 947 newColumnReference.setSourceLevel(0); 948 949 newResultColumn = (ResultColumn) getNodeFactory().getNode( 954 C_NodeTypes.RESULT_COLUMN, 955 oldResultColumn.getType(), 956 newColumnReference, 957 getContextManager()); 958 } 959 else 960 { 961 newResultColumn = genNewRCForInsert(targetTD, targetVTI, index + 1, dataDictionary); 962 } 963 964 newResultCols.addResultColumn(newResultColumn); 965 } 966 967 976 return (ResultSetNode) getNodeFactory().getNode( 977 C_NodeTypes.PROJECT_RESTRICT_NODE, 978 this, 979 newResultCols, 980 null, 981 null, 982 null, 983 null, 984 tableProperties, 985 getContextManager()); 986 } 987 988 1000 public boolean flattenableInFromSubquery(FromList fromList) 1001 { 1002 1003 return false; 1004 } 1005 1006 1014 public boolean performMaterialization(JBitSet outerTables) 1015 throws StandardException 1016 { 1017 return false; 1019 1020 1024 } 1026 1027 1030 abstract String getOperatorName(); 1031 1032 1037 PredicateList getLeftOptPredicateList() 1038 throws StandardException 1039 { 1040 if (leftOptPredicates == null) { 1041 leftOptPredicates = 1042 (PredicateList) getNodeFactory().getNode( 1043 C_NodeTypes.PREDICATE_LIST, 1044 getContextManager()); 1045 } 1046 1047 return leftOptPredicates; 1048 } 1049 1050 1055 PredicateList getRightOptPredicateList() 1056 throws StandardException 1057 { 1058 if (rightOptPredicates == null) { 1059 rightOptPredicates = 1060 (PredicateList) getNodeFactory().getNode( 1061 C_NodeTypes.PREDICATE_LIST, 1062 getContextManager()); 1063 } 1064 1065 return rightOptPredicates; 1066 } 1067 1068} 1069 | Popular Tags |