use of herddb.model.TransactionContext in project herddb by diennea.
the class ForeignKeySQLTest method alterTableCannotAddViolatedForeignKey.
@Test
public void alterTableCannotAddViolatedForeignKey() throws Exception {
String nodeId = "localhost";
try (DBManager manager = new DBManager("localhost", new MemoryMetadataStorageManager(), new MemoryDataStorageManager(), new MemoryCommitLogManager(), null, null)) {
manager.start();
CreateTableSpaceStatement st1 = new CreateTableSpaceStatement("tblspace1", Collections.singleton(nodeId), nodeId, 1, 0, 0);
manager.executeStatement(st1, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
manager.waitForTablespace("tblspace1", 10000);
execute(manager, "CREATE TABLE tblspace1.parent (k1 string primary key,n1 int,s1 string)", Collections.emptyList());
execute(manager, "CREATE TABLE tblspace1.child (k2 string primary key,n2 int,s2 string)", Collections.emptyList());
execute(manager, "INSERT INTO tblspace1.parent(k1,n1,s1) values('a',2,'pvalue')", Collections.emptyList(), TransactionContext.NO_TRANSACTION);
// insert a record that could violates the new FK1
execute(manager, "INSERT INTO tblspace1.child(k2,n2,s2) values('no',10,'a')", Collections.emptyList(), TransactionContext.NO_TRANSACTION);
// add the FK, it must fail
ForeignKeyViolationException err = expectThrows(ForeignKeyViolationException.class, () -> {
execute(manager, "ALTER TABLE tblspace1.`CHILD` Add CONSTRAINT `fk1` FOREIGN KEY (s2,n2) REFERENCES parent(k1,n1) ON DELETE RESTRICT", Collections.emptyList());
});
assertEquals("fk1", err.getForeignKeyName());
// check that the fk is not added
Table parentTable = manager.getTableSpaceManager("tblspace1").getTableManager("parent").getTable();
Table childTable = manager.getTableSpaceManager("tblspace1").getTableManager("child").getTable();
assertNull(childTable.foreignKeys);
// fix the record, in transaction
long tx = beginTransaction(manager, "tblspace1");
execute(manager, "UPDATE tblspace1.child set s2='a',n2=2", Collections.emptyList(), new TransactionContext(tx));
assertNotNull(manager.getTableSpaceManager("tblspace1").getTransaction(tx));
execute(manager, "ALTER TABLE tblspace1.`CHILD` Add CONSTRAINT `fk1` FOREIGN KEY (s2,n2) REFERENCES parent(k1,n1) ON DELETE RESTRICT", Collections.emptyList(), new TransactionContext(tx));
// transaction is committed automatically after an ALTER TABLE operation
assertNull(manager.getTableSpaceManager("tblspace1").getTransaction(tx));
// check that the fk is not present
childTable = manager.getTableSpaceManager("tblspace1").getTableManager("child").getTable();
assertEquals(1, childTable.foreignKeys.length);
assertEquals("fk1", childTable.foreignKeys[0].name);
assertEquals(ForeignKeyDef.ACTION_NO_ACTION, childTable.foreignKeys[0].onUpdateAction);
assertEquals(ForeignKeyDef.ACTION_NO_ACTION, childTable.foreignKeys[0].onDeleteAction);
assertEquals(parentTable.uuid, childTable.foreignKeys[0].parentTableId);
assertArrayEquals(new String[] { "s2", "n2" }, childTable.foreignKeys[0].columns);
assertArrayEquals(new String[] { "k1", "n1" }, childTable.foreignKeys[0].parentTableColumns);
}
}
use of herddb.model.TransactionContext in project herddb by diennea.
the class ForeignKeySQLTest method testServerSideOfForeignKey.
private void testServerSideOfForeignKey(final DBManager manager, long tx, String fkName, String updateAction, String deleteAction) throws DataScannerException, StatementExecutionException {
execute(manager, "INSERT INTO tblspace1.parent(k1,n1,s1) values('a',2,'pvalue')", Collections.emptyList(), new TransactionContext(tx));
execute(manager, "INSERT INTO tblspace1.parent(k1,n1,s1) values('newvalue',2,'foo')", Collections.emptyList(), new TransactionContext(tx));
execute(manager, "INSERT INTO tblspace1.child(k2,n2,s2) values('c1',2,'a')", Collections.emptyList(), new TransactionContext(tx));
execute(manager, "INSERT INTO tblspace1.child(k2,n2,s2) values('c2',2,'newvalue')", Collections.emptyList(), new TransactionContext(tx));
if ("SET NULL".equals(updateAction)) {
// assert that we are setting null only on the expected record
execute(manager, "UPDATE tblspace1.parent set n1=983 where k1='a'", Collections.emptyList(), new TransactionContext(tx));
assertEquals(1, scan(manager, "SELECT * FROM tblspace1.child WHERE s2 is NULL and n2 is NULL", Collections.emptyList(), new TransactionContext(tx)).consumeAndClose().size());
assertEquals(1, scan(manager, "SELECT * FROM tblspace1.child WHERE s2='newvalue'", Collections.emptyList(), new TransactionContext(tx)).consumeAndClose().size());
} else if ("CASCADE".equals(updateAction)) {
// not implemented
} else if ("NO ACTION".equals(updateAction)) {
ForeignKeyViolationException errOnUpdate = expectThrows(ForeignKeyViolationException.class, () -> {
execute(manager, "UPDATE tblspace1.parent set n1=983", Collections.emptyList(), new TransactionContext(tx));
});
assertEquals(fkName, errOnUpdate.getForeignKeyName());
} else {
fail();
}
if ("CASCADE".equals(deleteAction)) {
execute(manager, "DELETE FROM tblspace1.parent where k1='a'", Collections.emptyList(), new TransactionContext(tx));
// assert that we are deleting only the expected record
assertEquals(0, scan(manager, "SELECT * FROM tblspace1.child WHERE s2='a'", Collections.emptyList(), new TransactionContext(tx)).consumeAndClose().size());
assertEquals(1, scan(manager, "SELECT * FROM tblspace1.child WHERE s2='newvalue'", Collections.emptyList(), new TransactionContext(tx)).consumeAndClose().size());
} else if ("SET NULL".equals(deleteAction)) {
execute(manager, "DELETE FROM tblspace1.parent where k1='a'", Collections.emptyList(), new TransactionContext(tx));
// assert that we are setting null only on the expected record
assertEquals(1, scan(manager, "SELECT * FROM tblspace1.child WHERE s2 is NULL and n2 is NULL", Collections.emptyList(), new TransactionContext(tx)).consumeAndClose().size());
assertEquals(1, scan(manager, "SELECT * FROM tblspace1.child WHERE s2='newvalue'", Collections.emptyList(), new TransactionContext(tx)).consumeAndClose().size());
} else if ("NO ACTION".equals(deleteAction)) {
ForeignKeyViolationException errOnDelete = expectThrows(ForeignKeyViolationException.class, () -> {
execute(manager, "DELETE FROM tblspace1.parent", Collections.emptyList(), new TransactionContext(tx));
});
assertEquals(fkName, errOnDelete.getForeignKeyName());
execute(manager, "DELETE FROM tblspace1.child", Collections.emptyList(), new TransactionContext(tx));
execute(manager, "UPDATE tblspace1.parent set n1=983", Collections.emptyList(), new TransactionContext(tx));
execute(manager, "DELETE FROM tblspace1.parent", Collections.emptyList(), new TransactionContext(tx));
} else {
fail();
}
}
use of herddb.model.TransactionContext in project herddb by diennea.
the class UpdateTest method updateMultiRowsWithValidationError.
@Test
public void updateMultiRowsWithValidationError() throws Exception {
final int inserts = 10;
String nodeId = "localhost";
try (DBManager manager = new DBManager("localhost", new MemoryMetadataStorageManager(), new MemoryDataStorageManager(), new MemoryCommitLogManager(), null, null)) {
manager.start();
CreateTableSpaceStatement st1 = new CreateTableSpaceStatement("tblspace1", Collections.singleton(nodeId), nodeId, 1, 0, 0);
manager.executeStatement(st1, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), NO_TRANSACTION);
manager.waitForTablespace("tblspace1", 10000);
execute(manager, "CREATE TABLE tblspace1.tsql (k1 int, n1 int not null, primary key(k1))", Collections.emptyList());
for (int i = 0; i < inserts; i++) {
assertEquals(1, executeUpdate(manager, "INSERT INTO tblspace1.tsql(k1,n1) values(?,?)", Arrays.asList(Integer.valueOf(i), Integer.valueOf(1))).getUpdateCount());
}
long tx = beginTransaction(manager, "tblspace1");
TransactionContext ctx = new TransactionContext(tx);
// single record failed update
StatementExecutionException error = herddb.utils.TestUtils.expectThrows(StatementExecutionException.class, () -> {
executeUpdate(manager, "UPDATE tblspace1.tsql set n1 = null WHERE n1=1", Collections.emptyList(), ctx);
});
assertEquals("error on column n1 (integer not null):Cannot have null value in non-NULL type integer", error.getMessage());
// multi record failed update
StatementExecutionException errors = herddb.utils.TestUtils.expectThrows(StatementExecutionException.class, () -> {
executeUpdate(manager, "UPDATE tblspace1.tsql set n1 = null", Collections.emptyList(), ctx);
});
assertEquals("error on column n1 (integer not null):Cannot have null value in non-NULL type integer", errors.getMessage());
commitTransaction(manager, "tblspace1", tx);
}
}
use of herddb.model.TransactionContext in project herddb by diennea.
the class UpdateTest method simpleManualSequence.
@Test
public void simpleManualSequence() throws Exception {
String nodeId = "localhost";
try (DBManager manager = new DBManager("localhost", new MemoryMetadataStorageManager(), new MemoryDataStorageManager(), new MemoryCommitLogManager(), null, null)) {
manager.start();
CreateTableSpaceStatement st1 = new CreateTableSpaceStatement("tblspace1", Collections.singleton(nodeId), nodeId, 1, 0, 0);
manager.executeStatement(st1, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
manager.waitForTablespace("tblspace1", 10000);
execute(manager, "CREATE TABLE tblspace1.myseq (k1 int, k2 int, current_value int, primary key(k1, k2))", Collections.emptyList());
DMLStatementExecutionResult insertSequence1 = executeUpdate(manager, "INSERT INTO tblspace1.myseq(k1,k2,current_value) values(?,?,?)", Arrays.asList(Integer.valueOf(78), Integer.valueOf(0), Integer.valueOf(1)), TransactionContext.AUTOTRANSACTION_TRANSACTION);
assertTrue(insertSequence1.transactionId > 0);
try (DataScanner scan = scan(manager, "SELECT current_value from tblspace1.myseq where k1=?", Arrays.asList(78), new TransactionContext(insertSequence1.transactionId))) {
List<DataAccessor> recordSet = scan.consumeAndClose();
assertEquals(1, recordSet.size());
assertEquals(1, recordSet.get(0).get(0));
}
// set current_value = 2 if current_value = 1
DMLStatementExecutionResult updateSequence1 = executeUpdate(manager, "UPDATE tblspace1.myseq set current_value=? where k1=78 and k2=0 and current_value=?", Arrays.asList(Integer.valueOf(2), Integer.valueOf(1)), new TransactionContext(insertSequence1.transactionId));
assertEquals(insertSequence1.transactionId, updateSequence1.transactionId);
assertEquals(1, updateSequence1.getUpdateCount());
try (DataScanner scan = scan(manager, "SELECT current_value from tblspace1.myseq where k1=?", Arrays.asList(78), new TransactionContext(updateSequence1.transactionId))) {
List<DataAccessor> recordSet = scan.consumeAndClose();
assertEquals(1, recordSet.size());
assertEquals(2, recordSet.get(0).get(0));
}
DMLStatementExecutionResult updateSequence2 = executeUpdate(manager, "UPDATE tblspace1.myseq set current_value=? where k1=78 and k2=0 and current_value=?", Arrays.asList(Integer.valueOf(3), Integer.valueOf(2)), new TransactionContext(updateSequence1.transactionId));
assertEquals(updateSequence2.transactionId, updateSequence1.transactionId);
assertEquals(1, updateSequence2.getUpdateCount());
try (DataScanner scan = scan(manager, "SELECT current_value from tblspace1.myseq where k1=?", Arrays.asList(78), new TransactionContext(updateSequence1.transactionId))) {
List<DataAccessor> recordSet = scan.consumeAndClose();
assertEquals(1, recordSet.size());
assertEquals(3, recordSet.get(0).get(0));
}
DMLStatementExecutionResult deleteSequence2 = executeUpdate(manager, "DELETE FROM tblspace1.myseq where k1=78 and k2=0 ", Arrays.asList(), new TransactionContext(updateSequence1.transactionId));
assertEquals(deleteSequence2.transactionId, updateSequence1.transactionId);
assertEquals(1, deleteSequence2.getUpdateCount());
try (DataScanner scan = scan(manager, "SELECT current_value from tblspace1.myseq where k1=?", Arrays.asList(78), new TransactionContext(updateSequence1.transactionId))) {
List<DataAccessor> recordSet = scan.consumeAndClose();
assertEquals(0, recordSet.size());
}
}
}
use of herddb.model.TransactionContext in project herddb by diennea.
the class UpdateTest method updateThenSelect.
/**
* Check update then select (#320, not every row update really was run).
*
* @author diego.salvi
*/
@Test
public void updateThenSelect() throws Exception {
int runs = 50;
int inserts = 100;
String nodeId = "localhost";
try (DBManager manager = new DBManager("localhost", new MemoryMetadataStorageManager(), new MemoryDataStorageManager(), new MemoryCommitLogManager(), null, null)) {
manager.start();
CreateTableSpaceStatement st1 = new CreateTableSpaceStatement("tblspace1", Collections.singleton(nodeId), nodeId, 1, 0, 0);
manager.executeStatement(st1, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), NO_TRANSACTION);
manager.waitForTablespace("tblspace1", 10000);
for (int run = 0; run < runs; ++run) {
execute(manager, "CREATE TABLE tblspace1.tsql (k1 int, n1 int, primary key(k1))", Collections.emptyList());
for (int i = 0; i < inserts; ++i) {
assertEquals(1, executeUpdate(manager, "INSERT INTO tblspace1.tsql(k1,n1) values(?,?)", Arrays.asList(Integer.valueOf(i), Integer.valueOf(1))).getUpdateCount());
}
long tx = beginTransaction(manager, "tblspace1");
TransactionContext ctx = new TransactionContext(tx);
assertEquals(inserts, executeUpdate(manager, "UPDATE tblspace1.tsql set n1 = 100", Collections.emptyList(), ctx).getUpdateCount());
for (int i = 0; i < inserts; ++i) {
assertEquals(1, scan(manager, "SELECT k1, n1 FROM tblspace1.tsql WHERE k1 = ? AND n1 = 100", Arrays.asList(Integer.valueOf(i)), ctx).consumeAndClose().size());
}
for (int i = 0; i < inserts; ++i) {
try {
assertEquals(1, scan(manager, "SELECT k1, n1 FROM tblspace1.tsql WHERE k1 = ? AND n1 = 100", Arrays.asList(Integer.valueOf(i)), ctx).consumeAndClose().size());
} catch (AssertionError e) {
throw e;
}
}
commitTransaction(manager, "tblspace1", tx);
for (int i = 0; i < inserts; ++i) {
assertEquals(1, scan(manager, "SELECT k1, n1 FROM tblspace1.tsql WHERE k1 = ? AND n1 = 100", Arrays.asList(Integer.valueOf(i), ctx)).consumeAndClose().size());
}
execute(manager, "DROP TABLE tblspace1.tsql", Collections.emptyList());
}
}
}
Aggregations