1 21 22 package org.apache.derby.iapi.sql.dictionary; 23 24 import org.apache.derby.iapi.services.context.ContextManager; 25 26 import org.apache.derby.iapi.error.StandardException; 27 28 import org.apache.derby.iapi.sql.dictionary.GenericDescriptorList; 29 30 import org.apache.derby.iapi.sql.depend.Provider; 31 32 import org.apache.derby.iapi.sql.execute.ExecRow; 33 import org.apache.derby.catalog.UUID; 34 import org.apache.derby.catalog.DependableFinder; 35 import org.apache.derby.iapi.services.io.FormatableBitSet; 36 import org.apache.derby.iapi.sql.StatementType; 37 import org.apache.derby.iapi.services.io.StoredFormatIds; 38 39 import org.apache.derby.iapi.types.DataValueDescriptor; 40 import org.apache.derby.iapi.sql.depend.Provider; 41 import org.apache.derby.iapi.sql.execute.ExecRow; 42 import org.apache.derby.iapi.sql.execute.ExecutionContext; 43 44 import org.apache.derby.iapi.reference.SQLState; 45 import org.apache.derby.catalog.Dependable; 46 import org.apache.derby.iapi.services.sanity.SanityManager; 47 48 import java.util.Vector ; 49 import java.util.Enumeration ; 50 import java.util.List ; 51 import java.util.Iterator ; 52 53 97 98 public class TableDescriptor extends TupleDescriptor 99 implements UniqueSQLObjectDescriptor, Provider 100 { 101 public static final int BASE_TABLE_TYPE = 0; 102 public static final int SYSTEM_TABLE_TYPE = 1; 103 public static final int VIEW_TYPE = 2; 104 public static final int GLOBAL_TEMPORARY_TABLE_TYPE = 3; 105 public static final int SYNONYM_TYPE = 4; 106 public static final int VTI_TYPE = 5; 107 108 public static final char ROW_LOCK_GRANULARITY = 'R'; 109 public static final char TABLE_LOCK_GRANULARITY = 'T'; 110 public static final char DEFAULT_LOCK_GRANULARITY = ROW_LOCK_GRANULARITY; 111 112 114 115 private char lockGranularity; 117 private boolean onCommitDeleteRows; private boolean onRollbackDeleteRows; SchemaDescriptor schema; 120 String tableName; 121 UUID oid; 122 int tableType; 123 long heapConglomNumber = -1; 124 ColumnDescriptorList columnDescriptorList; 125 ConglomerateDescriptorList conglomerateDescriptorList; 126 ConstraintDescriptorList constraintDescriptorList; 127 private GenericDescriptorList triggerDescriptorList; 128 ViewDescriptor viewDescriptor; 129 FormatableBitSet referencedColumnMap; 130 131 133 private List statisticsDescriptorList; 134 135 145 146 public TableDescriptor 147 ( 148 DataDictionary dataDictionary, 149 String tableName, 150 SchemaDescriptor schema, 151 int tableType, 152 boolean onCommitDeleteRows, 153 boolean onRollbackDeleteRows 154 ) 155 { 156 this(dataDictionary, tableName, schema, tableType, '\0'); 157 158 this.onCommitDeleteRows = onCommitDeleteRows; 159 this.onRollbackDeleteRows = onRollbackDeleteRows; 160 } 161 162 172 173 public TableDescriptor 174 ( 175 DataDictionary dataDictionary, 176 String tableName, 177 SchemaDescriptor schema, 178 int tableType, 179 char lockGranularity 180 ) 181 { 182 super( dataDictionary ); 183 184 this.schema = schema; 185 this.tableName = tableName; 186 this.tableType = tableType; 187 this.lockGranularity = lockGranularity; 188 189 this.conglomerateDescriptorList = new ConglomerateDescriptorList(); 190 this.columnDescriptorList = new ColumnDescriptorList(); 191 this.constraintDescriptorList = new ConstraintDescriptorList(); 192 this.triggerDescriptorList = new GenericDescriptorList(); 193 } 194 195 199 205 public String getSchemaName() 206 { 207 return schema.getSchemaName(); 208 } 209 210 215 public SchemaDescriptor getSchemaDescriptor() 216 { 217 return schema; 218 } 219 220 225 public String getName() 226 { 227 return tableName; 228 } 229 230 236 public void setTableName(String newTableName) 237 { 238 this.tableName = newTableName; 239 } 240 241 246 public String getQualifiedName() 247 { 248 return quoteStringIfNecessary(getSchemaName()) + "." + 252 quoteStringIfNecessary(getName()); 253 } 254 255 265 266 private String quoteStringIfNecessary(String name) 267 { 268 String quotedString = name; 269 int quotePos = name.indexOf("\""); 270 271 if (quotePos == -1) 272 return name; 273 274 while(quotePos != -1) { 276 quotedString = quotedString.substring(0,quotePos) + "\"" + 277 quotedString.substring(quotePos); 278 quotePos = quotedString.indexOf("\"",quotePos+2); 279 } 280 return "\"" + quotedString + "\""; 281 282 } 283 284 289 public UUID getUUID() 290 { 291 return oid; 292 } 293 294 300 public int getTableType() 301 { 302 return tableType; 303 } 304 305 314 public long getHeapConglomerateId() 315 throws StandardException 316 { 317 DataDictionary dd = getDataDictionary(); 318 319 ConglomerateDescriptor cd = null; 320 321 324 if (heapConglomNumber != -1) 325 { 326 return heapConglomNumber; 327 } 328 329 ConglomerateDescriptor[] cds = getConglomerateDescriptors(); 330 331 for (int index = 0; index < cds.length; index++) 332 { 333 cd = cds[index]; 334 if ( ! cd.isIndex()) 335 break; 336 } 337 338 if (SanityManager.DEBUG) 339 { 340 if (cd == null) 341 { 342 SanityManager.THROWASSERT( 343 "cd is expected to be non-null for " + tableName); 344 } 345 346 if (cd.isIndex()) 347 { 348 SanityManager.THROWASSERT( 349 "Did not find heap conglomerate for " + tableName); 350 } 351 } 352 353 heapConglomNumber = cd.getConglomerateNumber(); 354 355 return heapConglomNumber; 356 } 357 358 364 public int getNumberOfColumns() 365 { 366 return getColumnDescriptorList().size(); 367 } 368 369 375 public FormatableBitSet getReferencedColumnMap() 376 { 377 return referencedColumnMap; 378 } 379 380 386 public void setReferencedColumnMap(FormatableBitSet referencedColumnMap) 387 { 388 this.referencedColumnMap = referencedColumnMap; 389 } 390 391 400 public int getMaxColumnID() 401 throws StandardException 402 { 403 int maxColumnID = 1; 404 int cdlSize = getColumnDescriptorList().size(); 405 for (int index = 0; index < cdlSize; index++) 406 { 407 ColumnDescriptor cd = (ColumnDescriptor) columnDescriptorList.elementAt(index); 408 maxColumnID = Math.max( maxColumnID, cd.getPosition() ); 409 } 410 411 return maxColumnID; 412 } 413 414 419 public void setUUID(UUID oid) 420 { 421 this.oid = oid; 422 } 423 424 429 public char getLockGranularity() 430 { 431 return lockGranularity; 432 } 433 434 439 public void setLockGranularity(char lockGranularity) 440 { 441 this.lockGranularity = lockGranularity; 442 } 443 444 449 public boolean isOnRollbackDeleteRows() 450 { 451 return onRollbackDeleteRows; 452 } 453 454 459 public boolean isOnCommitDeleteRows() 460 { 461 return onCommitDeleteRows; 462 } 463 464 468 public void resetHeapConglomNumber() 469 { 470 if (SanityManager.DEBUG) 471 { 472 if (tableType != TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE) 473 { 474 SanityManager.THROWASSERT("tableType expected to be TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE, not " + 475 tableType); 476 } 477 } 478 heapConglomNumber = -1; 479 } 480 481 489 public ExecRow getEmptyExecRow( ContextManager cm) 490 throws StandardException 491 { 492 int columnCount = getNumberOfColumns(); 493 ExecutionContext ec = (ExecutionContext) cm.getContext(ExecutionContext.CONTEXT_ID); 494 ExecRow result = ec.getExecutionFactory().getValueRow(columnCount); 495 496 for (int index = 0; index < columnCount; index++) 497 { 498 ColumnDescriptor cd = (ColumnDescriptor) columnDescriptorList.elementAt(index); 499 DataValueDescriptor dataValue = cd.getType().getNull(); 501 result.setColumn(index + 1, dataValue); 502 } 503 return result; 504 } 505 506 511 public ConglomerateDescriptorList getConglomerateDescriptorList() 512 { 513 return conglomerateDescriptorList; 514 } 515 516 521 public ViewDescriptor getViewDescriptor() 522 { 523 return viewDescriptor; 524 } 525 526 531 public void setViewDescriptor(ViewDescriptor viewDescriptor) 532 { 533 if (SanityManager.DEBUG) 534 { 535 if (tableType != TableDescriptor.VIEW_TYPE) 536 { 537 SanityManager.THROWASSERT("tableType expected to be TableDescriptor.VIEW_TYPE, not " + 538 tableType); 539 } 540 } 541 this.viewDescriptor = viewDescriptor; 542 } 543 544 550 public boolean isPersistent() 551 { 552 if (tableType == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE) 553 return false; 554 else 555 return(super.isPersistent()); 556 } 557 558 563 public boolean isSynonymDescriptor() 564 { 565 if (tableType == TableDescriptor.SYNONYM_TYPE) 566 return true; 567 return false; 568 } 569 570 576 public int getTotalNumberOfIndexes() 577 throws StandardException 578 { 579 int totalNumberOfIndexes = 0; 580 ConglomerateDescriptor[] cds = getConglomerateDescriptors(); 581 582 for (int index = 0; index < cds.length; index++) 583 { 584 if (cds[index].isIndex()) { totalNumberOfIndexes++; } 585 } 586 587 return totalNumberOfIndexes; 588 } 589 590 591 601 public void getAllRelevantTriggers 602 ( 603 int statementType, 604 int[] changedColumnIds, 605 GenericDescriptorList relevantTriggers 606 ) 607 throws StandardException 608 { 609 if (SanityManager.DEBUG) 610 { 611 SanityManager.ASSERT((statementType == StatementType.INSERT) || 612 (statementType == StatementType.BULK_INSERT_REPLACE) || 613 (statementType == StatementType.UPDATE) || 614 (statementType == StatementType.DELETE), 615 "invalid statement type "+statementType); 616 } 617 618 DataDictionary dd = getDataDictionary(); 619 Enumeration descs = dd.getTriggerDescriptors(this).elements(); 620 621 while (descs.hasMoreElements()) 622 { 623 TriggerDescriptor tgr = (TriggerDescriptor)descs.nextElement(); 624 625 if (tgr.needsToFire(statementType, changedColumnIds)) 626 { 627 relevantTriggers.add(tgr); 628 } 629 } 630 } 631 632 648 public void getAllRelevantConstraints 649 ( 650 int statementType, 651 boolean skipCheckConstraints, 652 int[] changedColumnIds, 653 boolean[] needsDeferredProcessing, 654 ConstraintDescriptorList relevantConstraints 655 ) 656 throws StandardException 657 { 658 if (SanityManager.DEBUG) 659 { 660 SanityManager.ASSERT((statementType == StatementType.INSERT) || 661 (statementType == StatementType.BULK_INSERT_REPLACE) || 662 (statementType == StatementType.UPDATE) || 663 (statementType == StatementType.DELETE), 664 "invalid statement type "+statementType); 665 } 666 667 DataDictionary dd = getDataDictionary(); 668 ConstraintDescriptorList cdl = dd.getConstraintDescriptors(this); 669 int cdlSize = cdl.size(); 670 671 for (int index = 0; index < cdlSize; index++) 672 { 673 ConstraintDescriptor cd = cdl.elementAt(index); 674 675 if (skipCheckConstraints && 676 (cd.getConstraintType() == DataDictionary.CHECK_CONSTRAINT)) 677 { 678 continue; 679 } 680 681 691 if (!needsDeferredProcessing[0] && 692 (cd instanceof ReferencedKeyConstraintDescriptor) && 693 (statementType != StatementType.UPDATE && 694 statementType != StatementType.BULK_INSERT_REPLACE)) 695 { 696 700 needsDeferredProcessing[0] = ((ReferencedKeyConstraintDescriptor)cd). 701 hasSelfReferencingFK(cdl, ConstraintDescriptor.ENABLED); 702 } 703 704 if (cd.needsToFire(statementType, changedColumnIds)) 705 { 706 711 if ((cd instanceof ReferencedKeyConstraintDescriptor) && 712 (statementType == StatementType.UPDATE || 713 statementType == StatementType.BULK_INSERT_REPLACE)) 714 { 715 needsDeferredProcessing[0] = true; 716 } 717 718 relevantConstraints.add(cd); 719 } 720 } 721 } 722 723 724 728 733 public DependableFinder getDependableFinder() 734 { 735 if (referencedColumnMap == null) 736 return getDependableFinder(StoredFormatIds.TABLE_DESCRIPTOR_FINDER_V01_ID); 737 else 738 return getColumnDependableFinder(StoredFormatIds.COLUMN_DESCRIPTOR_FINDER_V01_ID, 739 referencedColumnMap.getByteArray()); 740 } 741 742 747 public String getObjectName() 748 { 749 if (referencedColumnMap == null) 750 return tableName; 751 else 752 { 753 String name = new String (tableName); 754 boolean first = true; 755 for (int i = 0; i < columnDescriptorList.size(); i++) 756 { 757 ColumnDescriptor cd = (ColumnDescriptor) columnDescriptorList.elementAt(i); 758 if (referencedColumnMap.isSet(cd.getPosition())) 759 { 760 if (first) 761 { 762 name += "(" + cd.getColumnName(); 763 first = false; 764 } 765 else 766 name += ", " + cd.getColumnName(); 767 } 768 } 769 if (! first) 770 name += ")"; 771 return name; 772 } 773 } 774 775 780 public UUID getObjectID() 781 { 782 return oid; 783 } 784 785 790 public String getClassType() 791 { 792 return Dependable.TABLE; 793 } 794 795 799 804 public String toString() 805 { 806 if (SanityManager.DEBUG) 807 { 808 String tempString = "SCHEMA:\n" + schema + "\ntableName: " + tableName + "\n" + 809 "oid: " + oid + " tableType: " + tableType + "\n" + 810 "conglomerateDescriptorList: " + conglomerateDescriptorList + "\n" + 811 "columnDescriptorList: " + columnDescriptorList + "\n" + 812 "constraintDescriptorList: " + constraintDescriptorList + "\n" + 813 "heapConglomNumber: " + heapConglomNumber + "\n"; 814 if (tableType == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE) 815 { 816 tempString = tempString + "onCommitDeleteRows: " + "\n" + onCommitDeleteRows + "\n"; 817 tempString = tempString + "onRollbackDeleteRows: " + "\n" + onRollbackDeleteRows + "\n"; 818 } else 819 tempString = tempString + "lockGranularity: " + lockGranularity + "\n"; 820 return tempString; 821 } 822 else 823 { 824 return ""; 825 } 826 } 827 828 834 public ColumnDescriptorList getColumnDescriptorList() 835 { 836 return columnDescriptorList; 837 } 838 839 846 public ConstraintDescriptorList getConstraintDescriptorList() 847 throws StandardException 848 { 849 return constraintDescriptorList; 850 } 851 852 857 public void setConstraintDescriptorList(ConstraintDescriptorList newCDL) 858 { 859 constraintDescriptorList = newCDL; 860 } 861 862 867 public void emptyConstraintDescriptorList() 868 throws StandardException 869 { 870 this.constraintDescriptorList = new ConstraintDescriptorList(); 872 } 873 874 881 public ReferencedKeyConstraintDescriptor getPrimaryKey() 882 throws StandardException 883 { 884 ConstraintDescriptorList cdl = getDataDictionary().getConstraintDescriptors(this); 885 886 return cdl.getPrimaryKey(); 887 } 888 889 896 public GenericDescriptorList getTriggerDescriptorList() 897 throws StandardException 898 { 899 return triggerDescriptorList; 900 } 901 902 907 public void setTriggerDescriptorList(GenericDescriptorList newCDL) 908 { 909 triggerDescriptorList = newCDL; 910 } 911 912 917 public void emptyTriggerDescriptorList() 918 throws StandardException 919 { 920 this.triggerDescriptorList = new GenericDescriptorList(); 922 } 923 924 925 934 public boolean tableNameEquals(String otherTableName, String otherSchemaName) 935 { 936 String schemaName = getSchemaName(); 937 938 if ((schemaName == null) || 939 (otherSchemaName == null)) 940 { 941 return tableName.equals(otherTableName); 942 } 943 else 944 { 945 return schemaName.equals(otherSchemaName) && 946 tableName.equals(otherTableName); 947 } 948 } 949 950 957 public void removeConglomerateDescriptor(ConglomerateDescriptor cd) 958 throws StandardException 959 { 960 conglomerateDescriptorList.dropConglomerateDescriptor(getUUID(), cd); 961 } 962 963 971 public void removeConstraintDescriptor(ConstraintDescriptor cd) 972 throws StandardException 973 { 974 constraintDescriptorList.remove(cd); 975 } 976 977 986 public ColumnDescriptor getColumnDescriptor(String columnName) 987 { 988 return columnDescriptorList.getColumnDescriptor(oid, columnName); 989 } 990 991 996 public ColumnDescriptor getColumnDescriptor(int columnNumber) 997 { 998 return columnDescriptorList.getColumnDescriptor(oid, columnNumber); 999 } 1000 1001 1009 public ConglomerateDescriptor[] getConglomerateDescriptors() 1010 { 1011 1012 int size = conglomerateDescriptorList.size(); 1013 ConglomerateDescriptor[] cdls = new ConglomerateDescriptor[size]; 1014 conglomerateDescriptorList.toArray(cdls); 1015 return cdls; 1016 } 1017 1018 1029 public ConglomerateDescriptor getConglomerateDescriptor( 1030 long conglomerateNumber) 1031 throws StandardException 1032 { 1033 return conglomerateDescriptorList.getConglomerateDescriptor(conglomerateNumber); 1034 } 1035 1036 1049 public ConglomerateDescriptor[] getConglomerateDescriptors( 1050 long conglomerateNumber) 1051 throws StandardException 1052 { 1053 return conglomerateDescriptorList.getConglomerateDescriptors(conglomerateNumber); 1054 } 1055 1056 1057 1068 public ConglomerateDescriptor getConglomerateDescriptor( 1069 UUID conglomerateUUID) 1070 throws StandardException 1071 { 1072 return conglomerateDescriptorList.getConglomerateDescriptor(conglomerateUUID); 1073 } 1074 1075 1088 public ConglomerateDescriptor[] getConglomerateDescriptors( 1089 UUID conglomerateUUID) 1090 throws StandardException 1091 { 1092 return conglomerateDescriptorList.getConglomerateDescriptors(conglomerateUUID); 1093 } 1094 1095 1103 public IndexLister getIndexLister() 1104 throws StandardException 1105 { 1106 return new IndexLister( this ); 1107 } 1108 1109 1115 public boolean tableHasAutoincrement() 1116 { 1117 int cdlSize = getColumnDescriptorList().size(); 1118 for (int index = 0; index < cdlSize; index++) 1119 { 1120 ColumnDescriptor cd = 1121 (ColumnDescriptor) columnDescriptorList.elementAt(index); 1122 if (cd.isAutoincrement()) 1123 return true; 1124 } 1125 return false; 1126 } 1127 1128 1134 public String [] getColumnNamesArray() 1135 { 1136 int size = getNumberOfColumns(); 1137 String [] s = new String [size]; 1138 1139 for (int i = 0; i < size; i++) 1140 s[i] = getColumnDescriptor(i+1).getColumnName(); 1141 1142 return s; 1143 } 1144 1145 1154 public long[] getAutoincIncrementArray() 1155 { 1156 if (!tableHasAutoincrement()) 1157 return null; 1158 1159 int size = getNumberOfColumns(); 1160 long[] inc = new long[size]; 1161 1162 for (int i = 0; i < size; i++) 1163 { 1164 ColumnDescriptor cd = getColumnDescriptor(i + 1); 1165 if (cd.isAutoincrement()) 1166 inc[i] = cd.getAutoincInc(); 1167 } 1168 1169 return inc; 1170 } 1171 1172 1173 1175 private synchronized List getStatistics() throws StandardException 1176 { 1177 if (statisticsDescriptorList != null) 1180 return statisticsDescriptorList; 1181 1182 DataDictionary dd = getDataDictionary(); 1183 return statisticsDescriptorList = dd.getStatisticsDescriptors(this); 1184 } 1185 1186 1193 public boolean statisticsExist(ConglomerateDescriptor cd) 1194 throws StandardException 1195 { 1196 List sdl = getStatistics(); 1197 1198 if (cd == null) 1199 return (sdl.size() > 0); 1200 1201 UUID cdUUID = cd.getUUID(); 1202 1203 for (Iterator li = sdl.iterator(); li.hasNext(); ) 1204 { 1205 StatisticsDescriptor statDesc = (StatisticsDescriptor) li.next(); 1206 if (cdUUID.equals(statDesc.getReferenceID())) 1207 return true; 1208 1209 } 1210 1211 return false; 1212 } 1213 1214 1226 public double selectivityForConglomerate(ConglomerateDescriptor cd, 1227 int numKeys) 1228 throws StandardException 1229 { 1230 if (!statisticsExist(cd)) 1231 { 1232 if (SanityManager.DEBUG) 1233 { 1234 SanityManager.THROWASSERT("no statistics exist for conglomerate" 1235 + cd); 1236 } 1237 else 1238 { 1239 double selectivity = 0.1; 1240 for (int i = 0; i < numKeys; i++) 1241 selectivity *= 0.1; 1242 return selectivity; 1243 } 1244 } 1245 1246 UUID referenceUUID = cd.getUUID(); 1247 1248 List sdl = getStatistics(); 1249 for (Iterator li = sdl.iterator(); li.hasNext(); ) 1250 { 1251 StatisticsDescriptor statDesc = (StatisticsDescriptor) li.next(); 1252 1253 if (!referenceUUID.equals(statDesc.getReferenceID())) 1254 continue; 1255 1256 if (statDesc.getColumnCount() != numKeys) 1257 continue; 1258 1259 return statDesc.getStatistic().selectivity((Object [])null); 1260 } 1261 1262 if (SanityManager.DEBUG) 1263 SanityManager.THROWASSERT("Internal Error-- statistics not found in selectivityForConglomerate.\n cd = " + cd + "\nnumKeys = " + numKeys); 1264 return 0.1; } 1266 1267 1268 public String getDescriptorName() { return tableName; } 1269 1270 1271 public String getDescriptorType() 1272 { 1273 return (tableType == TableDescriptor.SYNONYM_TYPE) ? "Synonym" : "Table/View"; 1274 } 1275} 1276 | Popular Tags |