use of org.apache.derby.iapi.types.NumberDataValue in project derby by apache.
the class DataDictionaryImpl method getSetAutoincrementValue.
/**
* @see DataDictionary#getSetAutoincrementValue
*/
public NumberDataValue getSetAutoincrementValue(RowLocation rl, TransactionController tc, boolean doUpdate, NumberDataValue newValue, boolean wait) throws StandardException {
int columnNum = SYSCOLUMNSRowFactory.SYSCOLUMNS_AUTOINCREMENTVALUE;
TabInfoImpl ti = coreInfo[SYSCOLUMNS_CORE_NUM];
ConglomerateController heapCC = null;
SYSCOLUMNSRowFactory rf = (SYSCOLUMNSRowFactory) ti.getCatalogRowFactory();
ExecRow row = rf.makeEmptyRow();
FormatableBitSet columnToRead = new FormatableBitSet(SYSCOLUMNSRowFactory.SYSCOLUMNS_COLUMN_COUNT);
// FormatableBitSet is 0 based.
// current value.
columnToRead.set(columnNum - 1);
// start value.
columnToRead.set(columnNum);
// increment value.
columnToRead.set(columnNum + 1);
try {
/* if wait is true then we need to do a wait while trying to
open/fetch from the conglomerate. note we use wait both to
open as well as fetch from the conglomerate.
*/
heapCC = tc.openConglomerate(ti.getHeapConglomerate(), false, (TransactionController.OPENMODE_FORUPDATE | ((wait) ? 0 : TransactionController.OPENMODE_LOCK_NOWAIT)), TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ);
// fetch the current value
boolean baseRowExists = heapCC.fetch(rl, row.getRowArray(), columnToRead, wait);
if (SanityManager.DEBUG) {
// We're not prepared for a non-existing base row.
SanityManager.ASSERT(baseRowExists, "base row not found");
}
// while the Row interface is 1 based.
NumberDataValue currentAI = (NumberDataValue) row.getColumn(columnNum);
long currentAIValue = currentAI.getLong();
if (doUpdate) {
// increment the value
NumberDataValue increment = (NumberDataValue) row.getColumn(columnNum + 2);
currentAI = currentAI.plus(currentAI, increment, currentAI);
row.setColumn(columnNum, currentAI);
// store the new value in SYSCOLUMNS
FormatableBitSet columnToUpdate = new FormatableBitSet(SYSCOLUMNSRowFactory.SYSCOLUMNS_COLUMN_COUNT);
// current value.
columnToUpdate.set(columnNum - 1);
heapCC.replace(rl, row.getRowArray(), columnToUpdate);
}
// incrementing it.
if (newValue != null) {
// user has passed in an object; set the current value in there and
// return it.
newValue.setValue(currentAIValue);
return newValue;
} else {
// reuse the object read from row.
currentAI.setValue(currentAIValue);
return currentAI;
}
} finally {
if (heapCC != null)
heapCC.close();
}
}
use of org.apache.derby.iapi.types.NumberDataValue in project derby by apache.
the class BaseActivation method getCurrentValueAndAdvance.
/**
* Called by generated code to get the next number in an ANSI/ISO sequence
* and advance the sequence. Raises an exception if the sequence was declared
* NO CYCLE and its range is exhausted.
*
* @param sequenceUUIDstring The string value of the sequence's UUID
* @param typeFormatID The format id of the data type to be returned. E.g., StoredFormatIds.SQL_INTEGER_ID.
*
* @return The next number in the sequence
*/
public NumberDataValue getCurrentValueAndAdvance(String sequenceUUIDstring, int typeFormatID) throws StandardException {
NumberDataValue ndv = (NumberDataValue) getDataValueFactory().getNull(typeFormatID, StringDataValue.COLLATION_TYPE_UCS_BASIC);
lcc.getDataDictionary().getCurrentValueAndAdvance(sequenceUUIDstring, ndv);
return ndv;
}
use of org.apache.derby.iapi.types.NumberDataValue in project derby by apache.
the class InsertResultSet method getOldStyleBulkInsertValue.
/**
* Identity generation logic for bulk-insert used in pre-10.11 databases.
*
* @param index 0-based index into aiCache
*/
private void getOldStyleBulkInsertValue(int index, long increment) throws StandardException {
NumberDataValue dvd;
int columnPosition = index + 1;
ColumnDescriptor cd = td.getColumnDescriptor(columnPosition);
long ret;
// System.out.println("in bulk insert");
if (aiCache[index].isNull()) {
long startValue;
if (bulkInsertReplace) {
startValue = cd.getAutoincStart();
} else {
dvd = dd.getSetAutoincrementValue(constants.autoincRowLocation[index], tc, false, (NumberDataValue) aiCache[index], true);
startValue = dvd.getLong();
}
lcc.autoincrementCreateCounter(td.getSchemaName(), td.getName(), cd.getColumnName(), Long.valueOf(startValue), increment, columnPosition);
}
ret = lcc.nextAutoincrementValue(td.getSchemaName(), td.getName(), cd.getColumnName());
aiCache[columnPosition - 1].setValue(ret);
}
use of org.apache.derby.iapi.types.NumberDataValue in project derby by apache.
the class InsertResultSet method getOldStyleIdentityValue.
/**
* Identity generation logic used in pre-10.11 databases.
*
* @param index 0-based index into aiCache
*/
private NumberDataValue getOldStyleIdentityValue(int index) throws StandardException {
NumberDataValue newValue;
TransactionController nestedTC = null;
TransactionController tcToUse;
try {
// DERBY-5780, defaulting log syncing to false, which improves
// performance of identity value generation. If system
// crashes may reuse an identity value because commit did not
// sync, but only if no subsequent user transaction has
// committed or aborted and thus no row can exist that used
// the previous value. Without this identity values pay
// a synchronous I/O to the log file for each new value no
// matter how many are inserted in a single transaction.
nestedTC = tc.startNestedUserTransaction(false, false);
tcToUse = nestedTC;
} catch (StandardException se) {
// If I cannot start a Nested User Transaction use the parent
// transaction to do all the work.
tcToUse = tc;
}
try {
/* If tcToUse == tc, then we are using parent xaction-- this
can happen if for some reason we couldn't start a nested
transaction
*/
newValue = dd.getSetAutoincrementValue(constants.autoincRowLocation[index], tcToUse, true, (NumberDataValue) aiCache[index], (tcToUse == tc));
} catch (StandardException se) {
if (tcToUse == tc) {
/* we've using the parent xaction and we've timed out; just
throw an error and exit.
*/
throw se;
}
if (se.getMessageId().equals(SQLState.LOCK_TIMEOUT) || se.isSelfDeadlock()) {
// if we couldn't do this with a nested xaction, retry with
// parent-- we need to wait this time!
newValue = dd.getSetAutoincrementValue(constants.autoincRowLocation[index], tc, true, (NumberDataValue) aiCache[index], true);
} else if (se.getMessageId().equals(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE)) {
// error message
throw StandardException.newException(SQLState.LANG_AI_OVERFLOW, se, constants.getTableName(), constants.getColumnName(index));
} else
throw se;
} finally {
if (nestedTC != null) {
// DERBY-5493 - prior to fix all nested user update
// transactions did a nosync commit when commit() was
// called, this default has been changed to do synced
// commit. Changed this commit to be commitNoSync to
// not introduce performce degredation for autoincrement
// keys. As before, if server crashes the changes
// made in the nested transaction may be lost. If any
// subsequent user transaction is commited, including any
// inserts that would depend on the autoincrement value
// change then the nested tranaction is guaranteed on
// system crash.
nestedTC.commitNoSync(TransactionController.RELEASE_LOCKS);
nestedTC.destroy();
}
}
return newValue;
}
use of org.apache.derby.iapi.types.NumberDataValue in project derby by apache.
the class InsertResultSet method getSetAutoincrementValue.
/**
* getSetAutoincrementValue will get the autoincrement value of the
* columnPosition specified for the target table. If increment is
* non-zero we will also update the autoincrement value.
*
* @param columnPosition position of the column in the table (1-based)
* @param increment amount of increment.
*
* @exception StandardException if anything goes wrong.
*/
public NumberDataValue getSetAutoincrementValue(int columnPosition, long increment) throws StandardException {
// all our indices are 0 based.
int index = columnPosition - 1;
/* As in DB2, only for single row insert: insert into t1(c1) values (..) do
* we return the correct most recently generated identity column value. For
* multiple row insert, or insert with sub-select, the return value is non-
* deterministic, and is the previous return value of the IDENTITY_VAL_LOCAL
* function, before the insert statement. Also, DB2 can have at most 1 identity
* column per table. The return value won't be affected either if Derby
* table has more than one identity columns.
*/
setIdentity = (!autoincrementGenerated) && isSourceRowResultSet();
autoincrementGenerated = true;
if (bulkInsert) {
if (identitySequenceUUIDString == null) {
getOldStyleBulkInsertValue(index, increment);
} else {
if (bulkInsertCounters[index] == null) {
bulkInsertCounters[index] = dd.getBulkInsertCounter(identitySequenceUUIDString, bulkInsertReplace);
}
bulkInsertCounters[index].getCurrentValueAndAdvance((NumberDataValue) aiCache[index]);
}
} else {
NumberDataValue newValue;
//
if (identitySequenceUUIDString == null) {
newValue = getOldStyleIdentityValue(index);
} else {
newValue = activation.getCurrentValueAndAdvance(identitySequenceUUIDString, aiCache[index].getTypeFormatId());
}
aiCache[index] = newValue;
if (setIdentity) {
identityVal = newValue.getLong();
}
}
return (NumberDataValue) aiCache[index];
}
Aggregations