RowDef rowDef,
RowData rowData,
Collection<TableIndex> indexes,
BitSet tablesRequiringHKeyMaintenance,
boolean propagateHKeyChanges) {
Key hKey = getKey(session, storeData);
/*
* About propagateHKeyChanges as second to last argument to constructHKey (i.e. insertingRow):
* - If true, we're inserting a row and may need to generate a PK (for no-pk tables)
* - If this invocation is being done as part of hKey maintenance (propagate = false),
* then we are deleting and reinserting a row, and we don't want the PK value changed.
* - See bug 1020342.
*/
constructHKey(session, rowDef, rowData, hKey);
/*
* Don't check hKey uniqueness here. It would require a database access and we're not in
* in a good position to report a meaningful uniqueness violation (e.g. on the PK).
* Instead, rely on PK validation when indexes are maintained.
*/
packRowData(session, storeData, rowData);
store(session, storeData);
if(rowDef.isAutoIncrement()) {
final long location = rowDef.fieldLocation(rowData, rowDef.getAutoIncrementField());
if(location != 0) {
long autoIncrementValue = rowData.getIntegerValue((int) location, (int) (location >>> 32));
rowDef.getTableStatus().setAutoIncrement(session, autoIncrementValue);
}
}
boolean bumpCount = false;
WriteIndexRow indexRow = new WriteIndexRow(this);
for(TableIndex index : indexes) {
long zValue = -1;
SpatialColumnHandler spatialColumnHandler = null;
if (index.isSpatial()) {
spatialColumnHandler = new SpatialColumnHandler(index);
zValue = spatialColumnHandler.zValue(rowData);
}
writeIndexRow(session, index, rowData, hKey, indexRow, spatialColumnHandler, zValue, false);
// Only bump row count if PK row is written (may not be written during an ALTER)
// Bump row count *after* uniqueness checks. Avoids drift of TableStatus#getApproximateRowCount. See bug1112940.
bumpCount |= index.isPrimaryKey();
}
if(bumpCount) {
rowDef.getTableStatus().rowsWritten(session, 1);
}
for(RowListener listener : listenerService.getRowListeners()) {
listener.onInsertPost(session, rowDef.table(), hKey, rowData);
}
if(propagateHKeyChanges && rowDef.table().hasChildren()) {
/*
* Row being inserted might be the parent of orphan rows already present.
* The hKeys of these orphan rows need to be maintained. The ones of interest
* contain the PK from the inserted row, and nulls for other hKey fields nearer the root.
*/
hKey.clear();
Table table = rowDef.table();
PersistitKeyAppender hKeyAppender = PersistitKeyAppender.create(hKey, table.getName());
List<Column> pkColumns = table.getPrimaryKeyIncludingInternal().getColumns();
for(HKeySegment segment : table.hKey().segments()) {
RowDef segmentRowDef = segment.table().rowDef();
hKey.append(segmentRowDef.table().getOrdinal());
for(HKeyColumn hKeyColumn : segment.columns()) {
Column column = hKeyColumn.column();
if(pkColumns.contains(column)) {
RowDef columnTableRowDef = column.getTable().rowDef();
hKeyAppender.append(columnTableRowDef.getFieldDef(column.getPosition()), rowData);
} else {
hKey.append(null);
}
}
}
propagateDownGroup(session, rowDef.table().getAIS(), storeData, tablesRequiringHKeyMaintenance, indexRow, false);
}