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.sql.compile.Optimizable; 27 import org.apache.derby.iapi.sql.compile.OptimizablePredicate; 28 import org.apache.derby.iapi.sql.compile.OptimizablePredicateList; 29 import org.apache.derby.iapi.sql.compile.Optimizer; 30 import org.apache.derby.iapi.sql.compile.CostEstimate; 31 import org.apache.derby.iapi.sql.compile.JoinStrategy; 32 import org.apache.derby.iapi.sql.compile.AccessPath; 33 import org.apache.derby.iapi.sql.compile.RowOrdering; 34 import org.apache.derby.iapi.sql.compile.C_NodeTypes; 35 36 import org.apache.derby.iapi.sql.dictionary.*; 37 38 import org.apache.derby.iapi.types.DataTypeDescriptor; 39 40 import org.apache.derby.iapi.error.StandardException; 41 import org.apache.derby.iapi.services.sanity.SanityManager; 42 43 import org.apache.derby.iapi.reference.SQLState; 44 import org.apache.derby.iapi.error.StandardException; 45 46 import org.apache.derby.impl.sql.execute.HashScanResultSet; 47 48 import org.apache.derby.iapi.util.JBitSet; 49 import org.apache.derby.iapi.services.io.FormatableBitSet; 50 import org.apache.derby.iapi.util.StringUtil; 51 import org.apache.derby.catalog.UUID; 52 53 import java.util.Enumeration ; 54 import java.util.Properties ; 55 import java.util.Vector ; 56 import java.util.HashMap ; 57 58 68 abstract class FromTable extends ResultSetNode implements Optimizable 69 { 70 Properties tableProperties; 71 String correlationName; 72 TableName corrTableName; 73 int tableNumber; 74 75 78 int level; 79 int[] hashKeyColumns; 81 82 int initialCapacity = HashScanResultSet.DEFAULT_INITIAL_CAPACITY; 84 float loadFactor = HashScanResultSet.DEFAULT_LOADFACTOR; 85 int maxCapacity = HashScanResultSet.DEFAULT_MAX_CAPACITY; 86 87 AccessPathImpl currentAccessPath; 88 AccessPathImpl bestAccessPath; 89 AccessPathImpl bestSortAvoidancePath; 90 AccessPathImpl trulyTheBestAccessPath; 91 92 private int joinStrategyNumber; 93 94 protected String userSpecifiedJoinStrategy; 95 96 protected CostEstimate bestCostEstimate; 97 98 private FormatableBitSet refCols; 99 100 private double perRowUsage = -1; 101 102 private boolean considerSortAvoidancePath; 103 104 114 private HashMap bestPlanMap; 115 116 117 protected static final short REMOVE_PLAN = 0; 118 protected static final short ADD_PLAN = 1; 119 protected static final short LOAD_PLAN = 2; 120 121 122 protected TableName origTableName; 123 124 130 public void init(Object correlationName, Object tableProperties) 131 { 132 this.correlationName = (String ) correlationName; 133 this.tableProperties = (Properties ) tableProperties; 134 tableNumber = -1; 135 bestPlanMap = null; 136 } 137 138 141 public String getCorrelationName() { return correlationName; } 142 143 146 147 153 public CostEstimate optimizeIt( 154 Optimizer optimizer, 155 OptimizablePredicateList predList, 156 CostEstimate outerCost, 157 RowOrdering rowOrdering) 158 throws StandardException 159 { 160 updateBestPlanMap(ADD_PLAN, this); 171 172 CostEstimate singleScanCost = estimateCost(predList, 173 (ConglomerateDescriptor) null, 174 outerCost, 175 optimizer, 176 rowOrdering); 177 178 179 getCostEstimate(optimizer); 180 181 setCostEstimate(singleScanCost); 182 183 187 optimizeSubqueries(getDataDictionary(), costEstimate.rowCount()); 188 189 192 getCurrentAccessPath(). 193 getJoinStrategy(). 194 estimateCost( 195 this, 196 predList, 197 (ConglomerateDescriptor) null, 198 outerCost, 199 optimizer, 200 getCostEstimate() 201 ); 202 203 optimizer.considerCost(this, predList, getCostEstimate(), outerCost); 204 205 return getCostEstimate(); 206 } 207 208 212 public boolean nextAccessPath(Optimizer optimizer, 213 OptimizablePredicateList predList, 214 RowOrdering rowOrdering) 215 throws StandardException 216 { 217 int numStrat = optimizer.getNumberOfJoinStrategies(); 218 boolean found = false; 219 AccessPath ap = getCurrentAccessPath(); 220 221 225 if (userSpecifiedJoinStrategy != null) 226 { 227 232 if (ap.getJoinStrategy() != null) 233 { 234 ap.setJoinStrategy((JoinStrategy) null); 235 236 found = false; 237 } 238 else 239 { 240 ap.setJoinStrategy( 241 optimizer.getJoinStrategy(userSpecifiedJoinStrategy)); 242 243 if (ap.getJoinStrategy() == null) 244 { 245 throw StandardException.newException(SQLState.LANG_INVALID_JOIN_STRATEGY, 246 userSpecifiedJoinStrategy, getBaseTableName()); 247 } 248 249 found = true; 250 } 251 } 252 else if (joinStrategyNumber < numStrat) 253 { 254 255 ap.setJoinStrategy(optimizer.getJoinStrategy(joinStrategyNumber)); 256 257 joinStrategyNumber++; 258 259 found = true; 260 261 optimizer.trace(Optimizer.CONSIDERING_JOIN_STRATEGY, tableNumber, 0, 0.0, 262 ap.getJoinStrategy()); 263 } 264 265 269 tellRowOrderingAboutConstantColumns(rowOrdering, predList); 270 271 return found; 272 } 273 274 275 protected boolean canBeOrdered() 276 { 277 return false; 278 } 279 280 281 public AccessPath getCurrentAccessPath() 282 { 283 return currentAccessPath; 284 } 285 286 287 public AccessPath getBestAccessPath() 288 { 289 return bestAccessPath; 290 } 291 292 293 public AccessPath getBestSortAvoidancePath() 294 { 295 return bestSortAvoidancePath; 296 } 297 298 299 public AccessPath getTrulyTheBestAccessPath() 300 { 301 return trulyTheBestAccessPath; 302 } 303 304 305 public void rememberSortAvoidancePath() 306 { 307 considerSortAvoidancePath = true; 308 } 309 310 311 public boolean considerSortAvoidancePath() 312 { 313 return considerSortAvoidancePath; 314 } 315 316 317 public void rememberJoinStrategyAsBest(AccessPath ap) 318 { 319 Optimizer optimizer = ap.getOptimizer(); 320 321 ap.setJoinStrategy(getCurrentAccessPath().getJoinStrategy()); 322 323 optimizer.trace(Optimizer.REMEMBERING_JOIN_STRATEGY, tableNumber, 0, 0.0, 324 getCurrentAccessPath().getJoinStrategy()); 325 326 if (ap == bestAccessPath) 327 { 328 optimizer.trace(Optimizer.REMEMBERING_BEST_ACCESS_PATH_SUBSTRING, 329 tableNumber, 0, 0.0, ap); 330 } 331 else if (ap == bestSortAvoidancePath) 332 { 333 optimizer.trace(Optimizer.REMEMBERING_BEST_SORT_AVOIDANCE_ACCESS_PATH_SUBSTRING, 334 tableNumber, 0, 0.0, ap); 335 } 336 else 337 { 338 347 optimizer.trace(Optimizer.REMEMBERING_BEST_UNKNOWN_ACCESS_PATH_SUBSTRING, 348 tableNumber, 0, 0.0, ap); 349 } 350 } 351 352 353 public TableDescriptor getTableDescriptor() 354 { 355 if (SanityManager.DEBUG) 356 { 357 SanityManager.THROWASSERT( 358 "getTableDescriptor() not expected to be called for " 359 + getClass().toString()); 360 } 361 362 return null; 363 } 364 365 370 371 public boolean pushOptPredicate(OptimizablePredicate optimizablePredicate) 372 throws StandardException 373 { 374 return false; 375 } 376 377 382 public void pullOptPredicates( 383 OptimizablePredicateList optimizablePredicates) 384 throws StandardException 385 { 386 387 return; 388 } 389 390 395 public Optimizable modifyAccessPath(JBitSet outerTables) throws StandardException 396 { 397 398 return this; 399 } 400 401 405 public boolean isCoveringIndex(ConglomerateDescriptor cd) throws StandardException 406 { 407 return false; 408 } 409 410 411 public Properties getProperties() 412 { 413 return tableProperties; 414 } 415 416 417 public void setProperties(Properties tableProperties) 418 { 419 this.tableProperties = tableProperties; 420 } 421 422 425 public void verifyProperties(DataDictionary dDictionary) 426 throws StandardException 427 { 428 if (tableProperties == null) 429 { 430 return; 431 } 432 439 boolean indexSpecified = false; 440 Enumeration e = tableProperties.keys(); 441 while (e.hasMoreElements()) 442 { 443 String key = (String ) e.nextElement(); 444 String value = (String ) tableProperties.get(key); 445 446 if (key.equals("joinStrategy")) 447 { 448 userSpecifiedJoinStrategy = StringUtil.SQLToUpperCase(value); 449 } 450 else if (key.equals("hashInitialCapacity")) 451 { 452 initialCapacity = getIntProperty(value, key); 453 454 if (initialCapacity <= 0) 456 { 457 throw StandardException.newException(SQLState.LANG_INVALID_HASH_INITIAL_CAPACITY, 458 String.valueOf(initialCapacity)); 459 } 460 } 461 else if (key.equals("hashLoadFactor")) 462 { 463 try 464 { 465 loadFactor = Float.valueOf(value).floatValue(); 466 } 467 catch (NumberFormatException nfe) 468 { 469 throw StandardException.newException(SQLState.LANG_INVALID_NUMBER_FORMAT_FOR_OVERRIDE, 470 value, key); 471 } 472 473 if (loadFactor <= 0.0 || loadFactor > 1.0) 475 { 476 throw StandardException.newException(SQLState.LANG_INVALID_HASH_LOAD_FACTOR, 477 value); 478 } 479 } 480 else if (key.equals("hashMaxCapacity")) 481 { 482 maxCapacity = getIntProperty(value, key); 483 484 if (maxCapacity <= 0) 486 { 487 throw StandardException.newException(SQLState.LANG_INVALID_HASH_MAX_CAPACITY, 488 String.valueOf(maxCapacity)); 489 } 490 } 491 else 492 { 493 throw StandardException.newException(SQLState.LANG_INVALID_FROM_TABLE_PROPERTY, key, 495 "joinStrategy"); 496 } 497 } 498 } 499 500 503 public String getName() throws StandardException 504 { 505 return getExposedName(); 506 } 507 508 509 public String getBaseTableName() 510 { 511 return ""; 512 } 513 514 515 public int convertAbsoluteToRelativeColumnPosition(int absolutePosition) 516 { 517 return absolutePosition; 518 } 519 520 521 public void updateBestPlanMap(short action, 522 Object planKey) throws StandardException 523 { 524 if (action == REMOVE_PLAN) 525 { 526 if (bestPlanMap != null) 527 { 528 bestPlanMap.remove(planKey); 529 if (bestPlanMap.size() == 0) 530 bestPlanMap = null; 531 } 532 533 return; 534 } 535 536 AccessPath bestPath = getTrulyTheBestAccessPath(); 537 AccessPathImpl ap = null; 538 if (action == ADD_PLAN) 539 { 540 if (bestPath == null) 543 return; 544 545 if (bestPlanMap == null) 548 bestPlanMap = new HashMap (); 549 else 550 ap = (AccessPathImpl)bestPlanMap.get(planKey); 551 552 if (ap == null) 557 { 558 if (planKey instanceof Optimizer) 559 ap = new AccessPathImpl((Optimizer)planKey); 560 else 561 ap = new AccessPathImpl((Optimizer)null); 562 } 563 564 ap.copy(bestPath); 565 bestPlanMap.put(planKey, ap); 566 return; 567 } 568 569 572 if (bestPlanMap == null) 576 return; 577 578 ap = (AccessPathImpl)bestPlanMap.get(planKey); 579 580 if ((ap == null) || (ap.getCostEstimate() == null)) 583 return; 584 585 bestPath.copy(ap); 588 return; 589 } 590 591 592 public void rememberAsBest(int planType, Optimizer optimizer) 593 throws StandardException 594 { 595 AccessPath bestPath = null; 596 597 switch (planType) 598 { 599 case Optimizer.NORMAL_PLAN: 600 bestPath = getBestAccessPath(); 601 break; 602 603 case Optimizer.SORT_AVOIDANCE_PLAN: 604 bestPath = getBestSortAvoidancePath(); 605 break; 606 607 default: 608 if (SanityManager.DEBUG) 609 { 610 SanityManager.THROWASSERT( 611 "Invalid plan type " + planType); 612 } 613 } 614 615 getTrulyTheBestAccessPath().copy(bestPath); 616 617 if (!(this instanceof ProjectRestrictNode)) 631 updateBestPlanMap(ADD_PLAN, optimizer); 632 else 633 { 634 ProjectRestrictNode prn = (ProjectRestrictNode)this; 635 if (!(prn.getChildResult() instanceof Optimizable)) 636 updateBestPlanMap(ADD_PLAN, optimizer); 637 } 638 639 642 ConglomerateDescriptor cd = bestPath.getConglomerateDescriptor(); 643 644 if (isBaseTable()) 645 { 646 DataDictionary dd = getDataDictionary(); 647 TableDescriptor td = getTableDescriptor(); 648 getTrulyTheBestAccessPath().initializeAccessPathName(dd, td); 649 } 650 651 setCostEstimate(bestPath.getCostEstimate()); 652 653 bestPath.getOptimizer().trace(Optimizer.REMEMBERING_BEST_ACCESS_PATH, 654 tableNumber, planType, 0.0, bestPath); 655 } 656 657 658 public void startOptimizing(Optimizer optimizer, RowOrdering rowOrdering) 659 { 660 resetJoinStrategies(optimizer); 661 662 considerSortAvoidancePath = false; 663 664 669 CostEstimate ce = getBestAccessPath().getCostEstimate(); 670 671 if (ce != null) 672 ce.setCost(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE); 673 674 ce = getBestSortAvoidancePath().getCostEstimate(); 675 676 if (ce != null) 677 ce.setCost(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE); 678 679 if (! canBeOrdered()) 680 rowOrdering.addUnorderedOptimizable(this); 681 } 682 683 689 protected void resetJoinStrategies(Optimizer optimizer) 690 { 691 joinStrategyNumber = 0; 692 getCurrentAccessPath().setJoinStrategy((JoinStrategy) null); 693 } 694 695 700 public CostEstimate estimateCost(OptimizablePredicateList predList, 701 ConglomerateDescriptor cd, 702 CostEstimate outerCost, 703 Optimizer optimizer, 704 RowOrdering rowOrdering) 705 throws StandardException 706 { 707 if (SanityManager.DEBUG) 708 { 709 SanityManager.THROWASSERT( 710 "estimateCost() not expected to be called for " + 711 getClass().toString()); 712 } 713 714 return null; 715 } 716 717 725 public CostEstimate getFinalCostEstimate() 726 throws StandardException 727 { 728 if (finalCostEstimate != null) 730 return finalCostEstimate; 731 732 if (getTrulyTheBestAccessPath() == null) 733 finalCostEstimate = costEstimate; 734 else 735 finalCostEstimate = getTrulyTheBestAccessPath().getCostEstimate(); 736 737 return finalCostEstimate; 738 } 739 740 741 public boolean isBaseTable() 742 { 743 return false; 744 } 745 746 750 public boolean isMaterializable() 751 throws StandardException 752 { 753 756 757 HasCorrelatedCRsVisitor visitor = new HasCorrelatedCRsVisitor(); 758 accept(visitor); 759 return !(visitor.hasCorrelatedCRs()); 760 } 761 762 763 public boolean supportsMultipleInstantiations() 764 { 765 return true; 766 } 767 768 769 public int getTableNumber() 770 { 771 return tableNumber; 772 } 773 774 775 public boolean hasTableNumber() 776 { 777 return tableNumber >= 0; 778 } 779 780 781 public boolean forUpdate() 782 { 783 return false; 784 } 785 786 787 public int initialCapacity() 788 { 789 if (SanityManager.DEBUG) 790 { 791 SanityManager.THROWASSERT("Not expected to be called"); 792 } 793 794 return 0; 795 } 796 797 798 public float loadFactor() 799 { 800 if (SanityManager.DEBUG) 801 { 802 SanityManager.THROWASSERT("Not expected to be called"); 803 } 804 805 return 0.0F; 806 } 807 808 809 public int maxCapacity( JoinStrategy joinStrategy, int maxMemoryPerTable) throws StandardException 810 { 811 return joinStrategy.maxCapacity( maxCapacity, maxMemoryPerTable, getPerRowUsage()); 812 } 813 814 private double getPerRowUsage() throws StandardException 815 { 816 if( perRowUsage < 0) 817 { 818 FormatableBitSet refCols = resultColumns.getReferencedFormatableBitSet(cursorTargetTable(), true, false); 820 perRowUsage = 0.0; 821 822 823 for (int i = 0; i < refCols.size(); i++) 824 { 825 if (refCols.isSet(i)) 826 { 827 ResultColumn rc = (ResultColumn) resultColumns.elementAt(i); 828 DataTypeDescriptor expressionType = rc.getExpressionType(); 829 if( expressionType != null) 830 perRowUsage += expressionType.estimatedMemoryUsage(); 831 } 832 } 833 834 841 ConglomerateDescriptor cd = 842 getCurrentAccessPath().getConglomerateDescriptor(); 843 if (cd != null) 844 { 845 if (cd.isIndex() && ( ! isCoveringIndex(cd) ) ) 846 { 847 double baseIndexUsage = 1.0; 850 perRowUsage += ( baseIndexUsage + 11 ); 851 } 852 } 853 } 854 return perRowUsage ; 855 } 857 858 public int[] hashKeyColumns() 859 { 860 if (SanityManager.DEBUG) 861 { 862 SanityManager.ASSERT(hashKeyColumns != null, 863 "hashKeyColumns expected to be non-null"); 864 } 865 866 return hashKeyColumns; 867 } 868 869 870 public void setHashKeyColumns(int[] columnNumbers) 871 { 872 hashKeyColumns = columnNumbers; 873 } 874 875 880 public boolean feasibleJoinStrategy(OptimizablePredicateList predList, 881 Optimizer optimizer) 882 throws StandardException 883 { 884 return getCurrentAccessPath().getJoinStrategy(). 885 feasible(this, predList, optimizer); 886 } 887 888 889 public boolean memoryUsageOK( double rowCount, int maxMemoryPerTable) 890 throws StandardException 891 { 892 896 if( userSpecifiedJoinStrategy != null) 897 return true; 898 899 int intRowCount = (rowCount > Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int) rowCount; 900 return intRowCount <= maxCapacity( getCurrentAccessPath().getJoinStrategy(), maxMemoryPerTable); 901 } 902 903 906 public boolean legalJoinOrder(JBitSet assignedTableMap) 907 { 908 return true; 910 } 911 912 915 public int getNumColumnsReturned() 916 { 917 return resultColumns.size(); 918 } 919 920 923 public boolean isTargetTable() 924 { 925 return false; 926 } 927 928 933 public boolean isOneRowScan() 934 throws StandardException 935 { 936 942 return isOneRowResultSet(); 943 } 944 945 948 public void initAccessPaths(Optimizer optimizer) 949 { 950 if (currentAccessPath == null) 951 { 952 currentAccessPath = new AccessPathImpl(optimizer); 953 } 954 if (bestAccessPath == null) 955 { 956 bestAccessPath = new AccessPathImpl(optimizer); 957 } 958 if (bestSortAvoidancePath == null) 959 { 960 bestSortAvoidancePath = new AccessPathImpl(optimizer); 961 } 962 if (trulyTheBestAccessPath == null) 963 { 964 trulyTheBestAccessPath = new AccessPathImpl(optimizer); 965 } 966 } 967 968 973 public double uniqueJoin(OptimizablePredicateList predList) 974 throws StandardException 975 { 976 return -1.0; 977 } 978 979 private FormatableBitSet getRefCols() 980 { 981 if (refCols == null) 982 refCols = resultColumns.getReferencedFormatableBitSet(cursorTargetTable(), true, false); 983 984 return refCols; 985 } 986 987 988 993 String getUserSpecifiedJoinStrategy() 994 { 995 if (tableProperties == null) 996 { 997 return null; 998 } 999 1000 return tableProperties.getProperty("joinStrategy"); 1001 } 1002 1003 1009 protected boolean cursorTargetTable() 1010 { 1011 return false; 1012 } 1013 1014 protected CostEstimate getCostEstimate(Optimizer optimizer) 1015 { 1016 if (costEstimate == null) 1017 { 1018 costEstimate = optimizer.newCostEstimate(); 1019 } 1020 return costEstimate; 1021 } 1022 1023 1030 protected CostEstimate getScratchCostEstimate(Optimizer optimizer) 1031 { 1032 if (scratchCostEstimate == null) 1033 { 1034 scratchCostEstimate = optimizer.newCostEstimate(); 1035 } 1036 1037 return scratchCostEstimate; 1038 } 1039 1040 1043 protected void setCostEstimate(CostEstimate newCostEstimate) 1044 { 1045 costEstimate = getCostEstimate(); 1046 1047 costEstimate.setCost(newCostEstimate); 1048 } 1049 1050 1053 protected void assignCostEstimate(CostEstimate newCostEstimate) 1054 { 1055 costEstimate = newCostEstimate; 1056 } 1057 1058 1064 1065 public String toString() 1066 { 1067 if (SanityManager.DEBUG) 1068 { 1069 return "correlation Name: " + correlationName + "\n" + 1070 (corrTableName != null ? 1071 corrTableName.toString() : "null") + "\n" + 1072 "tableNumber " + tableNumber + "\n" + 1073 "level " + level + "\n" + 1074 super.toString(); 1075 } 1076 else 1077 { 1078 return ""; 1079 } 1080 } 1081 1082 1094 public ResultColumnList getResultColumnsForList(TableName allTableName, 1095 ResultColumnList inputRcl, 1096 TableName tableName) 1097 throws StandardException 1098 { 1099 ResultColumnList rcList = null; 1100 ResultColumn resultColumn; 1101 ValueNode valueNode; 1102 String columnName; 1103 TableName exposedName; 1104 TableName toCompare; 1105 1106 1109 1110 if(correlationName == null) 1111 toCompare = tableName; 1112 else { 1113 if(allTableName != null) 1114 toCompare = makeTableName(allTableName.getSchemaName(),correlationName); 1115 else 1116 toCompare = makeTableName(null,correlationName); 1117 } 1118 1119 if ( allTableName != null && 1120 ! allTableName.equals(toCompare)) 1121 { 1122 return null; 1123 } 1124 1125 1129 if (correlationName == null) 1130 { 1131 exposedName = tableName; 1132 } 1133 else 1134 { 1135 exposedName = makeTableName(null, correlationName); 1136 } 1137 1138 rcList = (ResultColumnList) getNodeFactory().getNode( 1139 C_NodeTypes.RESULT_COLUMN_LIST, 1140 getContextManager()); 1141 1142 1146 int inputSize = inputRcl.size(); 1147 for (int index = 0; index < inputSize; index++) 1148 { 1149 columnName = ((ResultColumn) inputRcl.elementAt(index)).getName(); 1151 valueNode = (ValueNode) getNodeFactory().getNode( 1152 C_NodeTypes.COLUMN_REFERENCE, 1153 columnName, 1154 exposedName, 1155 getContextManager()); 1156 resultColumn = (ResultColumn) getNodeFactory().getNode( 1157 C_NodeTypes.RESULT_COLUMN, 1158 columnName, 1159 valueNode, 1160 getContextManager()); 1161 1162 rcList.addResultColumn(resultColumn); 1164 } 1165 return rcList; 1166 } 1167 1168 1179 void pushExpressions(PredicateList predicateList) 1180 throws StandardException 1181 { 1182 if (SanityManager.DEBUG) 1183 { 1184 SanityManager.ASSERT(predicateList != null, 1185 "predicateList is expected to be non-null"); 1186 } 1187 } 1188 1189 1197 public String getExposedName() throws StandardException 1198 { 1199 if (SanityManager.DEBUG) 1200 SanityManager.THROWASSERT( 1201 "getExposedName() not expected to be called for " + this.getClass().getName()); 1202 return null; 1203 } 1204 1205 1210 public void setTableNumber(int tableNumber) 1211 { 1212 1213 if (SanityManager.DEBUG) 1214 SanityManager.ASSERT(this.tableNumber == -1, 1215 "tableNumber is not expected to be already set"); 1216 this.tableNumber = tableNumber; 1217 } 1218 1219 1227 public TableName getTableName() 1228 throws StandardException 1229 { 1230 if (correlationName == null) return null; 1231 1232 if (corrTableName == null) 1233 { 1234 corrTableName = makeTableName(null, correlationName); 1235 } 1236 1237 return corrTableName; 1238 } 1239 1240 1245 public void setLevel(int level) 1246 { 1247 this.level = level; 1248 } 1249 1250 1255 public int getLevel() 1256 { 1257 return level; 1258 } 1259 1260 1266 void decrementLevel(int decrement) 1267 { 1268 if (SanityManager.DEBUG) 1269 { 1270 1273 if (level < decrement && level != 0) 1274 { 1275 SanityManager.THROWASSERT( 1276 "level (" + level + 1277 ") expected to be >= decrement (" + 1278 decrement + ")"); 1279 } 1280 } 1281 1284 if (level > 0) 1285 { 1286 level -= decrement; 1287 } 1288 } 1289 1290 1299 public SchemaDescriptor getSchemaDescriptor() throws StandardException 1300 { 1301 return getSchemaDescriptor(corrTableName); 1302 } 1303 1304 1314 public SchemaDescriptor getSchemaDescriptor(TableName tableName) throws StandardException 1315 { 1316 SchemaDescriptor sd; 1317 1318 sd = getSchemaDescriptor(tableName.getSchemaName()); 1319 1320 return sd; 1321 } 1322 1323 1336 protected FromTable getFromTableByName(String name, String schemaName, boolean exactMatch) 1337 throws StandardException 1338 { 1339 if (schemaName != null) 1341 { 1342 return null; 1343 } 1344 1345 if (getExposedName().equals(name)) 1346 { 1347 return this; 1348 } 1349 return null; 1350 } 1351 1352 1358 public boolean isFlattenableJoinNode() 1359 { 1360 return false; 1361 } 1362 1363 1366 public boolean LOJ_reorderable(int numTables) 1367 throws StandardException 1368 { 1369 return false; 1370 } 1371 1372 1383 public FromTable transformOuterJoins(ValueNode predicateTree, int numTables) 1384 throws StandardException 1385 { 1386 return this; 1387 } 1388 1389 1394 public void fillInReferencedTableMap(JBitSet passedMap) 1395 { 1396 if (tableNumber != -1) 1397 { 1398 passedMap.set(tableNumber); 1399 } 1400 } 1401 1402 1410 protected void markUpdatableByCursor(Vector updateColumns) 1411 { 1412 resultColumns.markUpdatableByCursor(updateColumns); 1413 } 1414 1415 1432 public FromList flatten(ResultColumnList rcl, 1433 PredicateList outerPList, 1434 SubqueryList sql, 1435 GroupByList gbl) 1436 1437 throws StandardException 1438 { 1439 if (SanityManager.DEBUG) 1440 { 1441 SanityManager.THROWASSERT( 1442 "flatten() not expected to be called for " + this); 1443 } 1444 return null; 1445 } 1446 1447 1454 void optimizeSubqueries(DataDictionary dd, double rowCount) 1455 throws StandardException 1456 { 1457 } 1458 1459 1463 protected void tellRowOrderingAboutConstantColumns( 1464 RowOrdering rowOrdering, 1465 OptimizablePredicateList predList) 1466 { 1467 1471 if (predList != null) 1472 { 1473 for (int i = 0; i < predList.size(); i++) 1474 { 1475 Predicate pred = (Predicate) predList.getOptPredicate(i); 1476 1477 1478 if (pred.equalsComparisonWithConstantExpression(this)) 1479 { 1480 1481 ColumnReference cr = pred.getRelop().getColumnOperand(this); 1482 1483 if (cr != null) 1484 { 1485 1486 rowOrdering.columnAlwaysOrdered(this, cr.getColumnNumber()); 1487 } 1488 } 1489 } 1490 } 1491 1492 } 1493 1494 public boolean needsSpecialRCLBinding() 1495 { 1496 return false; 1497 } 1498 1499 1505 public void setOrigTableName(TableName tableName) 1506 { 1507 this.origTableName = tableName; 1508 } 1509 1510 1518 public TableName getOrigTableName() 1519 { 1520 return this.origTableName; 1521 } 1522} 1523 | Popular Tags |