use of org.apache.derby.iapi.sql.execute.ExecRow in project derby by apache.
the class TabInfoImpl method updateRow.
/**
* Updates a set of base rows in a catalog with the same key on an index
* and updates all the corresponding index rows.
*
* @param key key row
* @param newRows new version of the array of rows
* @param indexNumber index that key operates
* @param indicesToUpdate array of booleans, one for each index on the catalog.
* if a boolean is true, that means we must update the
* corresponding index because changes in the newRow
* affect it.
* @param colsToUpdate array of ints indicating which columns (1 based)
* to update. If null, do all.
* @param tc transaction controller
*
* @exception StandardException Thrown on failure
*/
void updateRow(ExecIndexRow key, ExecRow[] newRows, int indexNumber, boolean[] indicesToUpdate, int[] colsToUpdate, TransactionController tc) throws StandardException {
ConglomerateController heapCC;
ScanController drivingScan;
ExecIndexRow drivingIndexRow;
RowLocation baseRowLocation;
ExecRow baseRow = crf.makeEmptyRow();
if (SanityManager.DEBUG) {
SanityManager.ASSERT(indicesToUpdate.length == crf.getNumIndexes(), "Wrong number of indices.");
}
RowChanger rc = getRowChanger(tc, colsToUpdate, baseRow);
// Row level locking
rc.openForUpdate(indicesToUpdate, TransactionController.MODE_RECORD, true);
/* Open the heap conglomerate */
heapCC = tc.openConglomerate(getHeapConglomerate(), false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ);
drivingScan = tc.openScan(// conglomerate to open
getIndexConglomerate(indexNumber), // don't hold open across commit
false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ, // all fields as objects
(FormatableBitSet) null, // start position - first row
key.getRowArray(), // startSearchOperation
ScanController.GE, // scanQualifier
null, // stop position - through last row
key.getRowArray(), // stopSearchOperation
ScanController.GT);
// Get an index row based on the base row
drivingIndexRow = getIndexRowFromHeapRow(getIndexRowGenerator(indexNumber), heapCC.newRowLocationTemplate(), crf.makeEmptyRow());
int rowNum = 0;
while (drivingScan.fetchNext(drivingIndexRow.getRowArray())) {
baseRowLocation = (RowLocation) drivingIndexRow.getColumn(drivingIndexRow.nColumns());
boolean base_row_exists = heapCC.fetch(baseRowLocation, baseRow.getRowArray(), (FormatableBitSet) null);
if (SanityManager.DEBUG) {
// it can not be possible for heap row to disappear while
// holding scan cursor on index at ISOLATION_REPEATABLE_READ.
SanityManager.ASSERT(base_row_exists, "base row not found");
}
rc.updateRow(baseRow, (rowNum == newRows.length - 1) ? newRows[rowNum] : newRows[rowNum++], baseRowLocation);
}
rc.finish();
heapCC.close();
drivingScan.close();
rc.close();
}
use of org.apache.derby.iapi.sql.execute.ExecRow in project derby by apache.
the class TabInfoImpl method insertRowListImpl.
/**
* Insert logic to insert a list of rows into a table. This logic has two
* odd features.
*
* <OL>
* <LI>Returns an indication if any returned row was a duplicate.
* <LI>Returns the RowLocation of the last row inserted.
* </OL>
* @param rowList the list of rows to insert
* @param tc transaction controller
* @param rowLocationOut on output rowLocationOut[0] is set to the
* last RowLocation inserted.
* @return row number (>= 0) if duplicate row inserted into an index
* ROWNOTDUPLICATE otherwise
*/
private int insertRowListImpl(ExecRow[] rowList, TransactionController tc, RowLocation[] rowLocationOut) throws StandardException {
ConglomerateController heapController;
RowLocation heapLocation;
ExecIndexRow indexableRow;
int insertRetCode;
int retCode = ROWNOTDUPLICATE;
int indexCount = crf.getNumIndexes();
ConglomerateController[] indexControllers = new ConglomerateController[indexCount];
// Open the conglomerates
heapController = tc.openConglomerate(getHeapConglomerate(), false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ);
for (int ictr = 0; ictr < indexCount; ictr++) {
long conglomNumber = getIndexConglomerate(ictr);
if (conglomNumber > -1) {
indexControllers[ictr] = tc.openConglomerate(conglomNumber, false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ);
}
}
heapLocation = heapController.newRowLocationTemplate();
rowLocationOut[0] = heapLocation;
// loop through rows on this list, inserting them into system table
for (int rowNumber = 0; rowNumber < rowList.length; rowNumber++) {
ExecRow row = rowList[rowNumber];
// insert the base row and get its new location
heapController.insertAndFetchLocation(row.getRowArray(), heapLocation);
for (int ictr = 0; ictr < indexCount; ictr++) {
if (indexControllers[ictr] == null) {
continue;
}
// Get an index row based on the base row
indexableRow = getIndexRowFromHeapRow(getIndexRowGenerator(ictr), heapLocation, row);
insertRetCode = indexControllers[ictr].insert(indexableRow.getRowArray());
if (insertRetCode == ConglomerateController.ROWISDUPLICATE) {
retCode = rowNumber;
}
}
}
// Close the open conglomerates
for (int ictr = 0; ictr < indexCount; ictr++) {
if (indexControllers[ictr] == null) {
continue;
}
indexControllers[ictr].close();
}
heapController.close();
return retCode;
}
use of org.apache.derby.iapi.sql.execute.ExecRow in project derby by apache.
the class TabInfoImpl method getRowInternal.
/**
* @exception StandardException Thrown on failure
*/
private ExecRow getRowInternal(TransactionController tc, ConglomerateController heapCC, ExecIndexRow key, int indexNumber, RowLocation[] rl) throws StandardException {
ScanController drivingScan;
ExecIndexRow drivingIndexRow;
RowLocation baseRowLocation;
ExecRow baseRow = crf.makeEmptyRow();
drivingScan = tc.openScan(getIndexConglomerate(indexNumber), // don't hold open across commit
false, // open for read
0, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ, // all fields as objects
(FormatableBitSet) null, // start position - first row
key.getRowArray(), // startSearchOperation
ScanController.GE, // scanQualifier
null, // stop position - through last row
key.getRowArray(), // stopSearchOperation
ScanController.GT);
// Get an index row based on the base row
drivingIndexRow = getIndexRowFromHeapRow(getIndexRowGenerator(indexNumber), heapCC.newRowLocationTemplate(), crf.makeEmptyRow());
try {
if (drivingScan.fetchNext(drivingIndexRow.getRowArray())) {
rl[0] = baseRowLocation = (RowLocation) drivingIndexRow.getColumn(drivingIndexRow.nColumns());
boolean base_row_exists = heapCC.fetch(baseRowLocation, baseRow.getRowArray(), (FormatableBitSet) null);
if (SanityManager.DEBUG) {
// it can not be possible for heap row to disappear while
// holding scan cursor on index at ISOLATION_REPEATABLE_READ.
SanityManager.ASSERT(base_row_exists, "base row not found");
}
return baseRow;
} else {
return null;
}
} finally {
drivingScan.close();
}
}
use of org.apache.derby.iapi.sql.execute.ExecRow in project derby by apache.
the class ResultColumnList method buildEmptyRow.
/**
* Build an empty row with the size and shape of the ResultColumnList.
*
* @return an empty row of the correct size and shape.
* @exception StandardException Thrown on error
*/
public ExecRow buildEmptyRow() throws StandardException {
int columnCount = size();
ExecRow row = getExecutionFactory().getValueRow(columnCount);
int position = 1;
for (ResultColumn rc : this) {
DataTypeDescriptor dataType = rc.getTypeServices();
DataValueDescriptor dataValue = dataType.getNull();
row.setColumn(position++, dataValue);
}
return row;
}
use of org.apache.derby.iapi.sql.execute.ExecRow in project derby by apache.
the class CreateTableConstantAction method executeConstantAction.
// INTERFACE METHODS
/**
* This is the guts of the Execution-time logic for CREATE TABLE.
*
* @see ConstantAction#executeConstantAction
*
* @exception StandardException Thrown on failure
*/
public void executeConstantAction(Activation activation) throws StandardException {
TableDescriptor td;
UUID toid;
SchemaDescriptor schemaDescriptor;
ColumnDescriptor columnDescriptor;
ExecRow template;
LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
DataDictionary dd = lcc.getDataDictionary();
DependencyManager dm = dd.getDependencyManager();
TransactionController tc = lcc.getTransactionExecute();
/* Mark the activation as being for create table */
activation.setForCreateTable();
// setup for create conglomerate call:
// o create row template to tell the store what type of rows this
// table holds.
// o create array of collation id's to tell collation id of each
// column in table.
template = RowUtil.getEmptyValueRow(columnInfo.length, lcc);
int[] collation_ids = new int[columnInfo.length];
for (int ix = 0; ix < columnInfo.length; ix++) {
ColumnInfo col_info = columnInfo[ix];
if (col_info.defaultValue != null) {
/* If there is a default value, use it, otherwise use null */
template.setColumn(ix + 1, col_info.defaultValue);
} else {
template.setColumn(ix + 1, col_info.dataType.getNull());
}
// get collation info for each column.
collation_ids[ix] = col_info.dataType.getCollationType();
}
/* create the conglomerate to hold the table's rows
* RESOLVE - If we ever have a conglomerate creator
* that lets us specify the conglomerate number then
* we will need to handle it here.
*/
long conglomId = tc.createConglomerate(// we're requesting a heap conglomerate
"heap", // row template
template.getRowArray(), // column sort order - not required for heap
null, collation_ids, // properties
properties, tableType == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE ? (TransactionController.IS_TEMPORARY | TransactionController.IS_KEPT) : TransactionController.IS_DEFAULT);
/*
** 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.
*/
if (tableType != TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE)
dd.startWriting(lcc);
SchemaDescriptor sd;
if (tableType == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE)
sd = dd.getSchemaDescriptor(schemaName, tc, true);
else
sd = DDLConstantAction.getSchemaDescriptorForCreate(dd, activation, schemaName);
//
// Create a new table descriptor.
//
DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator();
if (tableType != TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE) {
td = ddg.newTableDescriptor(tableName, sd, tableType, lockGranularity);
dd.addDescriptor(td, sd, DataDictionary.SYSTABLES_CATALOG_NUM, false, tc);
} else {
td = ddg.newTableDescriptor(tableName, sd, tableType, onCommitDeleteRows, onRollbackDeleteRows);
td.setUUID(dd.getUUIDFactory().createUUID());
}
toid = td.getUUID();
// Save the TableDescriptor off in the Activation
activation.setDDLTableDescriptor(td);
/* NOTE: We must write the columns out to the system
* tables before any of the conglomerates, including
* the heap, since we read the columns before the
* conglomerates when building a TableDescriptor.
* This will hopefully reduce the probability of
* a deadlock involving those system tables.
*/
// for each column, stuff system.column
int index = 1;
ColumnDescriptor[] cdlArray = new ColumnDescriptor[columnInfo.length];
for (int ix = 0; ix < columnInfo.length; ix++) {
UUID defaultUUID = columnInfo[ix].newDefaultUUID;
/* Generate a UUID for the default, if one exists
* and there is no default id yet.
*/
if (columnInfo[ix].defaultInfo != null && defaultUUID == null) {
defaultUUID = dd.getUUIDFactory().createUUID();
}
if (// dealing with autoinc column
columnInfo[ix].autoincInc != 0) {
columnDescriptor = new ColumnDescriptor(columnInfo[ix].name, index++, columnInfo[ix].dataType, columnInfo[ix].defaultValue, columnInfo[ix].defaultInfo, td, defaultUUID, columnInfo[ix].autoincStart, columnInfo[ix].autoincInc, columnInfo[ix].autoinc_create_or_modify_Start_Increment, columnInfo[ix].autoincCycle);
//
if (dd.checkVersion(DataDictionary.DD_VERSION_DERBY_10_11, null)) {
CreateSequenceConstantAction csca = makeCSCA(columnInfo[ix], TableDescriptor.makeSequenceName(toid));
csca.executeConstantAction(activation);
}
} else {
columnDescriptor = new ColumnDescriptor(columnInfo[ix].name, index++, columnInfo[ix].dataType, columnInfo[ix].defaultValue, columnInfo[ix].defaultInfo, td, defaultUUID, columnInfo[ix].autoincStart, columnInfo[ix].autoincInc, columnInfo[ix].autoincCycle);
}
cdlArray[ix] = columnDescriptor;
}
if (tableType != TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE) {
dd.addDescriptorArray(cdlArray, td, DataDictionary.SYSCOLUMNS_CATALOG_NUM, false, tc);
}
// now add the column descriptors to the table.
ColumnDescriptorList cdl = td.getColumnDescriptorList();
for (int i = 0; i < cdlArray.length; i++) cdl.add(cdlArray[i]);
//
// Create a conglomerate desciptor with the conglomId filled in and
// add it.
//
// RESOLVE: Get information from the conglomerate descriptor which
// was provided.
//
ConglomerateDescriptor cgd = ddg.newConglomerateDescriptor(conglomId, null, false, null, false, null, toid, sd.getUUID());
if (tableType != TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE) {
dd.addDescriptor(cgd, sd, DataDictionary.SYSCONGLOMERATES_CATALOG_NUM, false, tc);
}
// add the newly added conglomerate to the table descriptor
ConglomerateDescriptorList conglomList = td.getConglomerateDescriptorList();
conglomList.add(cgd);
/* Create any constraints */
if (constraintActions != null) {
/*
** Do everything but FK constraints first,
** then FK constraints on 2nd pass.
*/
for (int conIndex = 0; conIndex < constraintActions.length; conIndex++) {
// skip fks
if (!constraintActions[conIndex].isForeignKeyConstraint()) {
constraintActions[conIndex].executeConstantAction(activation);
}
}
for (int conIndex = 0; conIndex < constraintActions.length; conIndex++) {
// only foreign keys
if (constraintActions[conIndex].isForeignKeyConstraint()) {
constraintActions[conIndex].executeConstantAction(activation);
}
}
}
//
for (int ix = 0; ix < columnInfo.length; ix++) {
addColumnDependencies(lcc, dd, td, columnInfo[ix]);
}
//
// The table itself can depend on the user defined types of its columns.
//
adjustUDTDependencies(lcc, dd, td, columnInfo, false);
if (tableType == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE) {
lcc.addDeclaredGlobalTempTable(td);
}
// Indicate that the CREATE TABLE statement itself depends on the
// table it is creating. Normally such statement dependencies are
// added during compilation, but here we have a bootstrapping issue
// because the table doesn't exist until the CREATE TABLE statement
// has been executed, so we had to defer the creation of this
// dependency until now. (DERBY-4479)
dd.getDependencyManager().addDependency(activation.getPreparedStatement(), td, lcc.getContextManager());
}
Aggregations