use of herddb.model.ForeignKeyViolationException in project herddb by diennea.
the class TableManager method validateForeignKeyConsistency.
private void validateForeignKeyConsistency(ForeignKeyDef fk, StatementEvaluationContext context, Transaction transaction) throws StatementExecutionException {
if (!tableSpaceManager.getDbmanager().isFullSQLSupportEnabled()) {
// we cannot perform this validation without Calcite
return;
}
Table parentTable = tableSpaceManager.getTableManagerByUUID(fk.parentTableId).getTable();
StringBuilder query = new StringBuilder("SELECT * " + " FROM " + delimit(this.tableSpaceManager.getTableSpaceName()) + "." + delimit(this.table.name) + " childtable " + " WHERE NOT EXISTS (SELECT * " + " FROM " + delimit(this.tableSpaceManager.getTableSpaceName()) + "." + delimit(parentTable.name) + " parenttable " + " WHERE ");
for (int i = 0; i < fk.columns.length; i++) {
if (i > 0) {
query.append(" AND ");
}
query.append("childtable.").append(delimit(fk.columns[i])).append(" = parenttable.").append(delimit(fk.parentTableColumns[i]));
}
query.append(")");
TransactionContext tx = transaction != null ? new TransactionContext(transaction.transactionId) : TransactionContext.NO_TRANSACTION;
boolean fkOk;
try (DataScanner scan = tableSpaceManager.getDbmanager().executeSimpleQuery(tableSpaceManager.getTableSpaceName(), query.toString(), Collections.emptyList(), // only one record
1, // keep read locks in TransactionContext
true, tx, context)) {
List<DataAccessor> resultSet = scan.consume();
fkOk = resultSet.isEmpty();
} catch (DataScannerException err) {
throw new StatementExecutionException(err);
}
if (!fkOk) {
throw new ForeignKeyViolationException(fk.name, "foreignKey " + table.name + "." + fk.name + " violated");
}
}
use of herddb.model.ForeignKeyViolationException in project herddb by diennea.
the class ForeignKeySQLTest method testChildSideOfForeignKey.
private void testChildSideOfForeignKey(final DBManager manager, long tx, String fkName) throws DataScannerException, StatementExecutionException {
ForeignKeyViolationException err = expectThrows(ForeignKeyViolationException.class, () -> {
execute(manager, "INSERT INTO tblspace1.child(k2,n2,s2) values('a',2,'pvalue')", Collections.emptyList(), new TransactionContext(tx));
});
assertEquals(fkName, err.getForeignKeyName());
execute(manager, "INSERT INTO tblspace1.parent(k1,n1,s1) values('a',2,'pvalue')", Collections.emptyList(), new TransactionContext(tx));
execute(manager, "INSERT INTO tblspace1.child(k2,n2,s2) values('c1',2,'a')", Collections.emptyList(), new TransactionContext(tx));
ForeignKeyViolationException errOnUpdate = expectThrows(ForeignKeyViolationException.class, () -> {
execute(manager, "UPDATE tblspace1.child set s2='badvalue'", Collections.emptyList(), new TransactionContext(tx));
});
assertEquals(fkName, errOnUpdate.getForeignKeyName());
execute(manager, "INSERT INTO tblspace1.parent(k1,n1,s1) values('newvalue',2,'foo')", Collections.emptyList(), new TransactionContext(tx));
dump(manager, "SELECT * FROM tblspace1.parent", Collections.emptyList(), new TransactionContext(tx));
execute(manager, "UPDATE tblspace1.child set s2='newvalue'", Collections.emptyList(), new TransactionContext(tx));
}
Aggregations