1 21 22 package org.apache.derby.impl.sql.execute; 23 24 import org.apache.derby.iapi.services.sanity.SanityManager; 25 26 import org.apache.derby.iapi.services.io.StreamStorable; 27 28 import org.apache.derby.iapi.error.StandardException; 29 30 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; 31 32 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor; 33 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptorList; 34 import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor; 35 import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList; 36 import org.apache.derby.iapi.sql.dictionary.ReferencedKeyConstraintDescriptor; 37 import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor; 38 import org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator; 39 import org.apache.derby.iapi.sql.dictionary.DataDictionary; 40 import org.apache.derby.iapi.sql.dictionary.DataDictionaryContext; 41 import org.apache.derby.iapi.sql.dictionary.DefaultDescriptor; 42 import org.apache.derby.iapi.sql.dictionary.IndexLister; 43 import org.apache.derby.iapi.sql.dictionary.IndexRowGenerator; 44 import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor; 45 import org.apache.derby.iapi.sql.dictionary.TableDescriptor; 46 import org.apache.derby.iapi.sql.dictionary.StatisticsDescriptor; 47 import org.apache.derby.iapi.sql.dictionary.DependencyDescriptor; 48 import org.apache.derby.iapi.sql.dictionary.CheckConstraintDescriptor; 49 import org.apache.derby.iapi.sql.dictionary.GenericDescriptorList; 50 import org.apache.derby.iapi.sql.dictionary.TriggerDescriptor; 51 import org.apache.derby.impl.sql.catalog.DDColumnDependableFinder; 52 53 import org.apache.derby.iapi.sql.StatementType; 54 55 import org.apache.derby.iapi.types.DataValueDescriptor; 56 import org.apache.derby.iapi.types.DataTypeDescriptor; 57 import org.apache.derby.iapi.types.DataValueFactory; 58 59 import org.apache.derby.iapi.reference.SQLState; 60 61 import org.apache.derby.iapi.sql.depend.Dependency; 62 import org.apache.derby.iapi.sql.depend.DependencyManager; 63 import org.apache.derby.iapi.sql.depend.Provider; 64 import org.apache.derby.iapi.sql.depend.ProviderInfo; 65 66 import org.apache.derby.iapi.reference.SQLState; 67 68 import org.apache.derby.iapi.sql.execute.ConstantAction; 69 import org.apache.derby.iapi.sql.execute.ExecIndexRow; 70 import org.apache.derby.iapi.sql.execute.ExecRow; 71 import org.apache.derby.iapi.sql.execute.ExecutionFactory; 72 73 import org.apache.derby.iapi.store.access.ColumnOrdering; 74 import org.apache.derby.iapi.store.access.ConglomerateController; 75 import org.apache.derby.iapi.store.access.GroupFetchScanController; 76 import org.apache.derby.iapi.store.access.Qualifier; 77 import org.apache.derby.iapi.store.access.RowLocationRetRowSource; 78 import org.apache.derby.iapi.store.access.RowSource; 79 import org.apache.derby.iapi.store.access.RowUtil; 80 import org.apache.derby.iapi.store.access.ScanController; 81 import org.apache.derby.iapi.store.access.SortController; 82 import org.apache.derby.iapi.store.access.SortObserver; 83 import org.apache.derby.iapi.store.access.TransactionController; 84 85 import org.apache.derby.iapi.types.NumberDataValue; 86 87 import org.apache.derby.iapi.sql.Activation; 88 import org.apache.derby.iapi.sql.ResultSet; 89 import org.apache.derby.iapi.sql.Statement; 90 import org.apache.derby.iapi.sql.PreparedStatement; 91 92 import org.apache.derby.iapi.types.RowLocation; 93 94 import org.apache.derby.catalog.UUID; 95 import org.apache.derby.catalog.IndexDescriptor; 96 import org.apache.derby.catalog.DependableFinder; 97 98 import org.apache.derby.catalog.types.DefaultInfoImpl; 99 import org.apache.derby.catalog.types.StatisticsImpl; 100 import org.apache.derby.catalog.types.ReferencedColumnsDescriptorImpl; 101 102 import java.sql.SQLException ; 103 import java.util.Properties ; 104 import java.util.Enumeration ; 105 106 import org.apache.derby.iapi.services.io.FormatableBitSet; 107 108 import java.util.List ; 109 import java.util.Iterator ; 110 111 117 118 class AlterTableConstantAction extends DDLSingleTableConstantAction 119 implements RowLocationRetRowSource 120 { 121 122 protected SchemaDescriptor sd; 123 protected String tableName; 124 protected UUID schemaId; 125 protected int tableType; 126 protected long tableConglomerateId; 127 protected ColumnInfo[] columnInfo; 128 protected ConstraintConstantAction[] constraintActions; 129 protected char lockGranularity; 130 private boolean compressTable; 131 private boolean sequential; 132 private int behavior; 133 134 private boolean doneScan; 136 private boolean[] needToDropSort; 137 private boolean[] validRow; 138 private int bulkFetchSize = 16; 139 private int currentCompressRow; 140 private int numIndexes; 141 private int rowCount; 142 private long estimatedRowCount; 143 private long[] indexConglomerateNumbers; 144 private long[] sortIds; 145 private FormatableBitSet indexedCols; 146 private ConglomerateController compressHeapCC; 147 private ExecIndexRow[] indexRows; 148 private ExecRow[] baseRow; 149 private ExecRow currentRow; 150 private GroupFetchScanController compressHeapGSC; 151 private IndexRowGenerator[] compressIRGs; 152 private DataValueDescriptor[][] baseRowArray; 153 private RowLocation[] compressRL; 154 private SortController[] sorters; 155 private int columnPosition; 156 private ColumnOrdering[][] ordering; 157 158 private TableDescriptor td; 159 160 161 private boolean truncateTable; 163 164 private LanguageConnectionContext lcc; 166 private DataDictionary dd; 167 private DependencyManager dm; 168 private TransactionController tc; 169 private Activation activation; 170 171 187 AlterTableConstantAction( 188 SchemaDescriptor sd, 189 String tableName, 190 UUID tableId, 191 long tableConglomerateId, 192 int tableType, 193 ColumnInfo[] columnInfo, 194 ConstraintConstantAction[] constraintActions, 195 char lockGranularity, 196 boolean compressTable, 197 int behavior, 198 boolean sequential, 199 boolean truncateTable) 200 { 201 super(tableId); 202 this.sd = sd; 203 this.tableName = tableName; 204 this.tableConglomerateId = tableConglomerateId; 205 this.tableType = tableType; 206 this.columnInfo = columnInfo; 207 this.constraintActions = constraintActions; 208 this.lockGranularity = lockGranularity; 209 this.compressTable = compressTable; 210 this.behavior = behavior; 211 this.sequential = sequential; 212 this.truncateTable = truncateTable; 213 214 if (SanityManager.DEBUG) 215 { 216 SanityManager.ASSERT(sd != null, "schema descriptor is null"); 217 } 218 } 219 220 222 public String toString() 223 { 224 227 if(truncateTable) 230 return "TRUNCATE TABLE " + tableName; 231 else 232 return "ALTER TABLE " + tableName; 233 } 234 235 237 244 public void executeConstantAction( Activation activation ) 245 throws StandardException 246 { 247 LanguageConnectionContext lcc = activation.getLanguageConnectionContext(); 248 DataDictionary dd = lcc.getDataDictionary(); 249 DependencyManager dm = dd.getDependencyManager(); 250 TransactionController tc = lcc.getTransactionExecute(); 251 252 261 dd.startWriting(lcc); 262 263 265 270 if (tableConglomerateId == 0) 272 { 273 td = dd.getTableDescriptor(tableId); 274 if (td == null) 275 { 276 throw StandardException.newException( 277 SQLState.LANG_TABLE_NOT_FOUND_DURING_EXECUTION, tableName); 278 } 279 tableConglomerateId = td.getHeapConglomerateId(); 280 } 281 282 lockTableForDDL(tc, tableConglomerateId, true); 283 284 td = dd.getTableDescriptor(tableId); 285 if (td == null) 286 { 287 throw StandardException.newException( 288 SQLState.LANG_TABLE_NOT_FOUND_DURING_EXECUTION, tableName); 289 } 290 291 if(truncateTable) 292 dm.invalidateFor(td, DependencyManager.TRUNCATE_TABLE, lcc); 293 else 294 dm.invalidateFor(td, DependencyManager.ALTER_TABLE, lcc); 295 execGuts( activation ); 296 } 297 298 299 307 public void execGuts( Activation activation) 308 throws StandardException 309 { 310 ColumnDescriptor columnDescriptor; 311 int numRows = 0; 312 boolean tableNeedsScanning = false; 313 boolean tableScanned = false; 314 315 LanguageConnectionContext lcc = activation.getLanguageConnectionContext(); 316 DataDictionary dd = lcc.getDataDictionary(); 317 DependencyManager dm = dd.getDependencyManager(); 318 TransactionController tc = lcc.getTransactionExecute(); 319 320 activation.setDDLTableDescriptor(td); 322 323 329 if (sd == null) 330 { 331 sd = getAndCheckSchemaDescriptor(dd, schemaId, "ALTER TABLE"); 332 } 333 334 335 340 if(truncateTable) 341 dm.invalidateFor(td, DependencyManager.TRUNCATE_TABLE, lcc); 342 else 343 dm.invalidateFor(td, DependencyManager.ALTER_TABLE, lcc); 344 345 if (columnInfo != null) 347 { 348 352 355 for (int ix = 0; ix < columnInfo.length; ix++) 356 { 357 358 364 if ((columnInfo[ix].action == ColumnInfo.CREATE) && 365 !(columnInfo[ix].dataType.isNullable()) && 366 (columnInfo[ix].defaultInfo == null) && 367 (columnInfo[ix].autoincInc == 0) 368 ) 369 { 370 tableNeedsScanning = true; 371 } 372 } 373 374 if (tableNeedsScanning) 376 { 377 numRows = getSemiRowCount(tc); 378 if (numRows > 0) 380 { 381 throw StandardException.newException(SQLState.LANG_ADDING_NON_NULL_COLUMN_TO_NON_EMPTY_TABLE, 382 td.getQualifiedName()); 383 } 384 tableScanned = true; 385 } 386 387 for (int ix = 0; ix < columnInfo.length; ix++) 389 { 390 ColumnDescriptorList cdl = new ColumnDescriptorList(); 391 392 393 394 396 if (columnInfo[ix].action == ColumnInfo.CREATE) 397 { 398 addNewColumnToTable(activation, ix); 399 } 400 else if (columnInfo[ix].action == 401 ColumnInfo.MODIFY_COLUMN_DEFAULT_RESTART || 402 columnInfo[ix].action == ColumnInfo.MODIFY_COLUMN_DEFAULT_INCREMENT) 403 { 404 modifyColumnDefault(activation, ix); 405 } 406 else if (columnInfo[ix].action == 407 ColumnInfo.MODIFY_COLUMN_TYPE) 408 { 409 modifyColumnType(activation, ix); 410 } 411 else if (columnInfo[ix].action == 412 ColumnInfo.MODIFY_COLUMN_CONSTRAINT) 413 { 414 modifyColumnConstraint(activation, columnInfo[ix].name, true); 415 } 416 else if (columnInfo[ix].action == 417 ColumnInfo.MODIFY_COLUMN_CONSTRAINT_NOT_NULL) 418 { 419 if (! tableScanned) 420 { 421 tableScanned = true; 422 numRows = getSemiRowCount(tc); 423 } 424 String colNames[] = new String [1]; 426 colNames[0] = columnInfo[ix].name; 427 boolean nullCols[] = new boolean[1]; 428 429 432 if (validateNotNullConstraint(colNames, nullCols, 433 numRows, lcc, SQLState.LANG_NULL_DATA_IN_NON_NULL_COLUMN)) 434 { 435 439 modifyColumnConstraint(activation, columnInfo[ix].name, false); 440 } 441 } 442 else if (columnInfo[ix].action == ColumnInfo.DROP) 443 { 444 dropColumnFromTable(activation, ix); 445 } 446 else if (SanityManager.DEBUG) 447 { 448 SanityManager.THROWASSERT( 449 "Unexpected action in AlterTableConstantAction"); 450 } 451 } 452 } 453 454 455 if (constraintActions != null) 456 { 457 for (int conIndex = 0; conIndex < constraintActions.length; conIndex++) 458 { 459 ConstraintConstantAction cca = constraintActions[conIndex]; 460 461 if (cca instanceof CreateConstraintConstantAction) 462 { 463 int constraintType = cca.getConstraintType(); 464 465 469 switch (constraintType) 470 { 471 case DataDictionary.PRIMARYKEY_CONSTRAINT: 472 ConstraintDescriptorList cdl = dd.getConstraintDescriptors(td); 474 if (cdl.getPrimaryKey() != null) 475 { 476 throw StandardException.newException(SQLState.LANG_ADD_PRIMARY_KEY_FAILED1, 477 td.getQualifiedName()); 478 } 479 if (! tableScanned) 480 { 481 tableScanned = true; 482 numRows = getSemiRowCount(tc); 483 } 484 485 break; 486 case DataDictionary.CHECK_CONSTRAINT: 487 if (! tableScanned) 488 { 489 tableScanned = true; 490 numRows = getSemiRowCount(tc); 491 } 492 if (numRows > 0) 493 { 494 500 ConstraintConstantAction.validateConstraint( 501 cca.getConstraintName(), 502 ((CreateConstraintConstantAction)cca).getConstraintText(), 503 td, 504 lcc, true); 505 } 506 break; 507 } 508 } 509 else 510 { 511 if (SanityManager.DEBUG) 512 { 513 if (!(cca instanceof DropConstraintConstantAction)) 514 { 515 SanityManager.THROWASSERT("constraintActions[" + conIndex + 516 "] expected to be instanceof DropConstraintConstantAction not " + 517 cca.getClass().getName()); 518 } 519 } 520 } 521 constraintActions[conIndex].executeConstantAction(activation); 522 } 523 } 524 525 if (lockGranularity != '\0') 527 { 528 if (SanityManager.DEBUG) 529 { 530 if (lockGranularity != 'T' && 531 lockGranularity != 'R') 532 { 533 SanityManager.THROWASSERT( 534 "lockGranularity expected to be 'T'or 'R', not " + lockGranularity); 535 } 536 } 537 538 td.setLockGranularity(lockGranularity); 540 dd.updateLockGranularity(td, sd, lockGranularity, tc); 542 } 543 544 if (compressTable) 546 { 547 compressTable(activation); 548 } 549 550 if (truncateTable) 552 { 553 truncateTable(activation); 554 } 555 556 557 } 558 559 566 private void addNewColumnToTable(Activation activation, 567 int ix) 568 throws StandardException 569 { 570 LanguageConnectionContext lcc = activation.getLanguageConnectionContext(); 571 DataDictionary dd = lcc.getDataDictionary(); 572 DependencyManager dm = dd.getDependencyManager(); 573 TransactionController tc = lcc.getTransactionExecute(); 574 575 ColumnDescriptor columnDescriptor = 576 td.getColumnDescriptor(columnInfo[ix].name); 577 DataValueDescriptor storableDV; 578 int colNumber = td.getMaxColumnID() + ix; 579 DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator(); 580 581 585 if (columnDescriptor != null) 586 { 587 throw 588 StandardException.newException( 589 SQLState.LANG_OBJECT_ALREADY_EXISTS_IN_OBJECT, 590 columnDescriptor.getDescriptorType(), 591 columnInfo[ix].name, 592 td.getDescriptorType(), 593 td.getQualifiedName()); 594 } 595 596 if (columnInfo[ix].defaultValue != null) 597 storableDV = columnInfo[ix].defaultValue; 598 else 599 storableDV = columnInfo[ix].dataType.getNull(); 600 601 tc.addColumnToConglomerate(td.getHeapConglomerateId(), colNumber, 603 storableDV); 604 605 UUID defaultUUID = columnInfo[ix].newDefaultUUID; 606 607 610 if (columnInfo[ix].defaultInfo != null && 611 defaultUUID == null) 612 { 613 defaultUUID = dd.getUUIDFactory().createUUID(); 614 } 615 616 columnDescriptor = new ColumnDescriptor( 619 columnInfo[ix].name, 620 colNumber + 1, 621 columnInfo[ix].dataType, 622 columnInfo[ix].defaultValue, 623 columnInfo[ix].defaultInfo, 624 td, 625 defaultUUID, 626 columnInfo[ix].autoincStart, 627 columnInfo[ix].autoincInc 628 ); 629 630 dd.addDescriptor(columnDescriptor, td, 631 DataDictionary.SYSCOLUMNS_CATALOG_NUM, false, tc); 632 633 td.getColumnDescriptorList().add(columnDescriptor); 635 636 if (columnDescriptor.isAutoincrement()) 637 { 638 updateNewAutoincrementColumn(activation, columnInfo[ix].name, 639 columnInfo[ix].autoincStart, 640 columnInfo[ix].autoincInc); 641 } 642 643 if (columnDescriptor.hasNonNullDefault()) 645 { 646 updateNewColumnToDefault(activation, 647 columnInfo[ix].name, 648 columnInfo[ix].defaultInfo.getDefaultText(), 649 lcc); 650 } 651 652 dd.updateSYSCOLPERMSforAddColumnToUserTable(td.getUUID(), tc); 661 } 662 663 670 private void dropColumnFromTable(Activation activation, 671 int ix) 672 throws StandardException 673 { 674 LanguageConnectionContext lcc = activation.getLanguageConnectionContext(); 675 DataDictionary dd = lcc.getDataDictionary(); 676 DependencyManager dm = dd.getDependencyManager(); 677 TransactionController tc = lcc.getTransactionExecute(); 678 679 680 ColumnDescriptor columnDescriptor = 681 td.getColumnDescriptor(columnInfo[ix].name); 682 683 if (columnDescriptor == null) 685 { 686 throw 687 StandardException.newException( 688 SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE, 689 columnInfo[ix].name, 690 td.getQualifiedName()); 691 } 692 693 DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator(); 694 ColumnDescriptorList tab_cdl = td.getColumnDescriptorList(); 695 int size = tab_cdl.size(); 696 697 if (size == 1) 699 { 700 throw StandardException.newException(SQLState.LANG_PROVIDER_HAS_DEPENDENT_OBJECT, 701 dm.getActionString(DependencyManager.DROP_COLUMN), 702 "THE *LAST* COLUMN " + columnInfo[ix].name, 703 "TABLE", 704 td.getQualifiedName() ); 705 } 706 707 columnPosition = columnDescriptor.getPosition(); 708 boolean cascade = (behavior == StatementType.DROP_CASCADE); 709 710 FormatableBitSet toDrop = new FormatableBitSet(size + 1); 711 toDrop.set(columnPosition); 712 td.setReferencedColumnMap(toDrop); 713 714 dm.invalidateFor(td, DependencyManager.DROP_COLUMN, lcc); 715 716 if (columnDescriptor.getDefaultInfo() != null) 718 { 719 DefaultDescriptor defaultDesc = columnDescriptor.getDefaultDescriptor(dd); 720 dm.clearDependencies(lcc, defaultDesc); 721 } 722 723 GenericDescriptorList tdl = dd.getTriggerDescriptors(td); 725 Enumeration descs = tdl.elements(); 726 while (descs.hasMoreElements()) 727 { 728 TriggerDescriptor trd = (TriggerDescriptor) descs.nextElement(); 729 int[] referencedCols = trd.getReferencedCols(); 730 if (referencedCols == null) 731 continue; 732 int refColLen = referencedCols.length, j; 733 boolean changed = false; 734 for (j = 0; j < refColLen; j++) 735 { 736 if (referencedCols[j] > columnPosition) 737 changed = true; 738 else if (referencedCols[j] == columnPosition) 739 { 740 if (cascade) 741 { 742 DropTriggerConstantAction.dropTriggerDescriptor(lcc, dm, dd, tc, trd, activation); 743 activation.addWarning( 744 StandardException.newWarning(SQLState.LANG_TRIGGER_DROPPED, 745 trd.getName(), td.getName())); 746 } 747 else 748 { throw StandardException.newException(SQLState.LANG_PROVIDER_HAS_DEPENDENT_OBJECT, 751 dm.getActionString(DependencyManager.DROP_COLUMN), 752 columnInfo[ix].name, "TRIGGER", 753 trd.getName() ); 754 } 755 break; 756 } 757 } 758 759 if (j == refColLen && changed) 761 { 762 dd.dropTriggerDescriptor(trd, tc); 763 for (j = 0; j < refColLen; j++) 764 { 765 if (referencedCols[j] > columnPosition) 766 referencedCols[j]--; 767 } 768 dd.addDescriptor(trd, sd, 769 DataDictionary.SYSTRIGGERS_CATALOG_NUM, 770 false, tc); 771 } 772 } 773 774 ConstraintDescriptorList csdl = dd.getConstraintDescriptors(td); 775 int csdl_size = csdl.size(); 776 777 int tbr_size = 0; 781 ConstraintDescriptor[] toBeRemoved = new ConstraintDescriptor[csdl_size]; 782 783 for (int i = csdl_size - 1; i >= 0; i--) 785 { 786 ConstraintDescriptor cd = csdl.elementAt(i); 787 int[] referencedColumns = cd.getReferencedColumns(); 788 int numRefCols = referencedColumns.length, j; 789 boolean changed = false; 790 for (j = 0; j < numRefCols; j++) 791 { 792 if (referencedColumns[j] > columnPosition) 793 changed = true; 794 if (referencedColumns[j] == columnPosition) 795 break; 796 } 797 if (j == numRefCols) { 799 if ((cd instanceof CheckConstraintDescriptor) && changed) 800 { 801 dd.dropConstraintDescriptor(td, cd, tc); 802 for (j = 0; j < numRefCols; j++) 803 { 804 if (referencedColumns[j] > columnPosition) 805 referencedColumns[j]--; 806 } 807 ((CheckConstraintDescriptor) cd).setReferencedColumnsDescriptor(new ReferencedColumnsDescriptorImpl(referencedColumns)); 808 dd.addConstraintDescriptor(cd, tc); 809 } 810 continue; 811 } 812 813 if (! cascade) 814 { 815 if (numRefCols > 1 || cd.getConstraintType() == DataDictionary.PRIMARYKEY_CONSTRAINT) 816 { 817 throw StandardException.newException(SQLState.LANG_PROVIDER_HAS_DEPENDENT_OBJECT, 818 dm.getActionString(DependencyManager.DROP_COLUMN), 819 columnInfo[ix].name, "CONSTRAINT", 820 cd.getConstraintName() ); 821 } 822 } 823 824 if (cd instanceof ReferencedKeyConstraintDescriptor) 825 { 826 toBeRemoved[tbr_size++] = cd; 828 continue; 829 } 830 831 dm.invalidateFor(cd, DependencyManager.DROP_CONSTRAINT, 833 lcc); 834 DropConstraintConstantAction.dropConstraintAndIndex(dm, td, dd, 835 cd, tc, lcc, true); 836 activation.addWarning(StandardException.newWarning(SQLState.LANG_CONSTRAINT_DROPPED, 837 cd.getConstraintName(), td.getName())); 838 } 839 840 for (int i = tbr_size - 1; i >= 0; i--) 841 { 842 ConstraintDescriptor cd = toBeRemoved[i]; 843 DropConstraintConstantAction.dropConstraintAndIndex(dm, td, dd, cd, 844 tc, lcc, false); 845 activation.addWarning(StandardException.newWarning(SQLState.LANG_CONSTRAINT_DROPPED, 846 cd.getConstraintName(), td.getName())); 847 848 if (cascade) 849 { 850 ConstraintDescriptorList fkcdl = dd.getForeignKeys(cd.getUUID()); 851 for (int j = 0; j < fkcdl.size(); j++) 852 { 853 ConstraintDescriptor fkcd = (ConstraintDescriptor) fkcdl.elementAt(j); 854 dm.invalidateFor(fkcd, 855 DependencyManager.DROP_CONSTRAINT, 856 lcc); 857 858 DropConstraintConstantAction.dropConstraintAndIndex( 859 dm, fkcd.getTableDescriptor(), dd, fkcd, tc, lcc, true); 860 activation.addWarning(StandardException.newWarning(SQLState.LANG_CONSTRAINT_DROPPED, 861 fkcd.getConstraintName(), fkcd.getTableDescriptor().getName())); 862 } 863 } 864 865 dm.invalidateFor(cd, DependencyManager.DROP_CONSTRAINT, lcc); 866 dm.clearDependencies(lcc, cd); 867 } 868 869 compressTable(activation); 870 871 dd.dropColumnDescriptor(td.getUUID(), columnInfo[ix].name, tc); 873 ColumnDescriptor[] cdlArray = new ColumnDescriptor[size - columnDescriptor.getPosition()]; 874 875 for (int i = columnDescriptor.getPosition(), j = 0; i < size; i++, j++) 876 { 877 ColumnDescriptor cd = (ColumnDescriptor) tab_cdl.elementAt(i); 878 dd.dropColumnDescriptor(td.getUUID(), cd.getColumnName(), tc); 879 cd.setPosition(i); 880 cdlArray[j] = cd; 881 } 882 dd.addDescriptorArray(cdlArray, td, 883 DataDictionary.SYSCOLUMNS_CATALOG_NUM, false, tc); 884 885 List deps = dd.getProvidersDescriptorList(td.getObjectID().toString()); 886 for (Iterator depsIterator = deps.listIterator(); depsIterator.hasNext();) 887 { 888 DependencyDescriptor depDesc = (DependencyDescriptor) depsIterator.next(); 889 DependableFinder finder = depDesc.getProviderFinder(); 890 if (finder instanceof DDColumnDependableFinder) 891 { 892 DDColumnDependableFinder colFinder = (DDColumnDependableFinder) finder; 893 FormatableBitSet oldColumnBitMap = new FormatableBitSet(colFinder.getColumnBitMap()); 894 FormatableBitSet newColumnBitMap = new FormatableBitSet(oldColumnBitMap); 895 newColumnBitMap.clear(); 896 int bitLen = oldColumnBitMap.getLength(); 897 for (int i = 0; i < bitLen; i++) 898 { 899 if (i < columnPosition && oldColumnBitMap.isSet(i)) 900 newColumnBitMap.set(i); 901 if (i > columnPosition && oldColumnBitMap.isSet(i)) 902 newColumnBitMap.set(i - 1); 903 } 904 if (newColumnBitMap.equals(oldColumnBitMap)) 905 continue; 906 dd.dropStoredDependency(depDesc, tc); 907 colFinder.setColumnBitMap(newColumnBitMap.getByteArray()); 908 dd.addDescriptor(depDesc, null, 909 DataDictionary.SYSDEPENDS_CATALOG_NUM, 910 true, tc); 911 } 912 } 913 } 914 915 private void modifyColumnType(Activation activation, 916 int ix) 917 throws StandardException 918 { 919 LanguageConnectionContext lcc = activation.getLanguageConnectionContext(); 920 DataDictionary dd = lcc.getDataDictionary(); 921 TransactionController tc = lcc.getTransactionExecute(); 922 923 ColumnDescriptor columnDescriptor = 924 td.getColumnDescriptor(columnInfo[ix].name), 925 newColumnDescriptor = null; 926 927 newColumnDescriptor = 928 new ColumnDescriptor(columnInfo[ix].name, 929 columnDescriptor.getPosition(), 930 columnInfo[ix].dataType, 931 columnDescriptor.getDefaultValue(), 932 columnDescriptor.getDefaultInfo(), 933 td, 934 columnDescriptor.getDefaultUUID(), 935 columnInfo[ix].autoincStart, 936 columnInfo[ix].autoincInc 937 ); 938 939 940 941 dd.dropColumnDescriptor(td.getUUID(), columnInfo[ix].name, tc); 943 dd.addDescriptor(newColumnDescriptor, td, 944 DataDictionary.SYSCOLUMNS_CATALOG_NUM, false, tc); 945 } 946 947 952 private void modifyColumnConstraint(Activation activation, 953 String colName, 954 boolean nullability) 955 throws StandardException 956 { 957 LanguageConnectionContext lcc = activation.getLanguageConnectionContext(); 958 DataDictionary dd = lcc.getDataDictionary(); 959 TransactionController tc = lcc.getTransactionExecute(); 960 961 ColumnDescriptor columnDescriptor = 962 td.getColumnDescriptor(colName), 963 newColumnDescriptor = null; 964 DataTypeDescriptor dataType = columnDescriptor.getType(); 965 966 dataType.setNullability(nullability); 968 969 newColumnDescriptor = 970 new ColumnDescriptor(colName, 971 columnDescriptor.getPosition(), 972 dataType, 973 columnDescriptor.getDefaultValue(), 974 columnDescriptor.getDefaultInfo(), 975 td, 976 columnDescriptor.getDefaultUUID(), 977 columnDescriptor.getAutoincStart(), 978 columnDescriptor.getAutoincInc()); 979 980 981 982 dd.dropColumnDescriptor(td.getUUID(), colName, tc); 984 dd.addDescriptor(newColumnDescriptor, td, 985 DataDictionary.SYSCOLUMNS_CATALOG_NUM, false, tc); 986 987 } 988 996 private void modifyColumnDefault(Activation activation, 997 int ix) 998 throws StandardException 999 { 1000 LanguageConnectionContext lcc = activation.getLanguageConnectionContext(); 1001 DataDictionary dd = lcc.getDataDictionary(); 1002 DependencyManager dm = dd.getDependencyManager(); 1003 TransactionController tc = lcc.getTransactionExecute(); 1004 1005 ColumnDescriptor columnDescriptor = 1006 td.getColumnDescriptor(columnInfo[ix].name); 1007 DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator(); 1008 int columnPosition = columnDescriptor.getPosition(); 1009 1010 if (columnDescriptor.hasNonNullDefault()) 1012 { 1013 DefaultDescriptor defaultDescriptor = new DefaultDescriptor(dd, columnInfo[ix].oldDefaultUUID, 1015 td.getUUID(), columnPosition); 1016 1017 1018 dm.invalidateFor(defaultDescriptor, DependencyManager.MODIFY_COLUMN_DEFAULT, lcc); 1019 1020 dm.clearDependencies(lcc, defaultDescriptor); 1022 } 1023 1024 UUID defaultUUID = columnInfo[ix].newDefaultUUID; 1025 1026 1029 if (columnInfo[ix].defaultInfo != null && 1030 defaultUUID == null) 1031 { 1032 defaultUUID = dd.getUUIDFactory().createUUID(); 1033 } 1034 1035 1036 columnDescriptor = new ColumnDescriptor( 1037 columnInfo[ix].name, 1038 columnPosition, 1039 columnInfo[ix].dataType, 1040 columnInfo[ix].defaultValue, 1041 columnInfo[ix].defaultInfo, 1042 td, 1043 defaultUUID, 1044 columnInfo[ix].autoincStart, 1045 columnInfo[ix].autoincInc, 1046 columnInfo[ix].autoinc_create_or_modify_Start_Increment 1047 ); 1048 1049 dd.dropColumnDescriptor(td.getUUID(), columnInfo[ix].name, tc); 1051 dd.addDescriptor(columnDescriptor, td, 1052 DataDictionary.SYSCOLUMNS_CATALOG_NUM, false, tc); 1053 1054 if (columnInfo[ix].action == ColumnInfo.MODIFY_COLUMN_DEFAULT_INCREMENT) 1055 { 1056 long maxValue = getColumnMax(activation, td, columnInfo[ix].name, 1059 columnInfo[ix].autoincInc, 1060 columnInfo[ix].autoincStart); 1061 dd.setAutoincrementValue(tc, td.getUUID(), columnInfo[ix].name, 1062 maxValue, true); 1063 } else if (columnInfo[ix].action == ColumnInfo.MODIFY_COLUMN_DEFAULT_RESTART) 1064 { 1065 dd.setAutoincrementValue(tc, td.getUUID(), columnInfo[ix].name, 1066 columnInfo[ix].autoincStart, false); 1067 } 1068 } 1069 1070 1071 1074 private void compressTable(Activation activation) 1075 throws StandardException 1076 { 1077 ExecRow emptyHeapRow; 1078 long newHeapConglom; 1079 Properties properties = new Properties (); 1080 RowLocation rl; 1081 this.lcc = activation.getLanguageConnectionContext(); 1082 this.dd = lcc.getDataDictionary(); 1083 this.dm = dd.getDependencyManager(); 1084 this.tc = lcc.getTransactionExecute(); 1085 this.activation = activation; 1086 1087 if (SanityManager.DEBUG) 1088 { 1089 if (lockGranularity != '\0') 1090 { 1091 SanityManager.THROWASSERT( 1092 "lockGranularity expected to be '\0', not " + lockGranularity); 1093 } 1094 SanityManager.ASSERT(! compressTable || columnInfo == null, 1095 "columnInfo expected to be null"); 1096 SanityManager.ASSERT(constraintActions == null, 1097 "constraintActions expected to be null"); 1098 } 1099 emptyHeapRow = td.getEmptyExecRow(lcc.getContextManager()); 1100 compressHeapCC = tc.openConglomerate( 1101 td.getHeapConglomerateId(), 1102 false, 1103 TransactionController.OPENMODE_FORUPDATE, 1104 TransactionController.MODE_TABLE, 1105 TransactionController.ISOLATION_SERIALIZABLE); 1106 1107 dm.invalidateFor(td, DependencyManager.COMPRESS_TABLE, lcc); 1115 1116 1117 rl = compressHeapCC.newRowLocationTemplate(); 1118 1119 compressHeapCC.getInternalTablePropertySet(properties); 1121 compressHeapCC.close(); 1122 compressHeapCC = null; 1123 1124 baseRow = new ExecRow[bulkFetchSize]; 1126 baseRowArray = new DataValueDescriptor[bulkFetchSize][]; 1127 validRow = new boolean[bulkFetchSize]; 1128 1129 1130 getAffectedIndexes(activation); 1131 compressRL = new RowLocation[bulkFetchSize]; 1133 indexRows = new ExecIndexRow[numIndexes]; 1134 if (! compressTable) 1135 { 1136 ExecRow newRow = activation.getExecutionFactory().getValueRow(emptyHeapRow.nColumns() - 1); 1137 for (int i = 0; i < newRow.nColumns(); i++) 1138 { 1139 newRow.setColumn(i + 1, i < columnPosition - 1 ? 1140 emptyHeapRow.getColumn(i + 1) : 1141 emptyHeapRow.getColumn(i + 1 + 1)); 1142 } 1143 emptyHeapRow = newRow; 1144 } 1145 setUpAllSorts(emptyHeapRow, rl); 1146 1147 openBulkFetchScan(td.getHeapConglomerateId()); 1149 1150 estimatedRowCount = compressHeapGSC.getEstimatedRowCount(); 1152 1153 for (int i = 0; i < bulkFetchSize; i++) 1155 { 1156 baseRow[i] = td.getEmptyExecRow(lcc.getContextManager()); 1158 baseRowArray[i] = baseRow[i].getRowArray(); 1159 compressRL[i] = compressHeapGSC.newRowLocationTemplate(); 1160 } 1161 1162 1163 newHeapConglom = tc.createAndLoadConglomerate( 1164 "heap", 1165 emptyHeapRow.getRowArray(), 1166 null, properties, 1168 TransactionController.IS_DEFAULT, 1169 this, 1170 (long[]) null); 1171 1172 closeBulkFetchScan(); 1173 1174 ScanController compressHeapSC = tc.openScan( 1176 newHeapConglom, 1177 false, 1178 TransactionController.OPENMODE_FORUPDATE, 1179 TransactionController.MODE_TABLE, 1180 TransactionController.ISOLATION_SERIALIZABLE, 1181 (FormatableBitSet) null, 1182 (DataValueDescriptor[]) null, 1183 0, 1184 (Qualifier[][]) null, 1185 (DataValueDescriptor[]) null, 1186 0); 1187 1188 compressHeapSC.setEstimatedRowCount(rowCount); 1189 1190 compressHeapSC.close(); 1191 compressHeapSC = null; 1193 1202 dd.startWriting(lcc); 1203 1204 if (compressIRGs.length > 0) 1206 { 1207 updateAllIndexes(newHeapConglom, dd); 1208 } 1209 1210 1214 long oldHeapConglom = td.getHeapConglomerateId(); 1216 ConglomerateDescriptor cd = td.getConglomerateDescriptor(oldHeapConglom); 1217 1218 dd.updateConglomerateDescriptor(cd, newHeapConglom, tc); 1220 tc.dropConglomerate(oldHeapConglom); 1222 cleanUp(); 1223 } 1224 1225 1226 1227 1244 private void truncateTable(Activation activation) 1245 throws StandardException 1246 { 1247 ExecRow emptyHeapRow; 1248 long newHeapConglom; 1249 Properties properties = new Properties (); 1250 RowLocation rl; 1251 this.lcc = activation.getLanguageConnectionContext(); 1252 this.dd = lcc.getDataDictionary(); 1253 this.dm = dd.getDependencyManager(); 1254 this.tc = lcc.getTransactionExecute(); 1255 this.activation = activation; 1256 1257 if (SanityManager.DEBUG) 1258 { 1259 if (lockGranularity != '\0') 1260 { 1261 SanityManager.THROWASSERT( 1262 "lockGranularity expected to be '\0', not " + lockGranularity); 1263 } 1264 SanityManager.ASSERT(columnInfo == null, 1265 "columnInfo expected to be null"); 1266 SanityManager.ASSERT(constraintActions == null, 1267 "constraintActions expected to be null"); 1268 } 1269 1270 1271 ConstraintDescriptorList cdl = dd.getConstraintDescriptors(td); 1274 for(int index = 0; index < cdl.size(); index++) 1275 { 1276 ConstraintDescriptor cd = cdl.elementAt(index); 1277 if (cd instanceof ReferencedKeyConstraintDescriptor) 1278 { 1279 ReferencedKeyConstraintDescriptor rfcd = (ReferencedKeyConstraintDescriptor) cd; 1280 if(rfcd.hasNonSelfReferencingFK(ConstraintDescriptor.ENABLED)) 1281 { 1282 throw StandardException.newException(SQLState.LANG_NO_TRUNCATE_ON_FK_REFERENCE_TABLE,td.getName()); 1283 } 1284 } 1285 } 1286 1287 GenericDescriptorList tdl = dd.getTriggerDescriptors(td); 1289 Enumeration descs = tdl.elements(); 1290 while (descs.hasMoreElements()) 1291 { 1292 TriggerDescriptor trd = (TriggerDescriptor) descs.nextElement(); 1293 if (trd.listensForEvent(TriggerDescriptor.TRIGGER_EVENT_DELETE) && 1294 trd.isEnabled()) 1295 { 1296 throw 1297 StandardException.newException(SQLState.LANG_NO_TRUNCATE_ON_ENABLED_DELETE_TRIGGERS, 1298 td.getName(),trd.getName()); 1299 } 1300 } 1301 1302 emptyHeapRow = td.getEmptyExecRow(lcc.getContextManager()); 1304 compressHeapCC = tc.openConglomerate( 1305 td.getHeapConglomerateId(), 1306 false, 1307 TransactionController.OPENMODE_FORUPDATE, 1308 TransactionController.MODE_TABLE, 1309 TransactionController.ISOLATION_SERIALIZABLE); 1310 1311 dm.invalidateFor(td, DependencyManager.TRUNCATE_TABLE, lcc); 1319 1320 rl = compressHeapCC.newRowLocationTemplate(); 1321 compressHeapCC.getInternalTablePropertySet(properties); 1323 compressHeapCC.close(); 1324 compressHeapCC = null; 1325 1326 newHeapConglom = tc.createConglomerate( 1328 "heap", 1329 emptyHeapRow.getRowArray(), 1330 null, properties, 1332 TransactionController.IS_DEFAULT); 1333 1334 1335 getAffectedIndexes(activation); 1336 if(numIndexes > 0) 1337 { 1338 indexRows = new ExecIndexRow[numIndexes]; 1339 ordering = new ColumnOrdering[numIndexes][]; 1340 for (int index = 0; index < numIndexes; index++) 1341 { 1342 indexRows[index] = compressIRGs[index].getIndexRowTemplate(); 1344 compressIRGs[index].getIndexRow(emptyHeapRow, 1345 rl, 1346 indexRows[index], 1347 (FormatableBitSet) null); 1348 1353 int[] baseColumnPositions = compressIRGs[index].baseColumnPositions(); 1354 boolean[] isAscending = compressIRGs[index].isAscending(); 1355 int numColumnOrderings; 1356 numColumnOrderings = baseColumnPositions.length + 1; 1357 ordering[index] = new ColumnOrdering[numColumnOrderings]; 1358 for (int ii =0; ii < numColumnOrderings - 1; ii++) 1359 { 1360 ordering[index][ii] = new IndexColumnOrder(ii, isAscending[ii]); 1361 } 1362 ordering[index][numColumnOrderings - 1] = new IndexColumnOrder(numColumnOrderings - 1); 1363 } 1364 } 1365 1366 1375 dd.startWriting(lcc); 1376 1377 if(numIndexes > 0) 1379 { 1380 long[] newIndexCongloms = new long[numIndexes]; 1381 for (int index = 0; index < numIndexes; index++) 1382 { 1383 updateIndex(newHeapConglom, dd, index, newIndexCongloms); 1384 } 1385 } 1386 1387 long oldHeapConglom = td.getHeapConglomerateId(); 1390 ConglomerateDescriptor cd = td.getConglomerateDescriptor(oldHeapConglom); 1391 1392 dd.updateConglomerateDescriptor(cd, newHeapConglom, tc); 1394 tc.dropConglomerate(oldHeapConglom); 1396 cleanUp(); 1397 } 1398 1399 1400 1406 private void updateAllIndexes(long newHeapConglom, 1407 DataDictionary dd) 1408 throws StandardException 1409 { 1410 long[] newIndexCongloms = new long[numIndexes]; 1411 1412 1413 if (sequential) 1414 { 1415 if (numIndexes >= 1) 1417 { 1418 updateIndex(newHeapConglom, dd, 0, newIndexCongloms); 1419 } 1420 for (int index = 1; index < numIndexes; index++) 1421 { 1422 openBulkFetchScan(newHeapConglom); 1424 while (getNextRowFromRowSource() != null) 1425 { 1426 objectifyStreamingColumns(); 1427 insertIntoSorter(index, compressRL[currentCompressRow - 1]); 1428 } 1429 updateIndex(newHeapConglom, dd, index, newIndexCongloms); 1430 closeBulkFetchScan(); 1431 } 1432 } 1433 else 1434 { 1435 for (int index = 0; index < numIndexes; index++) 1436 { 1437 updateIndex(newHeapConglom, dd, index, newIndexCongloms); 1438 } 1439 } 1440 } 1441 1442 private void updateIndex(long newHeapConglom, DataDictionary dd, 1443 int index, long[] newIndexCongloms) 1444 throws StandardException 1445 { 1446 ConglomerateController indexCC; 1447 Properties properties = new Properties (); 1448 ConglomerateDescriptor cd; 1449 cd = td.getConglomerateDescriptor(indexConglomerateNumbers[index]); 1451 1452 indexCC = tc.openConglomerate( 1454 indexConglomerateNumbers[index], 1455 false, 1456 TransactionController.OPENMODE_FORUPDATE, 1457 TransactionController.MODE_TABLE, 1458 TransactionController.ISOLATION_SERIALIZABLE); 1459 1460 indexCC.getInternalTablePropertySet(properties); 1462 1463 1466 int indexRowLength = indexRows[index].nColumns(); 1467 properties.put("baseConglomerateId", Long.toString(newHeapConglom)); 1468 if (cd.getIndexDescriptor().isUnique()) 1469 { 1470 properties.put("nUniqueColumns", 1471 Integer.toString(indexRowLength - 1)); 1472 } 1473 else 1474 { 1475 properties.put("nUniqueColumns", 1476 Integer.toString(indexRowLength)); 1477 } 1478 properties.put("rowLocationColumn", 1479 Integer.toString(indexRowLength - 1)); 1480 properties.put("nKeyFields", Integer.toString(indexRowLength)); 1481 1482 indexCC.close(); 1483 1484 1488 RowLocationRetRowSource cCount = null; 1489 boolean updateStatistics = false; 1490 if(!truncateTable) 1491 { 1492 sorters[index].close(); 1493 sorters[index] = null; 1494 1495 if (td.statisticsExist(cd)) 1496 { 1497 cCount = new CardinalityCounter(tc.openSortRowSource(sortIds[index])); 1498 updateStatistics = true; 1499 } 1500 else 1501 cCount = new CardinalityCounter(tc.openSortRowSource(sortIds[index])); 1502 1503 newIndexCongloms[index] = tc.createAndLoadConglomerate( 1504 "BTREE", 1505 indexRows[index].getRowArray(), 1506 ordering[index], 1507 properties, 1508 TransactionController.IS_DEFAULT, 1509 cCount, 1510 (long[]) null); 1511 1512 if (updateStatistics) 1521 dd.dropStatisticsDescriptors(td.getUUID(), cd.getUUID(), tc); 1522 1523 long numRows; 1524 if ((numRows = ((CardinalityCounter)cCount).getRowCount()) > 0) 1525 { 1526 long[] c = ((CardinalityCounter)cCount).getCardinality(); 1527 for (int i = 0; i < c.length; i++) 1528 { 1529 StatisticsDescriptor statDesc = 1530 new StatisticsDescriptor(dd, dd.getUUIDFactory().createUUID(), 1531 cd.getUUID(), td.getUUID(), "I", new StatisticsImpl(numRows, c[i]), 1532 i + 1); 1533 dd.addDescriptor(statDesc, null, DataDictionary.SYSSTATISTICS_CATALOG_NUM, 1535 true, tc); } 1537 } 1538 }else 1539 { 1540 newIndexCongloms[index] = tc.createConglomerate( 1541 "BTREE", 1542 indexRows[index].getRowArray(), 1543 ordering[index], 1544 properties, 1545 TransactionController.IS_DEFAULT); 1546 1547 1548 if (td.statisticsExist(cd)) 1551 dd.dropStatisticsDescriptors(td.getUUID(), cd.getUUID(), tc); 1552 } 1553 1554 1562 dd.updateConglomerateDescriptor( 1563 td.getConglomerateDescriptors(indexConglomerateNumbers[index]), 1564 newIndexCongloms[index], tc); 1565 1566 tc.dropConglomerate(indexConglomerateNumbers[index]); 1568 } 1569 1570 1571 1576 private void getAffectedIndexes(Activation activation) 1577 throws StandardException 1578 { 1579 IndexLister indexLister = td.getIndexLister( ); 1580 1581 1586 compressIRGs = indexLister.getIndexRowGenerators(); 1587 numIndexes = compressIRGs.length; 1588 indexConglomerateNumbers = indexLister.getIndexConglomerateNumbers(); 1589 1590 if (! (compressTable || truncateTable)) { 1592 for (int i = 0; i < compressIRGs.length; i++) 1593 { 1594 int[] baseColumnPositions = compressIRGs[i].baseColumnPositions(); 1595 int j; 1596 for (j = 0; j < baseColumnPositions.length; j++) 1597 if (baseColumnPositions[j] == columnPosition) break; 1598 if (j == baseColumnPositions.length) continue; 1600 1601 if (baseColumnPositions.length == 1 || 1602 (behavior == StatementType.DROP_CASCADE && compressIRGs[i].isUnique())) 1603 { 1604 numIndexes--; 1605 1608 ConglomerateDescriptor cd = td.getConglomerateDescriptor 1609 (indexConglomerateNumbers[i]); 1610 DropIndexConstantAction.dropIndex(dm, dd, tc, cd, td, activation.getLanguageConnectionContext()); 1611 1612 compressIRGs[i] = null; continue; 1614 } 1615 if (compressIRGs[i].isUnique()) 1619 { 1620 ConglomerateDescriptor cd = td.getConglomerateDescriptor 1621 (indexConglomerateNumbers[i]); 1622 throw StandardException.newException(SQLState.LANG_PROVIDER_HAS_DEPENDENT_OBJECT, 1623 dm.getActionString(DependencyManager.DROP_COLUMN), 1624 columnInfo[0].name, "UNIQUE INDEX", 1625 cd.getConglomerateName() ); 1626 } 1627 } 1628 IndexRowGenerator[] newIRGs = new IndexRowGenerator[numIndexes]; 1629 long[] newIndexConglomNumbers = new long[numIndexes]; 1630 1631 for (int i = 0, j = 0; i < numIndexes; i++, j++) 1632 { 1633 while (compressIRGs[j] == null) 1634 j++; 1635 1636 int[] baseColumnPositions = compressIRGs[j].baseColumnPositions(); 1637 newIRGs[i] = compressIRGs[j]; 1638 newIndexConglomNumbers[i] = indexConglomerateNumbers[j]; 1639 1640 boolean[] isAscending = compressIRGs[j].isAscending(); 1641 boolean reMakeArrays = false; 1642 int size = baseColumnPositions.length; 1643 for (int k = 0; k < size; k++) 1644 { 1645 if (baseColumnPositions[k] > columnPosition) 1646 baseColumnPositions[k]--; 1647 else if (baseColumnPositions[k] == columnPosition) 1648 { 1649 baseColumnPositions[k] = 0; reMakeArrays = true; 1651 } 1652 } 1653 if (reMakeArrays) 1654 { 1655 size--; 1656 int[] newBCP = new int[size]; 1657 boolean[] newIsAscending = new boolean[size]; 1658 for (int k = 0, step = 0; k < size; k++) 1659 { 1660 if (step == 0 && baseColumnPositions[k + step] == 0) 1661 step++; 1662 newBCP[k] = baseColumnPositions[k + step]; 1663 newIsAscending[k] = isAscending[k + step]; 1664 } 1665 IndexDescriptor id = compressIRGs[j].getIndexDescriptor(); 1666 id.setBaseColumnPositions(newBCP); 1667 id.setIsAscending(newIsAscending); 1668 id.setNumberOfOrderedColumns(id.numberOfOrderedColumns() - 1); 1669 } 1670 } 1671 compressIRGs = newIRGs; 1672 indexConglomerateNumbers = newIndexConglomNumbers; 1673 } 1674 1675 1680 Object [] compressIndexResult = 1681 compressIndexArrays(indexConglomerateNumbers, compressIRGs); 1682 1683 if (compressIndexResult != null) 1684 { 1685 indexConglomerateNumbers = (long[]) compressIndexResult[1]; 1686 compressIRGs = (IndexRowGenerator[]) compressIndexResult[2]; 1687 numIndexes = indexConglomerateNumbers.length; 1688 } 1689 1690 indexedCols = new FormatableBitSet(compressTable || truncateTable ? td.getNumberOfColumns() + 1 : 1691 td.getNumberOfColumns()); 1692 for (int index = 0; index < numIndexes; index++) 1693 { 1694 int[] colIds = compressIRGs[index].getIndexDescriptor().baseColumnPositions(); 1695 1696 for (int index2 = 0; index2 < colIds.length; index2++) 1697 { 1698 indexedCols.set(colIds[index2]); 1699 } 1700 } 1701 } 1702 1703 1709 private void setUpAllSorts(ExecRow sourceRow, 1710 RowLocation rl) 1711 throws StandardException 1712 { 1713 ordering = new ColumnOrdering[numIndexes][]; 1714 1715 needToDropSort = new boolean[numIndexes]; 1716 sortIds = new long[numIndexes]; 1717 1718 1719 for (int index = 0; index < numIndexes; index++) 1720 { 1721 indexRows[index] = compressIRGs[index].getIndexRowTemplate(); 1723 1724 compressIRGs[index].getIndexRow(sourceRow, 1727 rl, 1728 indexRows[index], 1729 (FormatableBitSet) null); 1730 1731 1736 int[] baseColumnPositions = compressIRGs[index].baseColumnPositions(); 1737 boolean[] isAscending = compressIRGs[index].isAscending(); 1738 int numColumnOrderings; 1739 SortObserver sortObserver = null; 1740 1745 boolean reuseWrappers = (numIndexes == 1); 1746 numColumnOrderings = baseColumnPositions.length + 1; 1747 sortObserver = new BasicSortObserver(false, false, 1748 indexRows[index], 1749 reuseWrappers); 1750 ordering[index] = new ColumnOrdering[numColumnOrderings]; 1751 for (int ii =0; ii < numColumnOrderings - 1; ii++) 1752 { 1753 ordering[index][ii] = new IndexColumnOrder(ii, isAscending[ii]); 1754 } 1755 ordering[index][numColumnOrderings - 1] = new IndexColumnOrder(numColumnOrderings - 1); 1756 1757 sortIds[index] = tc.createSort( 1759 (Properties )null, 1760 indexRows[index].getRowArrayClone(), 1761 ordering[index], 1762 sortObserver, 1763 false, estimatedRowCount, -1 ); 1767 } 1768 1769 sorters = new SortController[numIndexes]; 1770 for (int index = 0; index < numIndexes; index++) 1772 { 1773 sorters[index] = tc.openSort(sortIds[index]); 1774 needToDropSort[index] = true; 1775 } 1776 } 1777 1778 1780 1783 public FormatableBitSet getValidColumns() 1784 { 1785 return null; 1787 } 1788 1789 1793 public DataValueDescriptor[] getNextRowFromRowSource() 1794 throws StandardException 1795 { 1796 currentRow = null; 1797 if ((! doneScan) && 1799 (currentCompressRow == bulkFetchSize || !validRow[currentCompressRow])) 1800 { 1801 int bulkFetched = 0; 1802 1803 bulkFetched = compressHeapGSC.fetchNextGroup(baseRowArray, compressRL); 1804 1805 doneScan = (bulkFetched != bulkFetchSize); 1806 currentCompressRow = 0; 1807 rowCount += bulkFetched; 1808 for (int index = 0; index < bulkFetched; index++) 1809 { 1810 validRow[index] = true; 1811 } 1812 for (int index = bulkFetched; index < bulkFetchSize; index++) 1813 { 1814 validRow[index] = false; 1815 } 1816 } 1817 1818 if (validRow[currentCompressRow]) 1819 { 1820 if (compressTable) 1821 currentRow = baseRow[currentCompressRow]; 1822 else 1823 { 1824 if (currentRow == null) 1825 currentRow = activation.getExecutionFactory().getValueRow(baseRowArray[currentCompressRow].length - 1); 1826 for (int i = 0; i < currentRow.nColumns(); i++) 1827 { 1828 currentRow.setColumn(i + 1, i < columnPosition - 1 ? 1829 baseRow[currentCompressRow].getColumn(i+1) : 1830 baseRow[currentCompressRow].getColumn(i+1+1)); 1831 } 1832 } 1833 currentCompressRow++; 1834 } 1835 1836 if (currentRow != null) 1837 { 1838 1843 if (compressIRGs.length > 0) 1844 { 1845 1846 currentRow = currentRow.getClone(indexedCols); 1847 } 1848 1849 return currentRow.getRowArray(); 1850 } 1851 1852 return null; 1853 } 1854 1855 1858 public boolean needsToClone() 1859 { 1860 return(true); 1861 } 1862 1863 1866 public void closeRowSource() 1867 { 1868 } 1870 1871 1872 1874 1877 public boolean needsRowLocation() 1878 { 1879 return (numIndexes > 0); 1881 } 1882 1883 1887 public void rowLocation(RowLocation rl) 1888 throws StandardException 1889 { 1890 1891 if (compressIRGs.length > 0) 1892 { 1893 objectifyStreamingColumns(); 1894 1895 1899 int maxIndex = compressIRGs.length; 1900 if (maxIndex > 1 && sequential) 1901 { 1902 maxIndex = 1; 1903 } 1904 for (int index = 0; index < maxIndex; index++) 1905 { 1906 insertIntoSorter(index, rl); 1907 } 1908 } 1909 } 1910 1911 private void objectifyStreamingColumns() 1912 throws StandardException 1913 { 1914 for (int i = 0; i < currentRow.getRowArray().length; i++) 1916 { 1917 1920 if (! indexedCols.get(i + 1)) 1921 { 1922 continue; 1923 } 1924 1925 if (currentRow.getRowArray()[i] instanceof StreamStorable) 1926 { 1927 ((DataValueDescriptor) currentRow.getRowArray()[i]).getObject(); 1928 } 1929 } 1930 } 1931 1932 private void insertIntoSorter(int index, RowLocation rl) 1933 throws StandardException 1934 { 1935 indexRows[index].getNewObjectArray(); 1937 compressIRGs[index].getIndexRow(currentRow, 1939 (RowLocation) rl.cloneObject(), 1940 indexRows[index], 1941 (FormatableBitSet) null); 1942 1943 sorters[index].insert(indexRows[index].getRowArray()); 1945 } 1946 1947 1952 public void cleanUp() throws StandardException 1953 { 1954 if (compressHeapCC != null) 1955 { 1956 compressHeapCC.close(); 1957 compressHeapCC = null; 1958 } 1959 1960 if (compressHeapGSC != null) 1961 { 1962 closeBulkFetchScan(); 1963 } 1964 1965 if (sorters != null) 1967 { 1968 for (int index = 0; index < compressIRGs.length; index++) 1969 { 1970 if (sorters[index] != null) 1971 { 1972 sorters[index].close(); 1973 } 1974 sorters[index] = null; 1975 } 1976 } 1977 1978 if (needToDropSort != null) 1979 { 1980 for (int index = 0; index < needToDropSort.length; index++) 1981 { 1982 if (needToDropSort[index]) 1983 { 1984 tc.dropSort(sortIds[index]); 1985 needToDropSort[index] = false; 1986 } 1987 } 1988 } 1989 } 1990 1991 1993 2002 private int getSemiRowCount(TransactionController tc) 2003 throws StandardException 2004 { 2005 int numRows = 0; 2006 2007 ScanController sc = tc.openScan(td.getHeapConglomerateId(), 2008 false, 0, TransactionController.MODE_TABLE, 2011 TransactionController.ISOLATION_SERIALIZABLE, 2012 RowUtil.EMPTY_ROW_BITSET, null, ScanController.GE, null, null, ScanController.GT); 2019 while (sc.next()) 2020 { 2021 numRows++; 2022 2023 if (numRows == 2) 2025 { 2026 break; 2027 } 2028 } 2029 sc.close(); 2030 2031 return numRows; 2032 } 2033 2034 2046 private void updateNewColumnToDefault 2047 ( 2048 Activation activation, 2049 String columnName, 2050 String defaultText, 2051 LanguageConnectionContext lcc 2052 ) 2053 throws StandardException 2054 { 2055 2058 String updateStmt = "UPDATE \"" + td.getSchemaName() + "\".\"" + 2059 td.getName() + "\" SET \"" + 2060 columnName + "\" = " + defaultText; 2061 2062 2063 AlterTableConstantAction.executeUpdate(lcc, updateStmt); 2064 } 2065 2066 private static void executeUpdate(LanguageConnectionContext lcc, String updateStmt) throws StandardException 2067 { 2068 PreparedStatement ps = lcc.prepareInternalStatement(updateStmt); 2069 2070 ResultSet rs = ps.execute(lcc, true, 0L); 2074 rs.close(); 2075 rs.finish(); 2076 } 2077 2078 2081 private long getColumnMax(Activation activation, TableDescriptor td, String columnName, 2082 long increment, long initial) 2083 throws StandardException 2084 { 2085 String maxStr = (increment > 0) ? "MAX" : "MIN"; 2086 String maxStmt = "SELECT " + maxStr + "(\"" + columnName + "\")" + 2087 "FROM \"" + td.getSchemaName() + "\".\"" + td.getName() + "\""; 2088 2089 2090 LanguageConnectionContext lcc = activation.getLanguageConnectionContext(); 2091 PreparedStatement ps = lcc.prepareInternalStatement(maxStmt); 2092 2093 ResultSet rs = ps.execute(lcc, false, 0L); 2096 DataValueDescriptor[] rowArray = rs.getNextRow().getRowArray(); 2097 rs.close(); 2098 rs.finish(); 2099 2100 return rowArray[0].getLong(); 2101 } 2102 2103 private void dropAllColumnDefaults(UUID tableId, DataDictionary dd) 2104 throws StandardException 2105 { 2106 ColumnDescriptorList cdl = td.getColumnDescriptorList(); 2107 int cdlSize = cdl.size(); 2108 2109 for(int index = 0; index < cdlSize; index++) 2110 { 2111 ColumnDescriptor cd = (ColumnDescriptor) cdl.elementAt(index); 2112 2113 if (cd.getDefaultInfo() != null) 2116 { 2117 DefaultDescriptor defaultDesc = cd.getDefaultDescriptor(dd); 2118 dm.clearDependencies(lcc, defaultDesc); 2119 } 2120 } 2121 } 2122 2123 private void openBulkFetchScan(long heapConglomNumber) 2124 throws StandardException 2125 { 2126 doneScan = false; 2127 compressHeapGSC = tc.openGroupFetchScan( 2128 heapConglomNumber, 2129 false, 0, TransactionController.MODE_TABLE, 2132 TransactionController.ISOLATION_SERIALIZABLE, 2133 null, (DataValueDescriptor[]) null, 0, null, (DataValueDescriptor[]) null, 0); } 2140 2141 private void closeBulkFetchScan() 2142 throws StandardException 2143 { 2144 compressHeapGSC.close(); 2145 compressHeapGSC = null; 2146 } 2147 2148 2162 private void updateNewAutoincrementColumn(Activation activation, String columnName, long initial, 2163 long increment) 2164 throws StandardException 2165 { 2166 LanguageConnectionContext lcc = activation.getLanguageConnectionContext(); 2167 2168 lcc.setAutoincrementUpdate(true); 2171 2172 lcc.autoincrementCreateCounter(td.getSchemaName(), 2173 td.getName(), 2174 columnName, new Long (initial), 2175 increment, 0); 2176 String updateStmt = "UPDATE \"" + td.getSchemaName() + "\".\"" + 2182 td.getName() + "\" SET \"" + columnName + "\" = " + 2183 "org.apache.derby.iapi.db.ConnectionInfo::" + 2184 "nextAutoincrementValue(" + 2185 "'" + td.getSchemaName() + "'" + "," + 2186 "'" + td.getName() + "'" + "," + 2187 "'" + columnName + "'" + ")"; 2188 2189 2190 2191 try 2192 { 2193 AlterTableConstantAction.executeUpdate(lcc, updateStmt); 2194 } 2195 catch (StandardException se) 2196 { 2197 if (se.getMessageId().equals(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE)) 2198 { 2199 throw StandardException.newException(SQLState.LANG_AI_OVERFLOW, 2201 se, 2202 td.getName(), 2203 columnName); 2204 } 2205 throw se; 2206 } 2207 finally 2208 { 2209 lcc.autoincrementFlushCache(td.getUUID()); 2211 lcc.setAutoincrementUpdate(false); 2212 } 2213 2214 } 2215 2229 private boolean validateNotNullConstraint 2230 ( 2231 String columnNames[], 2232 boolean nullCols[], 2233 int numRows, 2234 LanguageConnectionContext lcc, 2235 String errorMsg 2236 ) 2237 throws StandardException 2238 { 2239 boolean foundNullable = false; 2240 StringBuffer constraintText = new StringBuffer (); 2241 2242 2247 for (int colCtr = 0; colCtr < columnNames.length; colCtr++) 2248 { 2249 ColumnDescriptor cd = td.getColumnDescriptor(columnNames[colCtr]); 2250 2251 if (cd == null) 2252 { 2253 throw StandardException.newException(SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE, 2254 columnNames[colCtr], 2255 td.getName()); 2256 } 2257 2258 if (cd.getType().isNullable()) 2259 { 2260 if (numRows > 0) 2261 { 2262 if (foundNullable) 2264 constraintText.append(" AND "); 2265 constraintText.append(columnNames[colCtr] + " IS NOT NULL "); 2266 } 2267 foundNullable = true; 2268 nullCols[colCtr] = true; 2269 } 2270 } 2271 2272 2275 if (foundNullable && numRows > 0) 2276 { 2277 if (!ConstraintConstantAction.validateConstraint( 2278 (String ) null, 2279 constraintText.toString(), 2280 td, 2281 lcc, 2282 false)) 2283 { 2284 if (errorMsg.equals(SQLState.LANG_NULL_DATA_IN_PRIMARY_KEY)) 2285 { throw StandardException.newException( 2287 SQLState.LANG_NULL_DATA_IN_PRIMARY_KEY, 2288 td.getQualifiedName()); 2289 } 2290 else 2291 { throw StandardException.newException( 2293 SQLState.LANG_NULL_DATA_IN_NON_NULL_COLUMN, 2294 td.getQualifiedName(), columnNames[0]); 2295 } 2296 } 2297 } 2298 return foundNullable; 2299 } 2300 2301 2314 private Object [] compressIndexArrays( 2315 long[] indexCIDS, 2316 IndexRowGenerator[] irgs) 2317 { 2318 2324 long[] workSpace = new long[indexCIDS.length]; 2325 int j = 0, k = indexCIDS.length - 1; 2326 for (int i = 0; i < indexCIDS.length; i++) 2327 { 2328 int m; 2329 for (m = 0; m < j; m++) { 2331 if (indexCIDS[i] == workSpace[m]) { 2333 workSpace[k--] = i; break; 2335 } 2336 } 2337 if (m == j) 2338 workSpace[j++] = indexCIDS[i]; } 2340 if (j < indexCIDS.length) { 2342 long[] newIndexCIDS = new long[j]; 2343 IndexRowGenerator[] newIrgs = new IndexRowGenerator[j]; 2344 int[] duplicateIndexes = new int[indexCIDS.length - j]; 2345 k = 0; 2346 for (int m = 0, n = indexCIDS.length - 1; m < indexCIDS.length; m++) 2348 { 2349 if (m < j) 2351 newIndexCIDS[m] = workSpace[m]; 2352 else 2353 duplicateIndexes[indexCIDS.length - m - 1] = (int) workSpace[m]; 2354 2355 if ((n >= j) && (m == (int) workSpace[n])) 2357 n--; 2358 else 2359 { 2360 newIrgs[k] = irgs[m]; 2361 k++; 2362 } 2363 } 2364 2365 Object [] returnValue = new Object [3]; returnValue[0] = duplicateIndexes; 2368 returnValue[1] = newIndexCIDS; 2369 returnValue[2] = newIrgs; 2370 return returnValue; 2371 } 2372 else return null; 2374 } 2375 2376} 2377 2378 | Popular Tags |