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.sql.compile.CompilerContext; 27 import org.apache.derby.iapi.sql.compile.Optimizable; 28 import org.apache.derby.iapi.sql.compile.OptimizableList; 29 import org.apache.derby.iapi.sql.compile.Optimizer; 30 import org.apache.derby.iapi.sql.compile.Visitable; 31 import org.apache.derby.iapi.sql.compile.Visitor; 32 import org.apache.derby.iapi.sql.compile.C_NodeTypes; 33 34 import org.apache.derby.iapi.sql.dictionary.DataDictionary; 35 36 import org.apache.derby.iapi.error.StandardException; 37 38 import org.apache.derby.iapi.reference.SQLState; 39 40 import org.apache.derby.iapi.util.JBitSet; 41 import org.apache.derby.iapi.util.StringUtil; 42 43 import java.util.Properties ; 44 import java.util.Enumeration ; 45 import java.util.Vector ; 46 47 53 54 public class FromList extends QueryTreeNodeVector implements OptimizableList 55 { 56 Properties properties; 57 boolean fixedJoinOrder = true; 59 boolean useStatistics = true; 61 62 private boolean referencesSessionSchema; 66 67 68 69 70 public void init(Object optimizeJoinOrder) 71 { 72 fixedJoinOrder = ! (((Boolean ) optimizeJoinOrder).booleanValue()); 73 } 74 75 80 public void init(Object optimizeJoinOrder, Object fromTable) 81 throws StandardException 82 { 83 init(optimizeJoinOrder); 84 85 addFromTable((FromTable) fromTable); 86 } 87 88 91 92 95 public Optimizable getOptimizable(int index) 96 { 97 return (Optimizable) elementAt(index); 98 } 99 100 103 public void setOptimizable(int index, Optimizable optimizable) 104 { 105 setElementAt((FromTable) optimizable, index); 106 } 107 108 112 public void verifyProperties(DataDictionary dDictionary) throws StandardException 113 { 114 int size = size(); 115 for (int index = 0; index < size; index++) 116 { 117 ((Optimizable) elementAt(index)).verifyProperties(dDictionary); 118 } 119 } 120 121 122 129 130 public void addFromTable(FromTable fromTable) throws StandardException 131 { 132 141 TableName leftTable = null; 142 TableName rightTable = null; 143 if (! (fromTable instanceof TableOperatorNode)) 144 { 145 146 int size = size(); 147 for (int index = 0; index < size; index++) 148 { 149 leftTable = fromTable.getTableName(); 150 151 if(((FromTable) elementAt(index)) instanceof TableOperatorNode) { 152 continue; 153 } 154 155 else { 156 rightTable = ((FromTable) elementAt(index)).getTableName(); 157 } 158 if(leftTable.equals(rightTable)) 159 { 160 throw StandardException.newException(SQLState.LANG_FROM_LIST_DUPLICATE_TABLE_NAME, fromTable.getExposedName()); 161 } 162 } 163 } 164 165 addElement(fromTable); 166 } 167 168 178 public boolean referencesTarget(String name, boolean baseTable) 179 throws StandardException 180 { 181 FromTable fromTable; 182 boolean found = false; 183 184 185 int size = size(); 186 for (int index = 0; index < size; index++) 187 { 188 fromTable = (FromTable) elementAt(index); 189 190 if (fromTable.referencesTarget(name, baseTable)) 191 { 192 found = true; 193 break; 194 } 195 } 196 197 return found; 198 } 199 200 207 public boolean referencesSessionSchema() 208 throws StandardException 209 { 210 FromTable fromTable; 211 boolean found = false; 212 213 if (referencesSessionSchema) return true; 220 221 222 int size = size(); 223 for (int index = 0; index < size; index++) 224 { 225 fromTable = (FromTable) elementAt(index); 226 227 if (fromTable.referencesSessionSchema()) 228 { 229 found = true; 230 break; 231 } 232 } 233 234 return found; 235 } 236 237 250 protected FromTable getFromTableByName(String name, String schemaName, boolean exactMatch) 251 throws StandardException 252 { 253 boolean found = false; 254 FromTable fromTable; 255 FromTable result = null; 256 257 int size = size(); 258 for (int index = 0; index < size; index++) 259 { 260 fromTable = (FromTable) elementAt(index); 261 262 result = fromTable.getFromTableByName(name, schemaName, exactMatch); 263 264 if (result != null) 265 { 266 return result; 267 } 268 } 269 return result; 270 } 271 272 282 283 public void bindTables(DataDictionary dataDictionary, 284 FromList fromListParam) 285 throws StandardException 286 { 287 FromTable fromTable; 288 289 297 int size = size(); 298 for (int index = 0; index < size; index++) 299 { 300 fromTable = (FromTable) elementAt(index); 301 ResultSetNode newNode = fromTable.bindNonVTITables(dataDictionary, fromListParam); 302 if (fromTable.referencesSessionSchema()) 307 referencesSessionSchema = true; 308 setElementAt(newNode, index); 309 } 310 for (int index = 0; index < size; index++) 311 { 312 fromTable = (FromTable) elementAt(index); 313 ResultSetNode newNode = fromTable.bindVTITables(fromListParam); 314 if (fromTable.referencesSessionSchema()) 315 referencesSessionSchema = true; 316 setElementAt(newNode, index); 317 } 318 } 319 320 327 328 public void bindExpressions( FromList fromListParam ) 329 throws StandardException 330 { 331 FromTable fromTable; 332 333 int size = size(); 334 for (int index = 0; index < size; index++) 335 { 336 fromTable = (FromTable) elementAt(index); 337 fromTable.bindExpressions( makeFromList( fromListParam, fromTable ) ); 338 } 339 } 340 341 349 private FromList makeFromList( FromList fromListParam, FromTable fromTable ) 350 { 351 if ( fromTable instanceof FromSubquery ) 352 { 353 FromSubquery fromSubquery = (FromSubquery) fromTable; 354 355 if ( fromSubquery.generatedForGroupByClause || fromSubquery.generatedForHavingClause ) 356 { return fromListParam; } 357 } 358 359 return this; 360 } 361 362 372 373 public void bindResultColumns(FromList fromListParam) 374 throws StandardException 375 { 376 FromTable fromTable; 377 378 int origList = fromListParam.size(); 379 int size = size(); 380 for (int index = 0; index < size; index++) 381 { 382 fromTable = (FromTable) elementAt(index); 383 if (fromTable.needsSpecialRCLBinding()) 384 fromTable.bindResultColumns(fromListParam); 385 386 fromListParam.insertElementAt(fromTable, 0); 387 } 388 389 390 while (fromListParam.size() > origList) 391 fromListParam.removeElementAt(0); 392 } 393 394 399 public boolean hasOuterJoins() 400 throws StandardException 401 { 402 FromTable fromTable; 403 404 int size = size(); 405 for (int index = 0; index < size; index++) 406 { 407 fromTable = (FromTable) elementAt(index); 408 if (fromTable instanceof HalfOuterJoinNode) 409 return true; 410 } 411 412 return false; 413 } 414 415 428 public ResultColumnList expandAll(TableName allTableName) 429 throws StandardException 430 { 431 ResultColumnList resultColumnList = null; 432 ResultColumnList tempRCList = null; 433 boolean matchfound = false; 434 FromTable fromTable; 435 436 440 int size = size(); 441 for (int index = 0; index < size; index++) 442 { 443 fromTable = (FromTable) elementAt(index); 444 445 450 tempRCList = fromTable.getAllResultColumns(allTableName); 451 452 if (tempRCList == null) 453 { 454 continue; 455 } 456 457 460 if (resultColumnList == null) 461 { 462 resultColumnList = tempRCList; 463 } 464 else 465 { 466 resultColumnList.nondestructiveAppend(tempRCList); 467 } 468 469 472 if (allTableName != null) 473 { 474 matchfound = true; 475 } 476 } 477 478 481 if (resultColumnList == null) 482 { 483 throw StandardException.newException(SQLState.LANG_EXPOSED_NAME_NOT_FOUND, allTableName); 484 } 485 486 return resultColumnList; 487 } 488 489 515 516 public ResultColumn bindColumnReference(ColumnReference columnReference) 517 throws StandardException 518 { 519 boolean columnNameMatch = false; 520 boolean tableNameMatch = false; 521 FromTable fromTable; 522 int currentLevel = -1; 523 int previousLevel = -1; 524 ResultColumn matchingRC = null; 525 ResultColumn resultColumn; 526 String crTableName = columnReference.getTableName(); 527 528 533 int size = size(); 534 for (int index = 0; index < size; index++) 535 { 536 fromTable = (FromTable) elementAt(index); 537 538 541 currentLevel = fromTable.getLevel(); 542 if (previousLevel != currentLevel) 543 { 544 if (columnNameMatch) 545 { 546 break; 547 } 548 549 if (tableNameMatch) 550 { 551 break; 552 } 553 } 554 555 previousLevel = currentLevel; 556 557 resultColumn = fromTable.getMatchingColumn(columnReference); 558 559 if (resultColumn != null) 560 { 561 if (! columnNameMatch) 562 { 563 569 matchingRC = resultColumn; 570 columnReference.setSource(resultColumn); 571 columnReference.setType(resultColumn.getTypeServices()); 572 575 columnReference.setNestingLevel(((FromTable) elementAt(0)).getLevel()); 576 columnReference.setSourceLevel(currentLevel); 577 columnNameMatch = true; 578 579 if (fromTable.isPrivilegeCollectionRequired()) 580 getCompilerContext().addRequiredColumnPriv( resultColumn.getTableColumnDescriptor()); 581 } 582 else 583 { 584 throw StandardException.newException(SQLState.LANG_AMBIGUOUS_COLUMN_NAME, 585 columnReference.getSQLColumnName()); 586 } 587 } 588 589 592 tableNameMatch = tableNameMatch || 593 (crTableName != null && 594 crTableName.equals(fromTable.getExposedName()) ); 595 } 596 597 return matchingRC; 598 } 599 600 607 608 public void rejectParameters() throws StandardException 609 { 610 FromTable fromTable; 611 612 int size = size(); 613 for (int index = 0; index < size; index++) 614 { 615 fromTable = (FromTable) elementAt(index); 616 fromTable.rejectParameters(); 617 } 618 } 619 620 public boolean LOJ_reorderable(int numTables) throws StandardException 624 { 625 boolean anyChange = false; 626 627 if (size() > 1) return anyChange; 628 629 FromTable ft = (FromTable) elementAt(0); 630 631 anyChange = ft.LOJ_reorderable(numTables); 632 633 return anyChange; 634 } 635 636 653 public void preprocess(int numTables, 654 GroupByList gbl, 655 ValueNode predicateTree) 656 throws StandardException 657 { 658 int size = size(); 659 660 661 for (int index = 0; index < size; index++) 662 { 663 FromTable ft = (FromTable) elementAt(index); 664 665 666 ft = ft.transformOuterJoins(predicateTree, numTables); 667 668 setElementAt(ft.preprocess(numTables, gbl, this), index); 669 } 670 } 671 672 684 public void flattenFromTables(ResultColumnList rcl, 685 PredicateList predicateList, 686 SubqueryList sql, 687 GroupByList gbl) 688 throws StandardException 689 { 690 boolean flattened = true; 691 Vector flattenedTableNumbers = new Vector (); 692 693 if (SanityManager.DEBUG) 694 { 695 SanityManager.ASSERT(rcl != null, 696 "rcl is expected to be non-null"); 697 SanityManager.ASSERT(predicateList != null, 698 "predicateList is expected to be non-null"); 699 SanityManager.ASSERT(sql != null, 700 "sql is expected to be non-null"); 701 } 702 703 708 while (flattened) 709 { 710 flattened = false; 711 712 for (int index = 0; index < size() && ! flattened; index++) 713 { 714 FromTable ft = (FromTable) elementAt(index); 715 716 717 if ((ft instanceof FromSubquery) || 718 ft.isFlattenableJoinNode()) 719 { 720 flattenedTableNumbers.addElement(new Integer (ft.getTableNumber())); 722 723 726 FromList flatteningFL = ft.flatten( 727 rcl, 728 predicateList, 729 sql, 730 gbl); 731 if (SanityManager.DEBUG) 732 { 733 SanityManager.ASSERT(flatteningFL == null || 734 flatteningFL.size() > 0, 735 "flatteningFL expected to be null or size > 0"); 736 } 737 738 if (flatteningFL != null) 739 { 740 setElementAt(flatteningFL.elementAt(0), index); 741 742 int innerSize = flatteningFL.size(); 743 for (int inner = 1; inner < innerSize; inner++) 744 { 745 insertElementAt(flatteningFL.elementAt(inner), index + inner); 746 } 747 } 748 else 749 { 750 754 removeElementAt(index); 755 } 756 flattened = true; 757 } 758 } 759 } 760 761 764 if (flattenedTableNumbers.size() > 0) 765 { 766 for (int i = 0; i < size(); i++) 767 { 768 FromTable ft = (FromTable) elementAt(i); 769 if (ft instanceof ProjectRestrictNode) 770 { 771 ResultSetNode rst = ((ProjectRestrictNode)ft).getChildResult(); 772 if (rst instanceof FromBaseTable) 773 { 774 ((FromBaseTable)rst).clearDependency(flattenedTableNumbers); 775 } 776 } 777 } 778 } 779 } 780 781 788 void pushPredicates(PredicateList predicateList) 789 throws StandardException 790 { 791 if (SanityManager.DEBUG) 792 { 793 SanityManager.ASSERT(predicateList != null, 794 "predicateList is expected to be non-null"); 795 } 796 797 802 predicateList.categorize(); 803 804 int size = size(); 805 for (int index = 0; index < size; index++) 806 { 807 FromTable fromTable = (FromTable) elementAt(index); 808 fromTable.pushExpressions(predicateList); 809 } 810 } 811 812 818 819 public void printSubNodes(int depth) 820 { 821 if (SanityManager.DEBUG) 822 { 823 FromTable fromTable; 824 825 super.printSubNodes(depth); 826 827 int size = size(); 828 for (int index = 0; index < size; index++) 829 { 830 fromTable = (FromTable) elementAt(index); 831 fromTable.treePrint(depth + 1); 832 } 833 } 834 } 835 836 842 public void setLevel(int level) 843 { 844 int size = size(); 845 for (int index = 0; index < size; index++) 846 { 847 FromTable fromTable = (FromTable) elementAt(index); 848 fromTable.setLevel(level); 849 } 850 } 851 852 860 public FromTable getFromTableByResultColumn(ResultColumn rc) 861 { 862 FromTable fromTable = null; 863 864 int size = size(); 865 for (int index = 0; index < size; index++) 866 { 867 fromTable = (FromTable) elementAt(index); 868 869 if (fromTable.getResultColumns().indexOf(rc) != -1) 870 { 871 break; 872 } 873 } 874 875 if (SanityManager.DEBUG) 876 { 877 SanityManager.ASSERT(fromTable != null, 878 "No matching FromTable found"); 879 } 880 return fromTable; 881 } 882 883 888 public void setProperties(Properties props) throws StandardException 889 { 890 properties = props; 891 892 897 Enumeration e = properties.keys(); 898 while (e.hasMoreElements()) 899 { 900 String key = (String ) e.nextElement(); 901 String value = (String ) properties.get(key); 902 903 if (key.equals("joinOrder")) 904 { 905 if (StringUtil.SQLEqualsIgnoreCase(value,"fixed")) 906 { 907 fixedJoinOrder = true; 908 } 909 else if (StringUtil.SQLEqualsIgnoreCase(value,"unfixed")) 910 { 911 fixedJoinOrder = false; 912 } 913 else 914 { 915 throw StandardException.newException(SQLState.LANG_INVALID_JOIN_ORDER_SPEC, value); 916 } 917 } 918 else if (key.equals("useStatistics")) 919 { 920 if (StringUtil.SQLEqualsIgnoreCase(value,"true")) 921 { 922 useStatistics = true; 923 } 924 else if (StringUtil.SQLEqualsIgnoreCase(value,"false")) 925 { 926 useStatistics = false; 927 } 928 else 929 { 930 throw StandardException.newException(SQLState.LANG_INVALID_STATISTICS_SPEC, value); 931 } 932 } 933 else 934 { 935 throw StandardException.newException(SQLState.LANG_INVALID_FROM_LIST_PROPERTY, key, value); 936 } 937 } 938 } 939 940 941 public void reOrder(int[] joinOrder) 942 { 943 int posn; 944 945 if (SanityManager.DEBUG) 946 { 947 if (joinOrder.length != size()) 948 { 949 SanityManager.THROWASSERT("In reOrder(), size of FromList is " + size() + " while size of joinOrder array is " + joinOrder.length); 950 } 951 952 958 int sum = 0; 959 for (int i = 0; i < joinOrder.length; i++) 960 { 961 if (joinOrder[i] < 0 || joinOrder[i] > (joinOrder.length - 1)) 962 { 963 SanityManager.THROWASSERT("joinOrder[" + i + "] == " + 964 joinOrder[i] + 965 " is out of range - must be between 0 and " + 966 (joinOrder.length - 1) + 967 " inclusive."); 968 } 969 970 sum += joinOrder[i]; 971 } 972 973 976 if (sum != ( ( joinOrder.length * (joinOrder.length - 1) ) / 2) ) 977 { 978 String arrayVals = ""; 979 for (int i = 0; i < joinOrder.length; i++) 980 arrayVals = arrayVals + joinOrder[i] + " "; 981 SanityManager.THROWASSERT("joinOrder array has some duplicate value: " + arrayVals); 982 } 983 } 984 985 986 QueryTreeNode[] orderedFL = new FromTable[joinOrder.length]; 987 for (posn = 0; posn < joinOrder.length; posn++) 988 { 989 993 orderedFL[posn] = elementAt(joinOrder[posn]); 994 } 995 996 997 for (posn = 0; posn < joinOrder.length; posn++) 998 { 999 setElementAt(orderedFL[posn], posn); 1000 } 1001 } 1002 1003 1004 public boolean useStatistics() 1005 { 1006 return useStatistics; 1007 } 1008 1009 1010 public boolean optimizeJoinOrder() 1011 { 1012 return ! fixedJoinOrder; 1013 } 1014 1015 1016 public boolean legalJoinOrder(int numTablesInQuery) 1017 { 1018 JBitSet assignedTableMap = new JBitSet(numTablesInQuery); 1019 1020 int size = size(); 1021 for (int index = 0; index < size; index++) 1022 { 1023 FromTable ft = (FromTable) elementAt(index); 1024 assignedTableMap.or(ft.getReferencedTableMap()); 1025 if ( ! ft.legalJoinOrder(assignedTableMap)) 1026 { 1027 return false; 1028 } 1029 } 1030 return true; 1031 } 1032 1033 1034 public void initAccessPaths(Optimizer optimizer) 1035 { 1036 int size = size(); 1037 for (int index = 0; index < size; index++) 1038 { 1039 FromTable ft = (FromTable) elementAt(index); 1040 ft.initAccessPaths(optimizer); 1041 } 1042 } 1043 1044 1051 public void bindUntypedNullsToResultColumns(ResultColumnList bindingRCL) 1052 throws StandardException 1053 { 1054 int size = size(); 1055 for (int index = 0; index < size; index++) 1056 { 1057 FromTable fromTable = (FromTable) elementAt(index); 1058 fromTable.bindUntypedNullsToResultColumns(bindingRCL); 1059 } 1060 } 1061 1062 1069 void decrementLevel(int decrement) 1070 { 1071 int size = size(); 1072 for (int index = 0; index < size; index++) 1073 { 1074 FromTable fromTable = (FromTable) elementAt(index); 1075 fromTable.decrementLevel(decrement); 1076 1077 1081 ProjectRestrictNode prn = (ProjectRestrictNode) fromTable; 1082 PredicateList pl = prn.getRestrictionList(); 1083 if (pl != null) 1084 { 1085 pl.decrementLevel(this, decrement); 1086 } 1087 } 1088 } 1089 1090 1091 1171 boolean returnsAtMostSingleRow(ResultColumnList rcl, 1172 ValueNode whereClause, 1173 PredicateList wherePredicates, 1174 DataDictionary dd) 1175 throws StandardException 1176 { 1177 boolean satisfiesOuter = false; 1178 int[] tableNumbers; 1179 ColumnReference additionalCR = null; 1180 1181 PredicateList predicatesTemp; 1182 predicatesTemp = (PredicateList) getNodeFactory().getNode( 1183 C_NodeTypes.PREDICATE_LIST, getContextManager()); 1184 int wherePredicatesSize = wherePredicates.size(); 1185 for (int index = 0; index < wherePredicatesSize; index++) 1186 predicatesTemp.addPredicate((Predicate)wherePredicates.elementAt(index)); 1187 1188 1194 if (rcl != null) 1195 { 1196 ResultColumn rc = (ResultColumn) rcl.elementAt(0); 1197 if (rc.getExpression() instanceof ColumnReference) 1198 { 1199 additionalCR = (ColumnReference) rc.getExpression(); 1200 } 1201 } 1202 1203 1206 int size = size(); 1207 for (int index = 0; index < size; index++) 1208 { 1209 FromTable fromTable = (FromTable) elementAt(index); 1210 if (! (fromTable instanceof ProjectRestrictNode)) 1211 { 1212 return false; 1213 } 1214 1215 ProjectRestrictNode prn = (ProjectRestrictNode) fromTable; 1216 1217 if (! (prn.getChildResult() instanceof FromBaseTable)) 1218 { 1219 return false; 1220 } 1221 FromBaseTable fbt = (FromBaseTable) prn.getChildResult(); 1222 if (fbt.getExistsBaseTable()) 1259 { 1260 int existsTableNumber = fbt.getTableNumber(); 1261 int predicatesTempSize = predicatesTemp.size(); 1262 for (int predicatesTempIndex = predicatesTempSize-1; 1263 predicatesTempIndex >= 0; predicatesTempIndex--) 1264 { 1265 AndNode topAndNode = (AndNode) 1266 ((Predicate) predicatesTemp.elementAt(predicatesTempIndex)).getAndNode(); 1267 1268 for (ValueNode whereWalker = topAndNode; whereWalker instanceof AndNode; 1269 whereWalker = ((AndNode) whereWalker).getRightOperand()) 1270 { 1271 AndNode and = (AndNode) whereWalker; 1273 1274 if (!and.getLeftOperand().isRelationalOperator() || 1277 !(((RelationalOperator)(and.getLeftOperand())).getOperator() == 1278 RelationalOperator.EQUALS_RELOP)) 1279 { 1280 continue; 1281 } 1282 1283 JBitSet referencedTables = and.getLeftOperand().getTablesReferenced(); 1284 if (referencedTables.get(existsTableNumber)) 1285 { 1286 predicatesTemp.removeElementAt(predicatesTempIndex); 1287 break; 1288 } 1289 } 1290 } 1291 } 1292 } 1293 1294 1299 tableNumbers = getTableNumbers(); 1300 JBitSet[][] tableColMap = new JBitSet[size][size]; 1301 boolean[] oneRow = new boolean[size]; 1302 boolean oneRowResult = false; 1303 1304 1305 for (int index = 0; index < size; index++) 1306 { 1307 ProjectRestrictNode prn = (ProjectRestrictNode) elementAt(index); 1308 FromBaseTable fbt = (FromBaseTable) prn.getChildResult(); 1309 1310 if (fbt.getExistsBaseTable()) 1312 { 1313 oneRow[index] = true; 1314 continue; 1315 } 1316 1317 int numColumns = fbt.getTableDescriptor().getNumberOfColumns(); 1318 boolean[] eqOuterCols = new boolean[numColumns + 1]; 1319 int tableNumber = fbt.getTableNumber(); 1320 boolean resultColTable = false; 1321 for (int i = 0; i < size; i++) 1322 tableColMap[index][i] = new JBitSet(numColumns + 1); 1323 1324 if (additionalCR != null && 1325 additionalCR.getTableNumber() == tableNumber) 1326 { 1327 rcl.recordColumnReferences(eqOuterCols, tableColMap[index], index); 1328 resultColTable = true; 1329 } 1330 1331 1334 if (whereClause != null) 1335 { 1336 whereClause.checkTopPredicatesForEqualsConditions( 1337 tableNumber, eqOuterCols, tableNumbers, 1338 tableColMap[index], resultColTable); 1339 } 1340 1341 1344 predicatesTemp.checkTopPredicatesForEqualsConditions( 1345 tableNumber, eqOuterCols, tableNumbers, 1346 tableColMap[index], resultColTable); 1347 1348 1352 if (prn.getRestrictionList() != null) 1353 { 1354 prn.getRestrictionList().checkTopPredicatesForEqualsConditions( 1355 tableNumber, eqOuterCols, tableNumbers, 1356 tableColMap[index], resultColTable); 1357 } 1358 1359 1362 if (! fbt.supersetOfUniqueIndex(tableColMap[index])) 1363 { 1364 return false; 1365 } 1366 1367 1370 oneRowResult = fbt.supersetOfUniqueIndex(eqOuterCols); 1371 if (oneRowResult) 1372 { 1373 oneRow[index] = true; 1374 satisfiesOuter = true; 1375 } 1376 } 1377 1378 1379 if (satisfiesOuter) 1380 { 1381 1384 boolean foundOneRow = true; 1385 while (foundOneRow) 1386 { 1387 foundOneRow = false; 1388 for (int index = 0; index < size; index++) 1389 { 1390 if (oneRow[index]) 1391 { 1392 for (int i = 0; i < size; i++) 1393 { 1394 1397 if (!oneRow[i] && tableColMap[i][index].get(0)) 1398 { 1399 oneRow[i] = true; 1400 foundOneRow = true; 1401 } 1402 } 1403 } 1404 } 1405 } 1406 1407 for (int index = 0; index < size; index++) 1408 { 1409 if (!oneRow[index]) 1410 { 1411 satisfiesOuter = false; 1412 break; 1413 } 1414 } 1415 } 1416 return satisfiesOuter; 1417 } 1418 1419 int[] getTableNumbers() 1420 { 1421 int size = size(); 1422 int[] tableNumbers = new int[size]; 1423 for (int index = 0; index < size; index++) 1424 { 1425 ProjectRestrictNode prn = (ProjectRestrictNode) elementAt(index); 1426 if (! (prn.getChildResult() instanceof FromTable)) 1427 { 1428 continue; 1429 } 1430 FromTable ft = (FromTable) prn.getChildResult(); 1431 tableNumbers[index] = ft.getTableNumber(); 1432 } 1433 1434 return tableNumbers; 1435 } 1436 1437 1448 void genExistsBaseTables(JBitSet referencedTableMap, FromList outerFromList, 1449 boolean isNotExists) 1450 throws StandardException 1451 { 1452 JBitSet dependencyMap = (JBitSet) referencedTableMap.clone(); 1453 1454 if (SanityManager.DEBUG) 1456 { 1457 if (size() != 1) 1458 { 1459 SanityManager.THROWASSERT( 1460 "size() expected to be 1, not " + size()); 1461 } 1462 } 1463 1464 1465 int size = size(); 1466 for (int index = 0; index < size; index++) 1467 { 1468 ResultSetNode ft = ((ProjectRestrictNode) elementAt(index)).getChildResult(); 1469 if (ft instanceof FromTable) 1470 { 1471 dependencyMap.clear(((FromTable) ft).getTableNumber()); 1472 } 1473 } 1474 1475 1484 if (dependencyMap.getFirstSetBit() == -1) 1485 { 1486 int outerSize = outerFromList.size(); 1487 for (int outer = 0; outer < outerSize; outer++) 1488 dependencyMap.or(((FromTable) outerFromList.elementAt(outer)).getReferencedTableMap()); 1489 } 1490 1491 1492 for (int index = 0; index < size; index++) 1493 { 1494 FromTable fromTable = (FromTable) elementAt(index); 1495 if (fromTable instanceof ProjectRestrictNode) 1496 { 1497 ProjectRestrictNode prn = (ProjectRestrictNode) fromTable; 1498 if (prn.getChildResult() instanceof FromBaseTable) 1499 { 1500 FromBaseTable fbt = (FromBaseTable) prn.getChildResult(); 1501 fbt.setExistsBaseTable(true, (JBitSet) dependencyMap.clone(), isNotExists); 1502 } 1503 } 1504 } 1505 } 1506 1507 1514 public int updateTargetLockMode() 1515 { 1516 if (SanityManager.DEBUG) 1517 { 1518 if (size() != 1) 1519 { 1520 SanityManager.THROWASSERT( 1521 "size() expected to be 1"); 1522 } 1523 } 1524 return ((ResultSetNode) elementAt(0)).updateTargetLockMode(); 1525 } 1526 1527 1534 boolean hashJoinSpecified() 1535 { 1536 int size = size(); 1537 for (int index = 0; index < size; index++) 1538 { 1539 FromTable ft = (FromTable) elementAt(index); 1540 String joinStrategy = ft.getUserSpecifiedJoinStrategy(); 1541 1542 if (joinStrategy != null && StringUtil.SQLToUpperCase(joinStrategy).equals("HASH")) 1543 { 1544 return true; 1545 } 1546 } 1547 1548 return false; 1549 } 1550 1551 1559 public Visitable accept(Visitor v) 1560 throws StandardException 1561 { 1562 int size = size(); 1563 for (int index = 0; index < size; index++) 1564 { 1565 FromTable fromTable = (FromTable) elementAt(index); 1566 setElementAt((QueryTreeNode) fromTable.accept(v), index); 1567 } 1568 1569 return this; 1570 } 1571} 1572 | Popular Tags |