onlineAt(OnlineDDLMonitor.Stage.PRE_METADATA);
final AISValidatorPair pair = txnService.run(session, new Callable<AISValidatorPair>() {
@Override
public AISValidatorPair call() {
AkibanInformationSchema origAIS = getAIS(session);
Table origTable = origAIS.getTable(tableName);
schemaManager().startOnline(session);
TableChangeValidator validator = alterTableDefinitions(
session, origTable, newDefinition, columnChanges, tableIndexChanges
);
List<ChangeSet> changeSets = buildChangeSets(
origAIS,
schemaManager().getOnlineAIS(session),
origTable.getTableId(),
validator
);
for(ChangeSet cs : changeSets) {
schemaManager().addOnlineChangeSet(session, cs);
}
return new AISValidatorPair(origAIS, validator);
}
});
onlineAt(OnlineDDLMonitor.Stage.POST_METADATA);
final String errorMsg;
final boolean[] success = { false };
try {
onlineAt(OnlineDDLMonitor.Stage.PRE_TRANSFORM);
alterTablePerform(session, tableName, pair.validator.getFinalChangeLevel(), context);
onlineAt(OnlineDDLMonitor.Stage.POST_TRANSFORM);
success[0] = true;
} finally {
onlineAt(OnlineDDLMonitor.Stage.PRE_FINAL);
errorMsg = txnService.run(session, new Callable<String>() {
@Override
public String call() {
String error = schemaManager().getOnlineDMLError(session);
if(success[0] && (error == null)) {
finishOnlineChange(session);
} else {
discardOnlineChange(session);
}
return error;
}
});
onlineAt(OnlineDDLMonitor.Stage.POST_FINAL);
}
if(errorMsg != null) {
throw new ConcurrentViolationException(errorMsg);
}
// Clear old storage after it is completely unused
txnService.run(session, new Runnable() {
@Override
public void run() {
Table origTable = pair.ais.getTable(tableName);
Table newTable = getTable(session, origTable.getTableId());
alterTableRemoveOldStorage(session, origTable, newTable, pair.validator);
}
});
return pair.validator.getFinalChangeLevel();