📄 insertresultset.java
字号:
0, // number of columns in partial row meaningless for insert tc, null, //Changed column ids constants.getStreamStorableHeapColIds(), activation ); rowChanger.setIndexNames(constants.indexNames); } else { lcc.getStatementContext().setTopResultSet(this, subqueryTrackingArray); } /* decode lock mode for the execution isolation level */ int lockMode = UpdateResultSet.decodeLockMode(lcc, constants.lockMode); rowChanger.open(lockMode); /* The source does not know whether or not we are doing a * deferred mode insert. If we are, then we must clear the * index scan info from the activation so that the row changer * does not re-use that information (which won't be valid for * a deferred mode insert). */ if (constants.deferred) { activation.clearIndexScanInfo(); } if (fkInfoArray != null) { if (fkChecker == null) { fkChecker = new RISetChecker(tc, fkInfoArray); } else { fkChecker.reopen(); } } if (firstExecute && constants.deferred) { Properties properties = new Properties(); // Get the properties on the old heap rowChanger.getHeapConglomerateController().getInternalTablePropertySet(properties); /* ** If deferred we save a copy of the entire row. */ rowHolder = new TemporaryRowHolderImpl(tc, properties, resultDescription); rowChanger.setRowHolder(rowHolder); } int[] columnIndexes = null; if (firstExecute && activation.getAutoGeneratedKeysResultsetMode()) { ResultDescription rd; Properties properties = new Properties(); columnIndexes = activation.getAutoGeneratedKeysColumnIndexes(); // Get the properties on the old heap rowChanger.getHeapConglomerateController().getInternalTablePropertySet(properties); if ( columnIndexes != null) {//use user provided column positions array columnIndexes = uniqueColumnPositionArray(columnIndexes); } else { //prepare array of auto-generated keys for the table since user didn't provide any columnIndexes = generatedColumnPositionsArray(); } rd = lcc.getLanguageFactory().getResultDescription(resultDescription,columnIndexes); autoGeneratedKeysRowsHolder = new TemporaryRowHolderImpl(tc, properties, rd); } while ( row != null ) { if (activation.getAutoGeneratedKeysResultsetMode()) autoGeneratedKeysRowsHolder.insert(getCompactRow(row, columnIndexes)); /* ** If we're doing a deferred insert, insert into the temporary ** conglomerate. Otherwise, insert directly into the permanent ** conglomerates using the rowChanger. */ if (constants.deferred) { rowHolder.insert(row); } else { // Evaluate any check constraints on the row evaluateCheckConstraints(); if (fkChecker != null) { fkChecker.doFKCheck(row); } // Objectify any streaming columns that are indexed. if (constants.irgs.length > 0) { DataValueDescriptor[] rowArray = row.getRowArray(); for (int i = 0; i < rowArray.length; i++) { //System.out.println("checking " + i); if (! constants.indexedCols[i]) { continue; } if (rowArray[i] instanceof StreamStorable) rowArray[i].getObject(); } } rowChanger.insertRow(row); } rowCount++; // No need to do a next on a single row source if (constants.singleRowSource) { row = null; } else { row = getNextRowCore(sourceResultSet); } } /* ** If it's a deferred insert, scan the temporary conglomerate and ** insert the rows into the permanent conglomerates using rowChanger. */ if (constants.deferred) { if (triggerInfo != null) { Vector v = null; if (aiCache != null) { v = new Vector(); for (int i = 0; i < aiCache.length; i++) { String s, t, c; if (aiCache[i] == null) continue; Long initialValue = lcc.lastAutoincrementValue( (s = constants.getSchemaName()), (t = constants.getTableName()), (c = constants.getColumnName(i))); AutoincrementCounter aic = new AutoincrementCounter( initialValue, constants.getAutoincIncrement(i), aiCache[i].getLong(), s, t, c, i + 1); v.addElement(aic); } } if (triggerActivator == null) { triggerActivator = new TriggerEventActivator(lcc, tc, constants.targetUUID, triggerInfo, TriggerExecutionContext.INSERT_EVENT, activation, v); } else { triggerActivator.reopen(); } // fire BEFORE trigger, do this before checking constraints triggerActivator.notifyEvent(TriggerEvents.BEFORE_INSERT, (CursorResultSet)null, rowHolder.getResultSet()); } CursorResultSet rs = rowHolder.getResultSet(); try { rs.open(); while ((deferredRowBuffer = rs.getNextRow()) != null) { // we have to set the source row so the check constraint // sees the correct row. sourceResultSet.setCurrentRow(deferredRowBuffer); evaluateCheckConstraints(); rowChanger.insertRow(deferredRowBuffer); } } finally { sourceResultSet.clearCurrentRow(); rs.close(); } if (fkChecker != null) { /* ** Second scan to make sure all the foreign key ** constraints are ok. We have to do this after ** we have completed the inserts in case of self ** referencing constraints. */ rs = rowHolder.getResultSet(); try { rs.open(); while ((deferredRowBuffer = rs.getNextRow()) != null) { fkChecker.doFKCheck(deferredRowBuffer); } } finally { rs.close(); } } // fire AFTER trigger if (triggerActivator != null) { triggerActivator.notifyEvent(TriggerEvents.AFTER_INSERT, (CursorResultSet)null, rowHolder.getResultSet()); } } if (rowHolder != null) { rowHolder.close(); // rowHolder kept across opens } if (fkChecker != null) { fkChecker.close(); fkChecker = null; } if (setIdentity) lcc.setIdentityValue(identityVal); } /* * Take the input row and return a new compact ExecRow * using the column positions provided in columnIndexes. * Copies references, no cloning. */ private ExecRow getCompactRow ( ExecRow inputRow, int[] columnIndexes ) throws StandardException { ExecRow outRow; int numInputCols = inputRow.nColumns(); if (columnIndexes == null) { outRow = new ValueRow(numInputCols); Object[] src = inputRow.getRowArray(); Object[] dst = outRow.getRowArray(); System.arraycopy(src, 0, dst, 0, src.length); return outRow; } int numOutputCols = columnIndexes.length; outRow = new ValueRow(numOutputCols); for (int i = 0; i < numOutputCols; i++) { outRow.setColumn(i+1, inputRow.getColumn(columnIndexes[i])); } return outRow; } // Do the work for a bulk insert private long bulkInsertCore(LanguageConnectionContext lcc, long oldHeapConglom) throws StandardException { fullTemplate = constants.getEmptyHeapRow(lcc); bulkHeapCC = tc.openCompiledConglomerate( false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_TABLE, TransactionController.ISOLATION_SERIALIZABLE, constants.heapSCOCI, heapDCOCI); long newHeapConglom; Properties properties = new Properties(); // Get the properties on the old heap bulkHeapCC.getInternalTablePropertySet(properties); if (triggerInfo != null) { triggerActivator = new TriggerEventActivator(lcc, tc, constants.targetUUID, triggerInfo, TriggerExecutionContext.INSERT_EVENT, activation, null); } /* ** If we have a before row trigger, then we ** are going to use a row holder pass to our ** trigger. */ if (hasBeforeRowTrigger && rowHolder != null) { rowHolder = new TemporaryRowHolderImpl(tc, properties, resultDescription); } // Add any new properties or change the values of any existing properties Properties targetProperties = constants.getTargetProperties(); Enumeration key = targetProperties.keys(); while (key.hasMoreElements()) { String keyValue = (String) key.nextElement(); properties.put(keyValue, targetProperties.getProperty(keyValue)); } // Are there indexes to be updated? if (constants.irgs.length > 0) { // Tell source whether or not we need the RIDs back sourceResultSet.setNeedsRowLocation(true); } dd = lcc.getDataDictionary(); td = dd.getTableDescriptor(constants.targetUUID); /* Do the bulk insert - only okay to reuse the * same conglomerate if bulkInsert. */ long[] loadedRowCount = new long[1]; if (bulkInsertReplace) { newHeapConglom = tc.createAndLoadConglomerate( "heap", fullTemplate.getRowArray(), null, //column sort order - not required for heap properties, TransactionController.IS_DEFAULT, sourceResultSet, loadedRowCount); } else { newHeapConglom = tc.recreateAndLoadConglomerate( "heap", false, fullTemplate.getRowArray(), null, //column sort order - not required for heap properties, TransactionController.IS_DEFAULT, oldHeapConglom, sourceResultSet, loadedRowCount); } /* Nothing else to do if we get back the same conglomerate number. * (In 2.0 this means that 0 rows were inserted.) */ if (newHeapConglom == oldHeapConglom) { return oldHeapConglom; } // Find out how many rows were inserted rowCount = (int) loadedRowCount[0]; // Set the "estimated" row count setEstimatedRowCount(newHeapConglom); /* ** Inform the data dictionary that we are about to write to it. ** There are several calls to data dictionary "get" methods here ** that might be done in "read" mode in the data dictionary, but ** it seemed safer to do this whole operation in "write" mode. ** ** We tell the data dictionary we're done writing at the end of ** the transaction. */ dd.startWriting(lcc); lcc.autoincrementFlushCache(constants.targetUUID); // invalidate any prepared statements that // depended on this table (including this one) DependencyManager dm = dd.getDependencyManager(); dm.invalidateFor(td, DependencyManager.BULK_INSERT, lcc); // Update all indexes if (constants.irgs.length > 0) { updateAllIndexes(newHeapConglom, constants, td, dd, fullTemplate); } // Drop the old conglomerate bulkHeapCC.close(); bulkHeapCC = null; /* Update the DataDictionary * RESOLVE - this will change in 1.4 because we will get * back the same conglomerate number */ // Get the ConglomerateDescriptor for the heap ConglomerateDescriptor cd = td.getConglomerateDescriptor(oldHeapConglom); // Update sys.sysconglomerates with new conglomerate # dd.updateConglomerateDescriptor(cd, newHeapConglom, tc); tc.dropConglomerate(oldHeapConglom); // END RESOLVE return newHeapConglom; } /* ** Bulk Referential Integrity Checker */ private void bulkValidateForeignKeys(TransactionController tc, ContextManager cm)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -