1 21 22 package org.apache.derby.impl.sql.execute; 23 24 import org.apache.derby.iapi.services.loader.GeneratedMethod; 25 26 import org.apache.derby.iapi.services.context.ContextManager; 27 28 import org.apache.derby.iapi.services.monitor.Monitor; 29 30 import org.apache.derby.iapi.services.sanity.SanityManager; 31 32 import org.apache.derby.iapi.services.stream.HeaderPrintWriter; 33 import org.apache.derby.iapi.services.stream.InfoStreams; 34 import org.apache.derby.iapi.services.io.StreamStorable; 35 import org.apache.derby.iapi.services.loader.GeneratedMethod; 36 37 import org.apache.derby.iapi.error.StandardException; 38 39 import org.apache.derby.iapi.sql.StatementUtil; 40 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; 41 42 import org.apache.derby.iapi.types.DataValueDescriptor; 43 import org.apache.derby.iapi.types.TypeId; 44 import org.apache.derby.iapi.types.RowLocation; 45 46 import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor; 47 import org.apache.derby.iapi.sql.dictionary.DataDictionary; 48 import org.apache.derby.iapi.sql.dictionary.DataDictionaryContext; 49 import org.apache.derby.iapi.sql.dictionary.IndexRowGenerator; 50 import org.apache.derby.iapi.sql.dictionary.TableDescriptor; 51 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor; 52 import org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator; 53 import org.apache.derby.iapi.sql.dictionary.StatisticsDescriptor; 54 import org.apache.derby.iapi.sql.dictionary.TriggerDescriptor; 55 import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor; 56 import org.apache.derby.iapi.sql.depend.DependencyManager; 57 58 import org.apache.derby.iapi.sql.ResultColumnDescriptor ; 59 60 import org.apache.derby.iapi.reference.SQLState; 61 62 import org.apache.derby.iapi.sql.execute.ConstantAction; 63 import org.apache.derby.iapi.sql.execute.CursorResultSet; 64 import org.apache.derby.iapi.sql.execute.ExecIndexRow; 65 import org.apache.derby.iapi.sql.execute.ExecRow; 66 import org.apache.derby.iapi.sql.execute.RowChanger; 67 import org.apache.derby.iapi.sql.execute.NoPutResultSet; 68 import org.apache.derby.iapi.sql.execute.TargetResultSet; 69 70 import org.apache.derby.iapi.types.NumberDataValue; 71 72 import org.apache.derby.iapi.sql.Activation; 73 import org.apache.derby.iapi.sql.LanguageProperties; 74 import org.apache.derby.iapi.sql.ResultDescription; 75 import org.apache.derby.iapi.sql.ResultSet; 76 77 import org.apache.derby.iapi.store.access.ColumnOrdering; 78 import org.apache.derby.iapi.store.access.ConglomerateController; 79 import org.apache.derby.iapi.store.access.DynamicCompiledOpenConglomInfo; 80 import org.apache.derby.iapi.store.access.GroupFetchScanController; 81 import org.apache.derby.iapi.store.access.Qualifier; 82 import org.apache.derby.iapi.store.access.RowLocationRetRowSource; 83 import org.apache.derby.iapi.store.access.ScanController; 84 import org.apache.derby.iapi.store.access.SortObserver; 85 import org.apache.derby.iapi.store.access.SortController; 86 import org.apache.derby.iapi.store.access.StaticCompiledOpenConglomInfo; 87 import org.apache.derby.iapi.store.access.TransactionController; 88 89 import org.apache.derby.impl.sql.execute.AutoincrementCounter; 90 import org.apache.derby.impl.sql.execute.InternalTriggerExecutionContext; 91 92 import org.apache.derby.catalog.UUID; 93 import org.apache.derby.catalog.types.StatisticsImpl; 94 import org.apache.derby.iapi.db.TriggerExecutionContext; 95 import org.apache.derby.iapi.services.io.FormatableBitSet; 96 import org.apache.derby.iapi.util.StringUtil; 97 98 import java.util.Enumeration ; 99 import java.util.Hashtable ; 100 import java.util.Properties ; 101 import java.util.Vector ; 102 103 109 class InsertResultSet extends DMLWriteResultSet implements TargetResultSet 110 { 111 114 116 private NoPutResultSet sourceResultSet; 117 NoPutResultSet savedSource; 118 InsertConstantAction constants; 119 private GeneratedMethod checkGM; 120 private long heapConglom; 121 122 private ResultSet autoGeneratedKeysResultSet; 124 private TemporaryRowHolderImpl autoGeneratedKeysRowsHolder; 125 126 128 private ResultDescription resultDescription; 129 private RowChanger rowChanger; 130 131 private TransactionController tc; 132 private ExecRow row; 133 134 boolean userSpecifiedBulkInsert; 135 boolean bulkInsertPerformed; 136 137 protected boolean bulkInsert; 139 private boolean bulkInsertReplace; 140 private boolean firstRow = true; 141 private boolean[] needToDropSort; 142 143 148 private Hashtable indexConversionTable; 149 150 private FormatableBitSet indexedCols; 152 private ConglomerateController bulkHeapCC; 153 154 protected DataDictionary dd; 155 protected TableDescriptor td; 156 157 private ExecIndexRow[] indexRows; 158 private ExecRow fullTemplate; 159 private long[] sortIds; 160 private RowLocationRetRowSource[] 161 rowSources; 162 private ScanController bulkHeapSC; 163 private ColumnOrdering[][] ordering; 164 private SortController[] sorters; 165 private TemporaryRowHolderImpl rowHolder; 166 private RowLocation rl; 167 168 private boolean hasBeforeStatementTrigger; 169 private boolean hasBeforeRowTrigger; 170 private BulkTableScanResultSet tableScan; 171 172 private int numOpens; 173 private boolean firstExecute; 174 175 private FKInfo[] fkInfoArray; 177 private TriggerInfo triggerInfo; 178 private RISetChecker fkChecker; 179 private TriggerEventActivator triggerActivator; 180 184 private NumberDataValue aiCache[]; 185 186 192 protected boolean autoincrementGenerated; 193 private long identityVal; private boolean setIdentity; 195 196 197 201 public ResultDescription getResultDescription() 202 { 203 return resultDescription; 204 } 205 206 208 213 public void changedRow(ExecRow execRow, RowLocation rowLocation) 214 throws StandardException 215 { 216 if (SanityManager.DEBUG) 217 { 218 SanityManager.ASSERT(bulkInsert, 219 "bulkInsert exected to be true"); 220 } 221 222 223 if (constants.irgs.length > 0) 224 { 225 RowLocation rlClone = (RowLocation) rowLocation.cloneObject(); 226 227 for (int i = 0; i < execRow.getRowArray().length; i++) 229 { 230 if (! constants.indexedCols[i]) 231 { 232 continue; 233 } 234 235 if (execRow.getRowArray()[i] instanceof StreamStorable) 236 ((DataValueDescriptor)execRow.getRowArray()[i]).getObject(); 237 } 238 239 if (firstRow) 241 { 242 firstRow = false; 243 indexRows = new ExecIndexRow[constants.irgs.length]; 244 setUpAllSorts(execRow.getNewNullRow(), rlClone); 245 } 246 247 for (int index = 0; index < constants.irgs.length; index++) 249 { 250 indexRows[index].getNewObjectArray(); 252 constants.irgs[index].getIndexRow(execRow, 254 rlClone, 255 indexRows[index], 256 (FormatableBitSet) null); 257 258 sorters[index].insert(indexRows[index].getRowArray()); 260 } 261 } 262 } 263 264 276 public ExecRow preprocessSourceRow(ExecRow execRow) 277 throws StandardException 278 { 279 285 if (hasBeforeRowTrigger) 286 { 287 rowHolder.truncate(); 290 rowHolder.insert(execRow); 291 triggerActivator.notifyEvent(TriggerEvents.BEFORE_INSERT, 292 (CursorResultSet)null, 293 rowHolder.getResultSet()); 294 } 295 296 if (checkGM != null && !hasBeforeStatementTrigger) 297 { 298 evaluateCheckConstraints(); 299 } 300 if (constants.irgs.length > 0) 302 { 303 304 return execRow.getClone(indexedCols); 305 } 306 else 307 { 308 return execRow; 309 } 310 } 311 312 318 private void evaluateCheckConstraints() 319 throws StandardException 320 { 321 if (checkGM != null) 322 { 323 324 checkGM.invoke(activation); 328 } 329 } 330 331 335 339 InsertResultSet(NoPutResultSet source, 340 GeneratedMethod checkGM, 341 Activation activation) 342 throws StandardException 343 { 344 super(activation); 345 sourceResultSet = source; 346 constants = (InsertConstantAction) constantAction; 347 this.checkGM = checkGM; 348 heapConglom = constants.conglomId; 349 350 tc = activation.getTransactionController(); 351 fkInfoArray = constants.getFKInfo( lcc.getExecutionContext() ); 352 triggerInfo = constants.getTriggerInfo(lcc.getExecutionContext()); 353 354 358 hasBeforeStatementTrigger = (triggerInfo != null) ? 359 triggerInfo.hasTrigger(true, false) : 360 false; 361 362 hasBeforeRowTrigger = (triggerInfo != null) ? 363 triggerInfo.hasTrigger(true, true) : 364 false; 365 366 resultDescription = sourceResultSet.getResultDescription(); 367 368 String insertMode = constants.getProperty("insertMode"); 370 371 RowLocation[] rla; 372 373 if ((rla = constants.getAutoincRowLocation()) != null) 374 { 375 aiCache = 376 new NumberDataValue[rla.length]; 377 for (int i = 0; i < resultDescription.getColumnCount(); i++) 378 { 379 if (rla[i] == null) 380 continue; 381 ResultColumnDescriptor rcd = 382 resultDescription.getColumnDescriptor(i + 1); 383 aiCache[i] = (NumberDataValue)rcd.getType().getNull(); 384 } 385 } 386 387 if (insertMode != null) 388 { 389 if (StringUtil.SQLEqualsIgnoreCase(insertMode,"BULKINSERT")) 390 { 391 userSpecifiedBulkInsert = true; 392 } 393 else if (StringUtil.SQLEqualsIgnoreCase(insertMode,"REPLACE")) 394 { 395 userSpecifiedBulkInsert = true; 396 bulkInsertReplace = true; 397 bulkInsert = true; 398 399 403 if (triggerInfo != null) 404 { 405 TriggerDescriptor td = triggerInfo.getTriggerArray()[0]; 406 throw StandardException.newException(SQLState.LANG_NO_BULK_INSERT_REPLACE_WITH_TRIGGER_DURING_EXECUTION, constants.getTableName(), td.getName()); 407 } 408 } 409 } 410 411 } 413 414 417 public void open() throws StandardException 418 { 419 firstExecute = (rowChanger == null); 421 422 autoincrementGenerated = false; 423 424 dd = lcc.getDataDictionary(); 425 426 432 if(activation.getAutoGeneratedKeysResultsetMode()) 433 { 434 if (activation.getAutoGeneratedKeysColumnIndexes() != null) 435 verifyAutoGeneratedColumnsIndexes(activation.getAutoGeneratedKeysColumnIndexes()); 436 else if (activation.getAutoGeneratedKeysColumnNames() != null) 437 verifyAutoGeneratedColumnsNames(activation.getAutoGeneratedKeysColumnNames()); 438 } 439 rowCount = 0; 440 441 if (numOpens++ == 0) 442 { 443 sourceResultSet.openCore(); 444 } 445 else 446 { 447 sourceResultSet.reopenCore(); 448 } 449 450 456 if (userSpecifiedBulkInsert) 457 { 458 if (! bulkInsertReplace) 459 { 460 bulkInsert = verifyBulkInsert(); 461 } 462 else 463 { 464 getExclusiveTableLock(); 465 } 466 } 467 468 if (bulkInsert) 469 { 470 sourceResultSet.setTargetResultSet(this); 472 long baseTableConglom = bulkInsertCore(lcc, heapConglom); 473 474 if (hasBeforeStatementTrigger) 475 { 476 tableScan = getTableScanResultSet(baseTableConglom); 477 478 triggerActivator.notifyEvent(TriggerEvents.BEFORE_INSERT, 480 (CursorResultSet)null, 481 tableScan); 482 483 if (checkGM != null) 487 { 488 tableScan = getTableScanResultSet(baseTableConglom); 489 490 try 491 { 492 ExecRow currRow = null; 493 while ((currRow = tableScan.getNextRowCore()) != null) 494 { 495 sourceResultSet.setCurrentRow(currRow); 498 evaluateCheckConstraints(); 499 } 500 } finally 501 { 502 sourceResultSet.clearCurrentRow(); 503 } 504 } 505 } 506 507 bulkValidateForeignKeys(tc, lcc.getContextManager()); 508 509 if ((triggerInfo != null) && 511 (triggerInfo.hasTrigger(false, true) || 512 triggerInfo.hasTrigger(false, false))) 513 { 514 triggerActivator.notifyEvent(TriggerEvents.AFTER_INSERT, 515 (CursorResultSet)null, 516 getTableScanResultSet(baseTableConglom)); 517 } 518 bulkInsertPerformed = true; 519 } 520 else 521 { 522 row = getNextRowCore(sourceResultSet); 523 normalInsertCore(lcc, firstExecute); 524 } 525 526 527 if (lcc.getRunTimeStatisticsMode()) 528 { 529 530 savedSource = sourceResultSet; 531 } 532 533 535 if (activation.getAutoGeneratedKeysResultsetMode()) 536 autoGeneratedKeysResultSet = autoGeneratedKeysRowsHolder.getResultSet(); 537 else 538 autoGeneratedKeysResultSet = null; 539 540 cleanUp(); 541 542 if (aiCache != null) 543 { 544 Hashtable aiHashtable = new Hashtable (); 545 int numColumns = aiCache.length; 546 for (int i = 0; i < numColumns; i++) 549 { 550 if (aiCache[i] == null) 551 continue; 552 aiHashtable.put(AutoincrementCounter.makeIdentity( 553 constants.getSchemaName(), 554 constants.getTableName(), 555 constants.getColumnName(i)), 556 new Long (aiCache[i].getLong())); 557 } 558 InternalTriggerExecutionContext itec = 559 (InternalTriggerExecutionContext)lcc.getTriggerExecutionContext(); 560 if (itec == null) 561 lcc.copyHashtableToAIHT(aiHashtable); 562 else 563 itec.copyHashtableToAIHT(aiHashtable); 564 } 565 566 endTime = getCurrentTimeMillis(); 567 } 568 569 573 private void verifyAutoGeneratedColumnsIndexes(int[] columnIndexes) 574 throws StandardException 575 { 576 int size = columnIndexes.length; 577 TableDescriptor td = dd.getTableDescriptor(constants.targetUUID); 578 579 for (int i = 0; i < size; i++) 581 { 582 if (td.getColumnDescriptor(columnIndexes[i]) == null) 583 throw StandardException.newException(SQLState.LANG_COLUMN_POSITION_NOT_FOUND, new Integer (columnIndexes[i])); 584 } 585 } 586 587 592 private int[] generatedColumnPositionsArray() 593 throws StandardException 594 { 595 TableDescriptor td = dd.getTableDescriptor(constants.targetUUID); 596 ColumnDescriptor cd; 597 int size = td.getMaxColumnID(); 598 599 int[] generatedColumnPositionsArray = new int[size]; 600 int generatedColumnNumbers = 0; 601 for (int i=0; i<size; i++) { 602 generatedColumnPositionsArray[i] = -1; 603 } 604 605 for (int i=0; i<size; i++) { 606 cd = td.getColumnDescriptor(i+1); 607 if (cd.isAutoincrement()) { generatedColumnNumbers++; 609 generatedColumnPositionsArray[i] = i+1; 610 } else if (cd.getDefaultValue() != null || cd.getDefaultInfo() != null) { generatedColumnNumbers++; 612 generatedColumnPositionsArray[i] = i+1; 613 } 614 } 615 int[] returnGeneratedColumnPositionsArray = new int[generatedColumnNumbers]; 616 617 for (int i=0, j=0; i<size; i++) { 618 if (generatedColumnPositionsArray[i] != -1) 619 returnGeneratedColumnPositionsArray[j++] = generatedColumnPositionsArray[i]; 620 } 621 622 return returnGeneratedColumnPositionsArray; 623 } 624 625 629 private int[] uniqueColumnPositionArray(int[] columnIndexes) 630 throws StandardException 631 { 632 int size = columnIndexes.length; 633 TableDescriptor td = dd.getTableDescriptor(constants.targetUUID); 634 635 int[] uniqueColumnIndexes = new int[td.getMaxColumnID()]; 638 639 int uniqueColumnNumbers = 0; 640 641 642 for (int i=0; i<size; i++) { 645 if (uniqueColumnIndexes[columnIndexes[i] - 1] == 0) { 646 uniqueColumnNumbers++; 647 uniqueColumnIndexes[columnIndexes[i] - 1] = columnIndexes[i]; 648 } 649 } 650 int[] returnUniqueColumnIndexes = new int[uniqueColumnNumbers]; 651 652 for (int i=0, j=0; i<uniqueColumnIndexes.length; i++) { 654 if (uniqueColumnIndexes[i] != 0) 655 returnUniqueColumnIndexes[j++] = uniqueColumnIndexes[i]; 656 } 657 658 return returnUniqueColumnIndexes; 659 } 660 661 671 private void verifyAutoGeneratedColumnsNames(String [] columnNames) 672 throws StandardException 673 { 674 int size = columnNames.length; 675 int columnPositions[] = new int[size]; 676 677 TableDescriptor td = dd.getTableDescriptor(constants.targetUUID); 678 ColumnDescriptor cd; 679 680 for (int i = 0; i < size; i++) 681 { 682 if (columnNames[i] == null) 683 throw StandardException.newException(SQLState.LANG_COLUMN_NAME_NOT_FOUND, columnNames[i]); 684 cd = td.getColumnDescriptor(columnNames[i]); 685 if (cd == null) 686 throw StandardException.newException(SQLState.LANG_COLUMN_NAME_NOT_FOUND, columnNames[i]); 687 else 688 columnPositions[i] = cd.getPosition(); 689 } 690 activation.setAutoGeneratedKeysResultsetInfo(columnPositions, null); 691 } 692 693 696 public ResultSet getAutoGeneratedKeysResultset() 697 { 698 return autoGeneratedKeysResultSet; 699 } 700 701 702 712 public NumberDataValue 713 getSetAutoincrementValue(int columnPosition, long increment) 714 throws StandardException 715 { 716 long startValue = 0; 717 NumberDataValue dvd; 718 int index = columnPosition - 1; 720 728 setIdentity = (! autoincrementGenerated) && isSourceRowResultSet(); 729 autoincrementGenerated = true; 730 731 if (bulkInsert) 732 { 733 ColumnDescriptor cd = td.getColumnDescriptor(columnPosition); 734 long ret; 735 736 if (aiCache[index].isNull()) 739 { 740 if (bulkInsertReplace) 741 { 742 startValue = cd.getAutoincStart(); 743 } 744 else 745 { 746 dvd = dd.getSetAutoincrementValue( 747 constants.autoincRowLocation[index], 748 tc, false, aiCache[index], true); 749 startValue = dvd.getLong(); 750 } 751 lcc.autoincrementCreateCounter(td.getSchemaName(), 752 td.getName(), 753 cd.getColumnName(), 754 new Long (startValue), 755 increment, 756 columnPosition); 757 758 } 759 ret = lcc.nextAutoincrementValue(td.getSchemaName(), 760 td.getName(), 761 cd.getColumnName()); 762 aiCache[columnPosition - 1].setValue(ret); 763 } 764 765 else 766 { 767 NumberDataValue newValue; 768 TransactionController nestedTC = null, tcToUse = tc; 769 770 try 771 { 772 nestedTC = tc.startNestedUserTransaction(false); 773 tcToUse = nestedTC; 774 } 775 776 catch (StandardException se) 777 { 778 tcToUse = tc; 781 } 782 783 try 784 { 785 789 newValue = dd.getSetAutoincrementValue( 790 constants.autoincRowLocation[index], 791 tcToUse, true, aiCache[index], (tcToUse == tc)); 792 } 793 794 catch (StandardException se) 795 { 796 if (tcToUse == tc) 797 { 798 801 throw se; 802 } 803 804 if (se.getMessageId().equals(SQLState.LOCK_TIMEOUT)) 805 { 806 newValue = dd.getSetAutoincrementValue( 809 constants.autoincRowLocation[index], 810 tc, true, aiCache[index], true); 811 } 812 else if (se.getMessageId().equals(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE)) 813 { 814 throw StandardException.newException( 817 SQLState.LANG_AI_OVERFLOW, 818 se, 819 constants.getTableName(), 820 constants.getColumnName(index)); 821 } 822 else throw se; 823 } 824 finally 825 { 826 if (nestedTC != null) 830 { 831 nestedTC.commit(); 832 nestedTC.destroy(); 833 } 834 } 835 aiCache[index] = newValue; 836 if (setIdentity) 837 identityVal = newValue.getLong(); 838 } 839 840 return aiCache[index]; 841 842 } 843 844 private boolean isSourceRowResultSet () 846 { 847 boolean isRow = false; 848 if (sourceResultSet instanceof NormalizeResultSet) 849 isRow = (((NormalizeResultSet) sourceResultSet).source instanceof RowResultSet); 850 return isRow; 851 } 852 853 private boolean isSingleRowResultSet() 855 { 856 boolean isRow = false; 857 858 if (sourceResultSet instanceof RowResultSet) 859 isRow = true; 860 else if (sourceResultSet instanceof NormalizeResultSet) 861 isRow = (((NormalizeResultSet) sourceResultSet).source instanceof RowResultSet); 862 863 return isRow; 864 } 865 866 private void normalInsertCore(LanguageConnectionContext lcc, boolean firstExecute) 868 throws StandardException 869 { 870 boolean setUserIdentity = constants.hasAutoincrement() && isSingleRowResultSet(); 871 boolean firstDeferredRow = true; 872 ExecRow deferredRowBuffer = null; 873 long user_autoinc=0; 874 875 880 if (firstExecute) 881 { 882 rowChanger = lcc.getLanguageConnectionFactory().getExecutionFactory() 883 .getRowChanger( 884 heapConglom, 885 constants.heapSCOCI, 886 heapDCOCI, 887 constants.irgs, 888 constants.indexCIDS, 889 constants.indexSCOCIs, 890 indexDCOCIs, 891 0, tc, 893 null, constants.getStreamStorableHeapColIds(), 895 activation 896 ); 897 rowChanger.setIndexNames(constants.indexNames); 898 } 899 else 900 { 901 lcc.getStatementContext().setTopResultSet(this, subqueryTrackingArray); 902 } 903 904 905 int lockMode = UpdateResultSet.decodeLockMode(lcc, constants.lockMode); 906 907 rowChanger.open(lockMode); 908 909 915 if (constants.deferred) 916 { 917 activation.clearIndexScanInfo(); 918 } 919 920 if (fkInfoArray != null) 921 { 922 if (fkChecker == null) 923 { 924 fkChecker = new RISetChecker(tc, fkInfoArray); 925 } 926 else 927 { 928 fkChecker.reopen(); 929 } 930 } 931 932 if (firstExecute && constants.deferred) 933 { 934 Properties properties = new Properties(); 935 936 rowChanger.getHeapConglomerateController().getInternalTablePropertySet(properties); 938 939 942 rowHolder = new TemporaryRowHolderImpl(activation, properties, 943 resultDescription); 944 rowChanger.setRowHolder(rowHolder); 945 } 946 947 int[] columnIndexes = null; 948 if (firstExecute && activation.getAutoGeneratedKeysResultsetMode()) 949 { 950 ResultDescription rd; 951 Properties properties = new Properties(); 952 columnIndexes = activation.getAutoGeneratedKeysColumnIndexes(); 953 954 rowChanger.getHeapConglomerateController().getInternalTablePropertySet(properties); 956 957 if ( columnIndexes != null) { columnIndexes = uniqueColumnPositionArray(columnIndexes); 959 } else { columnIndexes = generatedColumnPositionsArray(); 961 } 962 963 rd = lcc.getLanguageFactory().getResultDescription(resultDescription,columnIndexes); 964 autoGeneratedKeysRowsHolder = 965 new TemporaryRowHolderImpl(activation, properties, rd); 966 } 967 968 969 while ( row != null ) 970 { 971 if (activation.getAutoGeneratedKeysResultsetMode()) 972 autoGeneratedKeysRowsHolder.insert(getCompactRow(row, columnIndexes)); 973 974 979 if (constants.deferred) 980 { 981 rowHolder.insert(row); 982 } 983 else 984 { 985 evaluateCheckConstraints(); 987 988 if (fkChecker != null) 989 { 990 fkChecker.doFKCheck(row); 991 } 992 993 if (constants.irgs.length > 0) 995 { 996 DataValueDescriptor[] rowArray = row.getRowArray(); 997 for (int i = 0; i < rowArray.length; i++) 998 { 999 if (! constants.indexedCols[i]) 1001 { 1002 continue; 1003 } 1004 1005 1006 if (rowArray[i] instanceof StreamStorable) 1007 rowArray[i].getObject(); 1008 } 1009 } 1010 rowChanger.insertRow(row); 1011 } 1012 1013 rowCount++; 1014 1015 if(setUserIdentity ) 1016 { 1017 dd = lcc.getDataDictionary(); 1018 td = dd.getTableDescriptor(constants.targetUUID); 1019 1020 int maxColumns = td.getMaxColumnID(); 1021 int col; 1022 1023 for(col=1;col<=maxColumns;col++) 1024 { 1025 ColumnDescriptor cd = td.getColumnDescriptor(col); 1026 if(cd.isAutoincrement()) 1027 { 1028 break; 1029 } 1030 } 1031 1032 if(col <= maxColumns) 1033 { 1034 DataValueDescriptor dvd = row.cloneColumn(col); 1035 user_autoinc = dvd.getLong(); 1036 } 1037 } 1038 1039 if (constants.singleRowSource) 1041 { 1042 row = null; 1043 } 1044 else 1045 { 1046 row = getNextRowCore(sourceResultSet); 1047 } 1048 } 1049 1050 1054 if (constants.deferred) 1055 { 1056 if (triggerInfo != null) 1057 { 1058 Vector v = null; 1059 if (aiCache != null) 1060 { 1061 v = new Vector (); 1062 for (int i = 0; i < aiCache.length; i++) 1063 { 1064 String s, t, c; 1065 if (aiCache[i] == null) 1066 continue; 1067 1068 Long initialValue = 1069 lcc.lastAutoincrementValue( 1070 (s = constants.getSchemaName()), 1071 (t = constants.getTableName()), 1072 (c = constants.getColumnName(i))); 1073 1074 1075 AutoincrementCounter aic = 1076 new AutoincrementCounter( 1077 initialValue, 1078 constants.getAutoincIncrement(i), 1079 aiCache[i].getLong(), 1080 s, t, c, i + 1); 1081 v.addElement(aic); 1082 } 1083 } 1084 1085 if (triggerActivator == null) 1086 { 1087 triggerActivator = new TriggerEventActivator(lcc, 1088 tc, 1089 constants.targetUUID, 1090 triggerInfo, 1091 TriggerExecutionContext.INSERT_EVENT, 1092 activation, 1093 v); 1094 } 1095 else 1096 { 1097 triggerActivator.reopen(); 1098 } 1099 1100 triggerActivator.notifyEvent(TriggerEvents.BEFORE_INSERT, 1102 (CursorResultSet)null, 1103 rowHolder.getResultSet()); 1104 } 1105 1106 CursorResultSet rs = rowHolder.getResultSet(); 1107 try 1108 { 1109 rs.open(); 1110 while ((deferredRowBuffer = rs.getNextRow()) != null) 1111 { 1112 sourceResultSet.setCurrentRow(deferredRowBuffer); 1115 evaluateCheckConstraints(); 1116 rowChanger.insertRow(deferredRowBuffer); 1117 } 1118 } finally 1119 { 1120 sourceResultSet.clearCurrentRow(); 1121 rs.close(); 1122 } 1123 1124 if (fkChecker != null) 1125 { 1126 1132 rs = rowHolder.getResultSet(); 1133 try 1134 { 1135 rs.open(); 1136 while ((deferredRowBuffer = rs.getNextRow()) != null) 1137 { 1138 fkChecker.doFKCheck(deferredRowBuffer); 1139 } 1140 } finally 1141 { 1142 rs.close(); 1143 } 1144 } 1145 1146 if (triggerActivator != null) 1148 { 1149 triggerActivator.notifyEvent(TriggerEvents.AFTER_INSERT, 1150 (CursorResultSet)null, 1151 rowHolder.getResultSet()); 1152 } 1153 } 1154 1155 if (rowHolder != null) 1156 { 1157 rowHolder.close(); 1158 } 1160 if (fkChecker != null) 1161 { 1162 fkChecker.close(); 1163 fkChecker = null; 1164 } 1165 if (setIdentity) 1166 lcc.setIdentityValue(identityVal); 1167 1171 else if(setUserIdentity ) 1172 { 1173 lcc.setIdentityValue(user_autoinc); 1174 } 1175 } 1176 1177 1182 private ExecRow getCompactRow 1183 ( 1184 ExecRow inputRow, 1185 int[] columnIndexes 1186 ) 1187 throws StandardException 1188 { 1189 ExecRow outRow; 1190 int numInputCols = inputRow.nColumns(); 1191 1192 if (columnIndexes == null) 1193 { 1194 outRow = new ValueRow(numInputCols); 1195 Object [] src = inputRow.getRowArray(); 1196 Object [] dst = outRow.getRowArray(); 1197 System.arraycopy(src, 0, dst, 0, src.length); 1198 return outRow; 1199 } 1200 1201 int numOutputCols = columnIndexes.length; 1202 1203 outRow = new ValueRow(numOutputCols); 1204 for (int i = 0; i < numOutputCols; i++) 1205 { 1206 outRow.setColumn(i+1, 1207 inputRow.getColumn(columnIndexes[i])); 1208 } 1209 1210 return outRow; 1211 } 1212 1213 private long bulkInsertCore(LanguageConnectionContext lcc, 1215 long oldHeapConglom) 1216 throws StandardException 1217 { 1218 fullTemplate = constants.getEmptyHeapRow(lcc); 1219 bulkHeapCC = tc.openCompiledConglomerate( 1220 false, 1221 TransactionController.OPENMODE_FORUPDATE, 1222 TransactionController.MODE_TABLE, 1223 TransactionController.ISOLATION_SERIALIZABLE, 1224 constants.heapSCOCI, 1225 heapDCOCI); 1226 1227 long newHeapConglom; 1228 1229 Properties properties = new Properties(); 1230 1231 bulkHeapCC.getInternalTablePropertySet(properties); 1233 1234 if (triggerInfo != null) 1235 { 1236 triggerActivator = new TriggerEventActivator(lcc, 1237 tc, 1238 constants.targetUUID, 1239 triggerInfo, 1240 TriggerExecutionContext.INSERT_EVENT, 1241 activation, null); 1242 } 1243 1244 1249 if (hasBeforeRowTrigger && rowHolder != null) 1250 { 1251 rowHolder = 1252 new TemporaryRowHolderImpl(activation, properties, 1253 resultDescription); 1254 } 1255 1256 Properties targetProperties = constants.getTargetProperties(); 1258 Enumeration key = targetProperties.keys(); 1259 while (key.hasMoreElements()) 1260 { 1261 String keyValue = (String ) key.nextElement(); 1262 properties.put(keyValue, targetProperties.getProperty(keyValue)); 1263 } 1264 1265 if (constants.irgs.length > 0) 1267 { 1268 sourceResultSet.setNeedsRowLocation(true); 1270 } 1271 1272 dd = lcc.getDataDictionary(); 1273 td = dd.getTableDescriptor(constants.targetUUID); 1274 1275 1278 long[] loadedRowCount = new long[1]; 1279 if (bulkInsertReplace) 1280 { 1281 newHeapConglom = tc.createAndLoadConglomerate( 1282 "heap", 1283 fullTemplate.getRowArray(), 1284 null, properties, 1286 TransactionController.IS_DEFAULT, 1287 sourceResultSet, 1288 loadedRowCount); 1289 } 1290 else 1291 { 1292 newHeapConglom = tc.recreateAndLoadConglomerate( 1293 "heap", 1294 false, 1295 fullTemplate.getRowArray(), 1296 null, properties, 1298 TransactionController.IS_DEFAULT, 1299 oldHeapConglom, 1300 sourceResultSet, 1301 loadedRowCount); 1302 } 1303 1304 1307 if (newHeapConglom == oldHeapConglom) 1308 { 1309 return oldHeapConglom; 1310 } 1311 1312 rowCount = (int) loadedRowCount[0]; 1314 1315 setEstimatedRowCount(newHeapConglom); 1317 1318 1327 dd.startWriting(lcc); 1328 1329 lcc.autoincrementFlushCache(constants.targetUUID); 1330 1331 DependencyManager dm = dd.getDependencyManager(); 1334 1335 dm.invalidateFor(td, DependencyManager.BULK_INSERT, lcc); 1336 1337 1338 if (constants.irgs.length > 0) 1340 { 1341 updateAllIndexes(newHeapConglom, constants, td, dd, fullTemplate); 1342 } 1343 1344 bulkHeapCC.close(); 1346 bulkHeapCC = null; 1347 1348 1352 ConglomerateDescriptor cd = td.getConglomerateDescriptor(oldHeapConglom); 1354 1355 dd.updateConglomerateDescriptor(cd, newHeapConglom, tc); 1357 tc.dropConglomerate(oldHeapConglom); 1358 1360 return newHeapConglom; 1361 } 1362 1363 1366 private void bulkValidateForeignKeys(TransactionController tc, ContextManager cm) 1367 throws StandardException 1368 { 1369 FKInfo fkInfo; 1370 1371 1378 if ((indexRows == null && !bulkInsertReplace) || 1379 fkInfoArray == null) 1380 { 1381 return; 1382 } 1383 1384 for (int i = 0; i < fkInfoArray.length; i++) 1385 { 1386 fkInfo = fkInfoArray[i]; 1387 1388 1405 if (bulkInsertReplace) 1406 { 1407 for (int index = 0; index < fkInfo.fkConglomNumbers.length; index++) 1408 { 1409 1413 if (fkInfo.fkIsSelfReferencing[index] && indexRows == null) 1414 { 1415 continue; 1416 } 1417 1418 long pkConglom; 1419 long fkConglom; 1420 1421 if (fkInfo.fkIsSelfReferencing[index]) 1422 { 1423 1426 pkConglom = ((Long )indexConversionTable.get( 1427 new Long (fkInfo.refConglomNumber))).longValue(); 1428 fkConglom = ((Long )indexConversionTable.get( 1429 new Long (fkInfo.fkConglomNumbers[index]))).longValue(); 1430 } 1431 else 1432 { 1433 1441 Long pkConglomLong = (Long )indexConversionTable.get( 1442 new Long (fkInfo.refConglomNumber)); 1443 Long fkConglomLong = (Long )indexConversionTable.get( 1444 new Long (fkInfo.fkConglomNumbers[index])); 1445 if (pkConglomLong == null) 1446 { 1447 pkConglom = fkInfo.refConglomNumber; 1448 } 1449 else 1450 { 1451 pkConglom = pkConglomLong.longValue(); 1452 } 1453 if (fkConglomLong == null) 1454 { 1455 fkConglom = fkInfo.fkConglomNumbers[index]; 1456 } 1457 else 1458 { 1459 fkConglom = fkConglomLong.longValue(); 1460 } 1461 } 1462 bulkValidateForeignKeysCore( 1463 tc, cm, fkInfoArray[i], fkConglom, pkConglom, 1464 fkInfo.fkConstraintNames[index]); 1465 } 1466 } 1467 else 1468 { 1469 1475 if (SanityManager.DEBUG) 1476 { 1477 SanityManager.ASSERT(fkInfo.type == FKInfo.FOREIGN_KEY, 1478 "error, expected to only check foreign keys on insert"); 1479 } 1480 Long fkConglom = (Long )indexConversionTable.get( 1481 new Long (fkInfo.fkConglomNumbers[0])); 1482 bulkValidateForeignKeysCore( 1483 tc, cm, fkInfoArray[i], fkConglom.longValue(), 1484 fkInfo.refConglomNumber, fkInfo.fkConstraintNames[0]); 1485 } 1486 } 1487 } 1488 1489 private void bulkValidateForeignKeysCore( 1490 TransactionController tc, ContextManager cm, 1491 FKInfo fkInfo, long fkConglom, long pkConglom, 1492 String fkConstraintName) 1493 throws StandardException 1494 { 1495 ExecRow template; 1496 GroupFetchScanController refScan = null; 1497 GroupFetchScanController fkScan = null; 1498 1499 try 1500 { 1501 1502 template = makeIndexTemplate(fkInfo, fullTemplate, cm); 1503 1504 1508 fkScan = 1509 tc.openGroupFetchScan( 1510 fkConglom, 1511 false, 0, tc.MODE_TABLE, tc.ISOLATION_READ_COMMITTED, (FormatableBitSet)null, (DataValueDescriptor[])null, ScanController.GE, null, (DataValueDescriptor[])null, ScanController.GT ); 1524 1525 if (SanityManager.DEBUG) 1526 { 1527 1537 if (! bulkInsertReplace) 1538 { 1539 SanityManager.ASSERT(fkScan.next(), 1540 "No rows in fk index, even though indexRows != null"); 1541 1542 1545 fkScan.reopenScan( 1546 (DataValueDescriptor[])null, ScanController.GE, null, (DataValueDescriptor[])null, ScanController.GT ); 1552 } 1553 } 1554 1555 1560 refScan = 1561 tc.openGroupFetchScan( 1562 pkConglom, 1563 false, 0, (fkConglom == pkConglom) ? 1566 tc.MODE_TABLE : 1567 tc.MODE_RECORD, 1568 tc.ISOLATION_READ_COMMITTED, (FormatableBitSet)null, (DataValueDescriptor[])null, ScanController.GE, null, (DataValueDescriptor[])null, ScanController.GT ); 1577 1578 1582 ExecRow firstFailedRow = template.getClone(); 1583 RIBulkChecker riChecker = new RIBulkChecker(refScan, 1584 fkScan, 1585 template, 1586 true, (ConglomerateController)null, 1588 firstFailedRow); 1589 1590 int numFailures = riChecker.doCheck(); 1591 if (numFailures > 0) 1592 { 1593 StandardException se = StandardException.newException(SQLState.LANG_FK_VIOLATION, fkConstraintName, 1594 fkInfo.tableName, 1595 StatementUtil.typeName(fkInfo.stmtType), 1596 RowUtil.toString(firstFailedRow, 0, fkInfo.colArray.length - 1)); 1597 throw se; 1598 } 1599 } 1600 finally 1601 { 1602 if (fkScan != null) 1603 { 1604 fkScan.close(); 1605 fkScan = null; 1606 } 1607 if (refScan != null) 1608 { 1609 refScan.close(); 1610 refScan = null; 1611 } 1612 } 1613 } 1614 1615 1618 private ExecRow makeIndexTemplate(FKInfo fkInfo, ExecRow fullTemplate, ContextManager cm) 1619 throws StandardException 1620 { 1621 ExecRow newRow = RowUtil.getEmptyIndexRow(fkInfo.colArray.length+1, cm); 1622 1623 DataValueDescriptor[] templateColArray = fullTemplate.getRowArray(); 1624 DataValueDescriptor[] newRowColArray = newRow.getRowArray(); 1625 1626 int i; 1627 for (i = 0; i < fkInfo.colArray.length; i++) 1628 { 1629 newRowColArray[i] = 1630 (templateColArray[fkInfo.colArray[i] - 1]).getClone(); 1631 } 1632 1633 newRowColArray[i] = 1634 (DataValueDescriptor) fkInfo.rowLocation.cloneObject(); 1635 1636 return newRow; 1637 } 1638 1639 1645 private void setUpAllSorts(ExecRow sourceRow, 1646 RowLocation rl) 1647 throws StandardException 1648 { 1649 int numIndexes = constants.irgs.length; 1650 int numColumns = td.getNumberOfColumns(); 1651 1652 ordering = new ColumnOrdering[numIndexes][]; 1653 needToDropSort = new boolean[numIndexes]; 1654 sortIds = new long[numIndexes]; 1655 rowSources = new RowLocationRetRowSource[numIndexes]; 1656 indexedCols = new FormatableBitSet(numColumns + 1); 1658 1659 1660 1661 for (int index = 0; index < numIndexes; index++) 1662 { 1663 int[] keyColumns = constants.irgs[index].baseColumnPositions(); 1665 for (int i2 = 0; i2 < keyColumns.length; i2++) 1666 { 1667 indexedCols.set(keyColumns[i2]); 1669 } 1670 1671 indexRows[index] = constants.irgs[index].getIndexRowTemplate(); 1673 1674 constants.irgs[index].getIndexRow(sourceRow, 1677 rl, 1678 indexRows[index], 1679 (FormatableBitSet) null); 1680 1681 1686 ConglomerateDescriptor cd; 1687 cd = td.getConglomerateDescriptor(constants.indexCIDS[index]); 1689 int[] baseColumnPositions = constants.irgs[index].baseColumnPositions(); 1690 boolean[] isAscending = constants.irgs[index].isAscending(); 1691 int numColumnOrderings; 1692 SortObserver sortObserver = null; 1693 1698 boolean reuseWrappers = (numIndexes == 1); 1699 if (cd.getIndexDescriptor().isUnique()) 1700 { 1701 numColumnOrderings = baseColumnPositions.length; 1702 String [] columnNames = getColumnNames(baseColumnPositions); 1703 1704 String indexOrConstraintName = cd.getConglomerateName(); 1705 if (cd.isConstraint()) { 1707 ConstraintDescriptor conDesc = dd.getConstraintDescriptor(td, 1708 cd.getUUID()); 1709 indexOrConstraintName = conDesc.getConstraintName(); 1710 } 1711 sortObserver = new UniqueIndexSortObserver( 1712 false, cd.isConstraint(), 1714 indexOrConstraintName, 1715 indexRows[index], 1716 reuseWrappers, 1717 td.getName()); 1718 } 1719 else 1720 { 1721 numColumnOrderings = baseColumnPositions.length + 1; 1722 sortObserver = new BasicSortObserver(false, false, 1723 indexRows[index], 1724 reuseWrappers); 1725 } 1726 ordering[index] = new ColumnOrdering[numColumnOrderings]; 1727 for (int ii =0; ii < isAscending.length; ii++) 1728 { 1729 ordering[index][ii] = new IndexColumnOrder(ii, isAscending[ii]); 1730 } 1731 if (numColumnOrderings > isAscending.length) 1732 ordering[index][isAscending.length] = new IndexColumnOrder(isAscending.length); 1733 1734 sortIds[index] = tc.createSort( 1736 (Properties)null, 1737 indexRows[index].getRowArrayClone(), 1738 ordering[index], 1739 sortObserver, 1740 false, (int) sourceResultSet.getEstimatedRowCount(), -1 ); 1744 needToDropSort[index] = true; 1745 } 1746 1747 sorters = new SortController[numIndexes]; 1748 1749 for (int index = 0; index < numIndexes; index++) 1751 { 1752 sorters[index] = tc.openSort(sortIds[index]); 1753 needToDropSort[index] = true; 1754 } 1755 } 1756 1757 1763 private void updateAllIndexes(long newHeapConglom, 1764 InsertConstantAction constants, 1765 TableDescriptor td, 1766 DataDictionary dd, 1767 ExecRow fullTemplate) 1768 throws StandardException 1769 { 1770 int numIndexes = constants.irgs.length; 1771 1772 1777 if (indexRows == null) 1778 { 1779 if (bulkInsertReplace) 1780 { 1781 emptyIndexes(newHeapConglom, constants, td, dd, fullTemplate); 1782 } 1783 return; 1784 } 1785 1786 dd.dropStatisticsDescriptors(td.getUUID(), null, tc); 1787 long[] newIndexCongloms = new long[numIndexes]; 1788 1789 indexConversionTable = new Hashtable (numIndexes); 1790 for (int index = 0; index < numIndexes; index++) 1792 { 1793 ConglomerateController indexCC; 1794 Properties properties = new Properties(); 1795 ConglomerateDescriptor cd; 1796 cd = td.getConglomerateDescriptor(constants.indexCIDS[index]); 1798 1799 1800 indexCC = tc.openCompiledConglomerate( 1802 false, 1803 TransactionController.OPENMODE_FORUPDATE, 1804 TransactionController.MODE_TABLE, 1805 TransactionController.ISOLATION_SERIALIZABLE, 1806 constants.indexSCOCIs[index], 1807 indexDCOCIs[index]); 1808 1809 indexCC.getInternalTablePropertySet(properties); 1811 1812 1815 int indexRowLength = indexRows[index].nColumns(); 1816 properties.put("baseConglomerateId", Long.toString(newHeapConglom)); 1817 if (cd.getIndexDescriptor().isUnique()) 1818 { 1819 properties.put("nUniqueColumns", 1820 Integer.toString(indexRowLength - 1)); 1821 } 1822 else 1823 { 1824 properties.put("nUniqueColumns", 1825 Integer.toString(indexRowLength)); 1826 } 1827 properties.put("rowLocationColumn", 1828 Integer.toString(indexRowLength - 1)); 1829 properties.put("nKeyFields", Integer.toString(indexRowLength)); 1830 1831 indexCC.close(); 1832 1833 sorters[index].close(); 1837 sorters[index] = null; 1838 rowSources[index] = new CardinalityCounter(tc.openSortRowSource(sortIds[index])); 1839 newIndexCongloms[index] = tc.createAndLoadConglomerate( 1840 "BTREE", 1841 indexRows[index].getRowArray(), 1842 ordering[index], 1843 properties, 1844 TransactionController.IS_DEFAULT, 1845 rowSources[index], 1846 (long[]) null); 1847 1848 CardinalityCounter cCount = (CardinalityCounter)rowSources[index]; 1849 long numRows; 1850 if ((numRows = cCount.getRowCount()) > 0) 1851 { 1852 long[] c = cCount.getCardinality(); 1853 DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator(); 1854 1855 for (int i= 0; i < c.length; i++) 1856 { 1857 StatisticsDescriptor statDesc = 1858 new StatisticsDescriptor(dd, dd.getUUIDFactory().createUUID(), 1859 cd.getUUID(), td.getUUID(), 1860 "I", new 1861 StatisticsImpl(numRows, 1862 c[i]), 1863 i + 1); 1864 dd.addDescriptor(statDesc, null, 1865 DataDictionary.SYSSTATISTICS_CATALOG_NUM, 1866 true, tc); 1867 } 1868 1869 } 1870 1871 1879 dd.updateConglomerateDescriptor( 1880 td.getConglomerateDescriptors(constants.indexCIDS[index]), 1881 newIndexCongloms[index], tc); 1882 1883 tc.dropConglomerate(constants.indexCIDS[index]); 1885 1886 indexConversionTable.put(new Long (constants.indexCIDS[index]), 1887 new Long (newIndexCongloms[index])); 1888 } 1889 } 1890 1891 1896 public void cleanUp() throws StandardException 1897 { 1898 1899 if (tableScan != null) 1900 { 1901 tableScan.close(); 1902 tableScan = null; 1903 } 1904 1905 if (triggerActivator != null) 1906 { 1907 triggerActivator.cleanup(); 1908 } 1910 1911 1912 if (sourceResultSet != null) 1913 { 1914 sourceResultSet.close(); 1915 } 1917 numOpens = 0; 1918 1919 if (rowChanger != null) 1920 { 1921 rowChanger.close(); 1922 } 1923 1924 if (rowHolder != null) 1925 { 1926 rowHolder.close(); 1927 } 1928 1929 if (fkChecker != null) 1930 { 1931 fkChecker.close(); 1932 } 1934 1935 if (bulkHeapCC != null) 1936 { 1937 bulkHeapCC.close(); 1938 bulkHeapCC = null; 1939 } 1940 1941 if (bulkHeapSC != null) 1942 { 1943 bulkHeapSC.close(); 1944 bulkHeapSC = null; 1945 } 1946 1947 if (sorters != null) 1949 { 1950 for (int index = 0; index < constants.irgs.length; index++) 1951 { 1952 if (sorters[index] != null) 1953 { 1954 sorters[index].close(); 1955 } 1956 sorters[index] = null; 1957 } 1958 } 1959 1960 if (needToDropSort != null) 1961 { 1962 for (int index = 0; index < needToDropSort.length; index++) 1963 { 1964 if (needToDropSort[index]) 1965 { 1966 tc.dropSort(sortIds[index]); 1967 needToDropSort[index] = false; 1968 } 1969 } 1970 } 1971 1972 if (rowSources != null) 1973 { 1974 for (int index = 0; index < rowSources.length; index++) 1975 { 1976 if (rowSources[index] != null) 1977 { 1978 rowSources[index].closeRowSource(); 1979 rowSources[index] = null; 1980 } 1981 } 1982 } 1983 super.close(); 1984 } 1985 1986 1988 2001 protected boolean verifyBulkInsert() 2002 throws StandardException 2003 { 2004 if (constants.deferred) 2006 { 2007 2010 if (SanityManager.DEBUG) 2011 { 2012 SanityManager.ASSERT(! bulkInsertReplace, 2013 "bulkInsertReplace expected to be false for deferred mode inserts"); 2014 } 2015 return false; 2016 } 2017 2018 return getExclusiveTableLock(); 2019 } 2020 2021 2030 private boolean getExclusiveTableLock() 2031 throws StandardException 2032 { 2033 boolean rowFound = false; 2034 2035 bulkHeapSC = tc.openCompiledScan( 2036 false, 2037 TransactionController.OPENMODE_FORUPDATE, 2038 TransactionController.MODE_TABLE, 2039 TransactionController.ISOLATION_SERIALIZABLE, 2040 (FormatableBitSet) null, 2041 (DataValueDescriptor[]) null, 2042 0, 2043 (Qualifier[][]) null, 2044 (DataValueDescriptor[]) null, 2045 0, 2046 constants.heapSCOCI, 2047 heapDCOCI); 2048 2049 2053 if (! bulkInsertReplace) 2054 { 2055 rowFound = bulkHeapSC.next(); 2056 } 2057 else 2058 { 2059 rl = bulkHeapSC.newRowLocationTemplate(); 2060 } 2061 2062 bulkHeapSC.close(); 2063 bulkHeapSC = null; 2064 2065 return ! rowFound; 2066 } 2067 2068 2075 private void setEstimatedRowCount(long heapConglom) 2076 throws StandardException 2077 { 2078 bulkHeapSC = tc.openCompiledScan( 2079 false, 2080 TransactionController.OPENMODE_FORUPDATE, 2081 TransactionController.MODE_TABLE, 2082 TransactionController.ISOLATION_SERIALIZABLE, 2083 (FormatableBitSet) null, 2084 (DataValueDescriptor[]) null, 2085 0, 2086 (Qualifier[][]) null, 2087 (DataValueDescriptor[]) null, 2088 0, 2089 constants.heapSCOCI, 2090 heapDCOCI); 2091 2092 bulkHeapSC.setEstimatedRowCount(rowCount); 2093 2094 bulkHeapSC.close(); 2095 bulkHeapSC = null; 2096 } 2097 2098 2110 private void emptyIndexes(long newHeapConglom, 2111 InsertConstantAction constants, 2112 TableDescriptor td, 2113 DataDictionary dd, 2114 ExecRow fullTemplate) 2115 throws StandardException 2116 { 2117 int numIndexes = constants.irgs.length; 2118 ExecIndexRow[] indexRows = new ExecIndexRow[numIndexes]; 2119 ExecRow baseRows = null; 2120 ColumnOrdering[][] ordering = new ColumnOrdering[numIndexes][]; 2121 int numColumns = td.getNumberOfColumns(); 2122 2123 FormatableBitSet bitSet = new FormatableBitSet(numColumns + 1); 2125 int numReferencedColumns = 0; 2127 for (int index = 0; index < numIndexes; index++) 2128 { 2129 int[] baseColumnPositions = constants.irgs[index].baseColumnPositions(); 2130 for (int bcp = 0; bcp < baseColumnPositions.length; bcp++) 2131 { 2132 if (! bitSet.get(baseColumnPositions[bcp])) 2133 { 2134 bitSet.set(baseColumnPositions[bcp] ); 2135 numReferencedColumns++; 2136 } 2137 } 2138 } 2139 2140 baseRows = activation.getExecutionFactory().getValueRow(numReferencedColumns); 2142 2143 int colNumber = 0; 2145 for (int index = 0; index < numColumns; index++) 2146 { 2147 if (bitSet.get(index + 1)) 2148 { 2149 colNumber++; 2150 baseRows.setColumn( 2152 colNumber, 2153 fullTemplate.getColumn(index + 1).getClone()); 2154 } 2155 } 2156 2157 needToDropSort = new boolean[numIndexes]; 2158 sortIds = new long[numIndexes]; 2159 2160 2163 for (int index = 0; index < numIndexes; index++) 2164 { 2165 indexRows[index] = constants.irgs[index].getIndexRowTemplate(); 2167 2168 constants.irgs[index].getIndexRow(baseRows, 2171 rl, 2172 indexRows[index], 2173 bitSet); 2174 2175 2180 ConglomerateDescriptor cd; 2181 cd = td.getConglomerateDescriptor(constants.indexCIDS[index]); 2183 int[] baseColumnPositions = constants.irgs[index].baseColumnPositions(); 2184 boolean[] isAscending = constants.irgs[index].isAscending(); 2185 int numColumnOrderings; 2186 SortObserver sortObserver = null; 2187 if (cd.getIndexDescriptor().isUnique()) 2188 { 2189 numColumnOrderings = baseColumnPositions.length; 2190 String [] columnNames = getColumnNames(baseColumnPositions); 2191 2192 String indexOrConstraintName = cd.getConglomerateName(); 2193 if (cd.isConstraint()) { 2195 ConstraintDescriptor conDesc = dd.getConstraintDescriptor(td, 2196 cd.getUUID()); 2197 indexOrConstraintName = conDesc.getConstraintName(); 2198 } 2199 sortObserver = new UniqueIndexSortObserver( 2200 false, cd.isConstraint(), 2202 indexOrConstraintName, 2203 indexRows[index], 2204 true, 2205 td.getName()); 2206 } 2207 else 2208 { 2209 numColumnOrderings = baseColumnPositions.length + 1; 2210 sortObserver = new BasicSortObserver(false, false, 2211 indexRows[index], 2212 true); 2213 } 2214 ordering[index] = new ColumnOrdering[numColumnOrderings]; 2215 for (int ii =0; ii < isAscending.length; ii++) 2216 { 2217 ordering[index][ii] = new IndexColumnOrder(ii, isAscending[ii]); 2218 } 2219 if (numColumnOrderings > isAscending.length) 2220 ordering[index][isAscending.length] = new IndexColumnOrder(isAscending.length); 2221 2222 sortIds[index] = tc.createSort( 2224 (Properties)null, 2225 indexRows[index].getRowArrayClone(), 2226 ordering[index], 2227 sortObserver, 2228 false, rowCount, -1 ); 2232 needToDropSort[index] = true; 2233 } 2234 2235 rowSources = new RowLocationRetRowSource[numIndexes]; 2239 SortController[] sorters = new SortController[numIndexes]; 2241 for (int index = 0; index < numIndexes; index++) 2242 { 2243 sorters[index] = tc.openSort(sortIds[index]); 2244 sorters[index].close(); 2245 rowSources[index] = tc.openSortRowSource(sortIds[index]); 2246 } 2247 2248 long[] newIndexCongloms = new long[numIndexes]; 2249 2250 for (int index = 0; index < numIndexes; index++) 2252 { 2253 ConglomerateController indexCC; 2254 Properties properties = new Properties(); 2255 ConglomerateDescriptor cd; 2256 cd = td.getConglomerateDescriptor(constants.indexCIDS[index]); 2258 2259 2260 indexCC = tc.openCompiledConglomerate( 2262 false, 2263 TransactionController.OPENMODE_FORUPDATE, 2264 TransactionController.MODE_TABLE, 2265 TransactionController.ISOLATION_SERIALIZABLE, 2266 constants.indexSCOCIs[index], 2267 indexDCOCIs[index]); 2268 2269 indexCC.getInternalTablePropertySet(properties); 2271 2272 2275 int indexRowLength = indexRows[index].nColumns(); 2276 properties.put("baseConglomerateId", Long.toString(newHeapConglom)); 2277 if (cd.getIndexDescriptor().isUnique()) 2278 { 2279 properties.put("nUniqueColumns", 2280 Integer.toString(indexRowLength - 1)); 2281 } 2282 else 2283 { 2284 properties.put("nUniqueColumns", 2285 Integer.toString(indexRowLength)); 2286 } 2287 properties.put("rowLocationColumn", 2288 Integer.toString(indexRowLength - 1)); 2289 properties.put("nKeyFields", Integer.toString(indexRowLength)); 2290 2291 indexCC.close(); 2292 2293 newIndexCongloms[index] = tc.createAndLoadConglomerate( 2297 "BTREE", 2298 indexRows[index].getRowArray(), 2299 null, properties, 2301 TransactionController.IS_DEFAULT, 2302 rowSources[index], 2303 (long[]) null); 2304 2305 2311 dd.updateConglomerateDescriptor( 2312 td.getConglomerateDescriptors(constants.indexCIDS[index]), 2313 newIndexCongloms[index], tc); 2314 2315 tc.dropConglomerate(constants.indexCIDS[index]); 2317 } 2318 } 2319 2320 2324 private BulkTableScanResultSet getTableScanResultSet 2325 ( 2326 long conglomId 2327 ) throws StandardException 2328 { 2329 if (tableScan == null) 2330 { 2331 tableScan = new BulkTableScanResultSet( 2332 conglomId, 2333 tc.getStaticCompiledConglomInfo(conglomId), 2334 activation, 2335 new MyRowAllocator(fullTemplate), 0, (GeneratedMethod)null, 0, (GeneratedMethod)null, 0, false, 2342 (Qualifier[][])null, "tableName", 2344 (String )null, 2345 (String )null, false, false, -1, -1, 2350 tc.MODE_TABLE, 2351 true, tc.ISOLATION_READ_COMMITTED, 2353 LanguageProperties.BULK_FETCH_DEFAULT_INT, false, 0d, 0d ); 2358 tableScan.openCore(); 2359 } 2360 else 2361 { 2362 tableScan.reopenCore(); 2363 } 2364 return tableScan; 2365 } 2366 2367 private String [] getColumnNames(int[] baseColumnPositions) 2368 { 2369 int length = baseColumnPositions.length; 2370 String [] columnNames = new String [length]; 2371 for(int i = 0; i < length; i++) 2372 { 2373 columnNames[i] = constants.getColumnName(i); 2374 } 2375 return columnNames; 2376 } 2377 2378 public void finish() throws StandardException { 2379 sourceResultSet.finish(); 2380 super.finish(); 2381 } 2382 2383 2384 class MyRowAllocator implements GeneratedMethod 2386 { 2387 private ExecRow row; 2388 MyRowAllocator(ExecRow row) 2389 { 2390 this.row = row; 2391 } 2392 2393 public Object invoke(Object ref) 2394 { 2395 return row.getClone(); 2396 } 2397 } 2398} 2399 2400 | Popular Tags |