private int tryUpdate() {
if (!transactional) {
session.commit(true);
}
Database db = session.getDatabase();
Table table = getSchema().getTableOrView(session, tableName);
if (getSchema().findConstraint(session, constraintName) != null) {
if (ifNotExists) {
return 0;
}
throw DbException.get(ErrorCode.CONSTRAINT_ALREADY_EXISTS_1, constraintName);
}
session.getUser().checkRight(table, Right.ALL);
db.lockMeta(session);
table.lock(session, true, true);
Constraint constraint;
switch (type) {
case CommandInterface.ALTER_TABLE_ADD_CONSTRAINT_PRIMARY_KEY: {
IndexColumn.mapColumns(indexColumns, table);
index = table.findPrimaryKey();
ArrayList<Constraint> constraints = table.getConstraints();
for (int i = 0; constraints != null && i < constraints.size(); i++) {
Constraint c = constraints.get(i);
if (Constraint.PRIMARY_KEY.equals(c.getConstraintType())) {
throw DbException.get(ErrorCode.SECOND_PRIMARY_KEY);
}
}
if (index != null) {
// if there is an index, it must match with the one declared
// we don't test ascending / descending
IndexColumn[] pkCols = index.getIndexColumns();
if (pkCols.length != indexColumns.length) {
throw DbException.get(ErrorCode.SECOND_PRIMARY_KEY);
}
for (int i = 0; i < pkCols.length; i++) {
if (pkCols[i].column != indexColumns[i].column) {
throw DbException.get(ErrorCode.SECOND_PRIMARY_KEY);
}
}
}
if (index == null) {
IndexType indexType = IndexType.createPrimaryKey(table.isPersistIndexes(), primaryKeyHash);
String indexName = table.getSchema().getUniqueIndexName(session, table, Constants.PREFIX_PRIMARY_KEY);
int id = getObjectId();
try {
index = table.addIndex(session, indexName, id, indexColumns, indexType, true, null);
} finally {
getSchema().freeUniqueName(indexName);
}
}
index.getIndexType().setBelongsToConstraint(true);
int constraintId = getObjectId();
String name = generateConstraintName(table);
ConstraintUnique pk = new ConstraintUnique(getSchema(), constraintId, name, table, true);
pk.setColumns(indexColumns);
pk.setIndex(index, true);
constraint = pk;
break;
}
case CommandInterface.ALTER_TABLE_ADD_CONSTRAINT_UNIQUE: {
IndexColumn.mapColumns(indexColumns, table);
boolean isOwner = false;
if (index != null && canUseUniqueIndex(index, table, indexColumns)) {
isOwner = true;
index.getIndexType().setBelongsToConstraint(true);
} else {
index = getUniqueIndex(table, indexColumns);
if (index == null) {
index = createIndex(table, indexColumns, true);
isOwner = true;
}
}
int id = getObjectId();
String name = generateConstraintName(table);
ConstraintUnique unique = new ConstraintUnique(getSchema(), id, name, table, false);
unique.setColumns(indexColumns);
unique.setIndex(index, isOwner);
constraint = unique;
break;
}
case CommandInterface.ALTER_TABLE_ADD_CONSTRAINT_CHECK: {
int id = getObjectId();
String name = generateConstraintName(table);
ConstraintCheck check = new ConstraintCheck(getSchema(), id, name, table);
TableFilter filter = new TableFilter(session, table, null, false, null);
checkExpression.mapColumns(filter, 0);
checkExpression = checkExpression.optimize(session);
check.setExpression(checkExpression);
check.setTableFilter(filter);
constraint = check;
if (checkExisting) {
check.checkExistingData(session);
}
break;
}
case CommandInterface.ALTER_TABLE_ADD_CONSTRAINT_REFERENTIAL: {
Table refTable = refSchema.getTableOrView(session, refTableName);
session.getUser().checkRight(refTable, Right.ALL);
if (!refTable.canReference()) {
throw DbException.get(ErrorCode.FEATURE_NOT_SUPPORTED_1, "Reference " + refTable.getSQL());
}
boolean isOwner = false;
IndexColumn.mapColumns(indexColumns, table);
if (index != null && canUseIndex(index, table, indexColumns)) {
isOwner = true;
index.getIndexType().setBelongsToConstraint(true);
} else {
index = getIndex(table, indexColumns);
if (index == null) {
index = createIndex(table, indexColumns, false);
isOwner = true;
}
}
if (refIndexColumns == null) {
Index refIdx = refTable.getPrimaryKey();
refIndexColumns = refIdx.getIndexColumns();
} else {
IndexColumn.mapColumns(refIndexColumns, refTable);
}
if (refIndexColumns.length != indexColumns.length) {
throw DbException.get(ErrorCode.COLUMN_COUNT_DOES_NOT_MATCH);
}
boolean isRefOwner = false;
if (refIndex != null && refIndex.getTable() == refTable && canUseIndex(refIndex, refTable, refIndexColumns)) {
isRefOwner = true;
refIndex.getIndexType().setBelongsToConstraint(true);
} else {
refIndex = null;
}
if (refIndex == null) {
refIndex = getIndex(refTable, refIndexColumns);
if (refIndex == null) {
refIndex = createIndex(refTable, refIndexColumns, true);
isRefOwner = true;
}
}
int id = getObjectId();
String name = generateConstraintName(table);
ConstraintReferential ref = new ConstraintReferential(getSchema(), id, name, table);
ref.setColumns(indexColumns);
ref.setIndex(index, isOwner);
ref.setRefTable(refTable);
ref.setRefColumns(refIndexColumns);
ref.setRefIndex(refIndex, isRefOwner);
if (checkExisting) {
ref.checkExistingData(session);
}
constraint = ref;
refTable.addConstraint(constraint);
ref.setDeleteAction(deleteAction);
ref.setUpdateAction(updateAction);
break;
}
default: