* @return Result object
*/
Result executeMergeStatement(Session session) {
Result resultOut = null;
RowSetNavigator generatedNavigator = null;
PersistentStore store = session.sessionData.getRowStore(baseTable);
if (generatedIndexes != null) {
resultOut = Result.newUpdateCountResult(generatedResultMetaData,
0);
generatedNavigator = resultOut.getChainedResult().getNavigator();
}
int count = 0;
// data generated for non-matching rows
RowSetNavigatorClient newData = new RowSetNavigatorClient(8);
// rowset for update operation
HashMappedList updateRowSet = new HashMappedList();
RangeVariable[] joinRangeIterators = targetRangeVariables;
// populate insert and update lists
RangeIterator[] rangeIterators =
new RangeIterator[joinRangeIterators.length];
for (int i = 0; i < joinRangeIterators.length; i++) {
rangeIterators[i] = joinRangeIterators[i].getIterator(session);
}
for (int currentIndex = 0; 0 <= currentIndex; ) {
RangeIterator it = rangeIterators[currentIndex];
boolean beforeFirst = it.isBeforeFirst();
if (it.next()) {
if (currentIndex < joinRangeIterators.length - 1) {
currentIndex++;
continue;
}
} else {
if (currentIndex == 1 && beforeFirst) {
Object[] data = getMergeInsertData(session);
if (data != null) {
newData.add(data);
}
}
it.reset();
currentIndex--;
continue;
}
// row matches!
if (updateExpressions != null) {
Row row = it.getCurrentRow(); // this is always the second iterator
Object[] data = getUpdatedData(session, baseTable,
updateColumnMap,
updateExpressions,
baseTable.getColumnTypes(),
row.getData());
updateRowSet.add(row, data);
}
}
// run the transaction as a whole, updating and inserting where needed
// update any matched rows
if (updateRowSet.size() > 0) {
count = update(session, baseTable, updateRowSet);
}
// insert any non-matched rows
newData.beforeFirst();
while (newData.hasNext()) {
Object[] data = (Object[]) newData.getNext();
baseTable.insertRow(session, store, data);
if (generatedNavigator != null) {
Object[] generatedValues = getGeneratedColumns(data);
generatedNavigator.add(generatedValues);
}
}
baseTable.fireAfterTriggers(session, Trigger.INSERT_AFTER, newData);