Search in sources :

Example 1 with DuplicatePrimaryKeyException

use of herddb.model.DuplicatePrimaryKeyException in project herddb by diennea.

the class RawSQLTest method multipleColumnPrimaryKeyTest.

@Test
public void multipleColumnPrimaryKeyTest() 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.tsql (k1 string," + "n1 int," + "s1 string, " + "primary key (k1,n1)" + ")", Collections.emptyList());
        assertEquals(1, executeUpdate(manager, "INSERT INTO tblspace1.tsql(k1,n1) values(?,?)", Arrays.asList("mykey", Integer.valueOf(1234))).getUpdateCount());
        try (DataScanner scan1 = scan(manager, "SELECT k1 as theKey,'one' as theStringConstant,3  LongConstant FROM tblspace1.tsql where k1 ='mykey'", Collections.emptyList())) {
            assertEquals(1, scan1.consume().size());
        }
        assertEquals(1, executeUpdate(manager, "INSERT INTO tblspace1.tsql(k1,n1) values(?,?)", Arrays.asList("mykey", Integer.valueOf(1235))).getUpdateCount());
        try (DataScanner scan1 = scan(manager, "SELECT k1 as theKey,'one' as theStringConstant,3  LongConstant FROM tblspace1.tsql where k1 ='mykey'", Collections.emptyList())) {
            assertEquals(2, scan1.consume().size());
        }
        try {
            assertEquals(1, executeUpdate(manager, "INSERT INTO tblspace1.tsql(k1,n1) values(?,?)", Arrays.asList("mykey", Integer.valueOf(1235))).getUpdateCount());
            fail();
        } catch (DuplicatePrimaryKeyException err) {
        }
        try (DataScanner scan1 = scan(manager, "SELECT k1,n1  FROM tblspace1.tsql where k1 ='mykey' order by n1", Collections.emptyList())) {
            List<DataAccessor> rows = scan1.consume();
            assertEquals(2, rows.size());
            assertEquals(1234, rows.get(0).get("n1"));
            assertEquals(1235, rows.get(1).get("n1"));
        }
        try (DataScanner scan1 = scan(manager, "SELECT k1,n1 FROM tblspace1.tsql where k1 ='mykey' and n1=1234", Collections.emptyList())) {
            assertEquals(1, scan1.consume().size());
        }
        assertEquals(1, executeUpdate(manager, "INSERT INTO tblspace1.tsql(n1,k1) values(?,?)", Arrays.asList(Integer.valueOf(1236), "mykey")).getUpdateCount());
        try (DataScanner scan1 = scan(manager, "SELECT k1,n1  FROM tblspace1.tsql where k1 ='mykey' order by n1 desc", Collections.emptyList())) {
            List<DataAccessor> rows = scan1.consume();
            assertEquals(3, rows.size());
            assertEquals(1236, rows.get(0).get("n1"));
            assertEquals(1235, rows.get(1).get("n1"));
            assertEquals(1234, rows.get(2).get("n1"));
        }
        try (DataScanner scan1 = scan(manager, "SELECT k1,n1 FROM tblspace1.tsql where k1 ='mykey' and n1=1234", Collections.emptyList())) {
            assertEquals(1, scan1.consume().size());
        }
        try (DataScanner scan1 = scan(manager, "SELECT k1,n1 FROM tblspace1.tsql where k1 ='mykey'", Collections.emptyList())) {
            assertEquals(3, scan1.consume().size());
        }
        assertEquals(1, executeUpdate(manager, "UPDATE tblspace1.tsql set s1=? where k1 =? and n1=?", Arrays.asList("newvalue", "mykey", Integer.valueOf(1236))).getUpdateCount());
        try (DataScanner scan1 = scan(manager, "SELECT k1,n1,s1 FROM tblspace1.tsql where k1 ='mykey' and n1=1236", Collections.emptyList())) {
            List<DataAccessor> rows = scan1.consume();
            assertEquals(1, rows.size());
            assertEquals(RawString.of("newvalue"), rows.get(0).get("s1"));
        }
        assertEquals(1, executeUpdate(manager, "DELETE FROM tblspace1.tsql where k1 =? and n1=?", Arrays.asList("mykey", Integer.valueOf(1236))).getUpdateCount());
        try (DataScanner scan1 = scan(manager, "SELECT k1,n1 FROM tblspace1.tsql where k1 ='mykey' and n1=1236", Collections.emptyList())) {
            assertEquals(0, scan1.consume().size());
        }
    }
}
Also used : CreateTableSpaceStatement(herddb.model.commands.CreateTableSpaceStatement) DataScanner(herddb.model.DataScanner) MemoryDataStorageManager(herddb.mem.MemoryDataStorageManager) DataAccessor(herddb.utils.DataAccessor) MemoryCommitLogManager(herddb.mem.MemoryCommitLogManager) DuplicatePrimaryKeyException(herddb.model.DuplicatePrimaryKeyException) RawString(herddb.utils.RawString) MemoryMetadataStorageManager(herddb.mem.MemoryMetadataStorageManager) Test(org.junit.Test)

Example 2 with DuplicatePrimaryKeyException

use of herddb.model.DuplicatePrimaryKeyException in project herddb by diennea.

the class SimpleTransactionTest method testInsertInsert.

@Test
public void testInsertInsert() throws Exception {
    Bytes key = Bytes.from_string("key1");
    {
        Record record = new Record(key, Bytes.from_int(0));
        InsertStatement st = new InsertStatement(tableSpace, tableName, record);
        assertEquals(1, manager.executeUpdate(st, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION).getUpdateCount());
    }
    long tx = beginTransaction();
    {
        Record record = new Record(key, Bytes.from_int(1));
        InsertStatement st = new InsertStatement(tableSpace, tableName, record);
        try {
            manager.executeUpdate(st, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), new TransactionContext(tx)).getUpdateCount();
            fail();
        } catch (DuplicatePrimaryKeyException expected) {
        }
    }
}
Also used : Bytes(herddb.utils.Bytes) TransactionContext(herddb.model.TransactionContext) DuplicatePrimaryKeyException(herddb.model.DuplicatePrimaryKeyException) Record(herddb.model.Record) InsertStatement(herddb.model.commands.InsertStatement) Test(org.junit.Test)

Example 3 with DuplicatePrimaryKeyException

use of herddb.model.DuplicatePrimaryKeyException in project herddb by diennea.

the class TableManager method executeInsert.

private StatementExecutionResult executeInsert(InsertStatement insert, Transaction transaction, StatementEvaluationContext context) throws StatementExecutionException, DataStorageManagerException {
    /*
         an insert can succeed only if the row is valid and the "keys" structure  does not contain the requested key
         the insert will add the row in the 'buffer' without assigning a page to it
         locks: the insert uses global 'insert' lock on the table
         the insert will update the 'maxKey' for auto_increment primary keys
         */
    Bytes key = new Bytes(insert.getKeyFunction().computeNewValue(null, context, tableContext));
    byte[] value = insert.getValuesFunction().computeNewValue(new Record(key, null), context, tableContext);
    final long size = DataPage.estimateEntrySize(key, value);
    if (size > maxLogicalPageSize) {
        throw new RecordTooBigException("New record " + key + " is to big to be inserted: size " + size + ", max size " + maxLogicalPageSize);
    }
    LockHandle lock = lockForWrite(key, transaction);
    try {
        if (transaction != null) {
            if (transaction.recordDeleted(table.name, key)) {
            // OK, INSERT on a DELETED record inside this transaction
            } else if (transaction.recordInserted(table.name, key) != null) {
                // ERROR, INSERT on a INSERTED record inside this transaction
                throw new DuplicatePrimaryKeyException(key, "key " + key + ", decoded as " + RecordSerializer.deserializePrimaryKey(key.data, table) + ", already exists in table " + table.name + " inside transaction " + transaction.transactionId);
            } else if (keyToPage.containsKey(key)) {
                throw new DuplicatePrimaryKeyException(key, "key " + key + ", decoded as " + RecordSerializer.deserializePrimaryKey(key.data, table) + ", already exists in table " + table.name + " during transaction " + transaction.transactionId);
            }
        } else if (keyToPage.containsKey(key)) {
            throw new DuplicatePrimaryKeyException(key, "key " + key + ", decoded as " + RecordSerializer.deserializePrimaryKey(key.data, table) + ", already exists in table " + table.name);
        }
        LogEntry entry = LogEntryFactory.insert(table, key.data, value, transaction);
        CommitLogResult pos = log.log(entry, entry.transactionId <= 0);
        apply(pos, entry, false);
        return new DMLStatementExecutionResult(entry.transactionId, 1, key, insert.isReturnValues() ? Bytes.from_array(value) : null);
    } catch (LogNotAvailableException err) {
        throw new StatementExecutionException(err);
    } finally {
        if (transaction == null) {
            locksManager.releaseWriteLockForKey(key, lock);
        }
    }
}
Also used : Bytes(herddb.utils.Bytes) LockHandle(herddb.utils.LockHandle) DMLStatementExecutionResult(herddb.model.DMLStatementExecutionResult) DuplicatePrimaryKeyException(herddb.model.DuplicatePrimaryKeyException) Record(herddb.model.Record) CommitLogResult(herddb.log.CommitLogResult) RecordTooBigException(herddb.model.RecordTooBigException) LogEntry(herddb.log.LogEntry) StatementExecutionException(herddb.model.StatementExecutionException) LogNotAvailableException(herddb.log.LogNotAvailableException)

Example 4 with DuplicatePrimaryKeyException

use of herddb.model.DuplicatePrimaryKeyException in project herddb by diennea.

the class AutoTransactionTest method testAutoTransactionOnFailedInsert.

@Test
public void testAutoTransactionOnFailedInsert() throws Exception {
    int i = 1;
    {
        Map<String, Object> data = new HashMap<>();
        data.put("number", i);
        data.put("id", i);
        Record record = RecordSerializer.toRecord(data, table);
        InsertStatement st = new InsertStatement(tableSpace, tableName, record);
        manager.executeUpdate(st, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
    }
    try {
        Map<String, Object> data = new HashMap<>();
        data.put("number", i);
        data.put("id", i);
        Record record = RecordSerializer.toRecord(data, table);
        InsertStatement st = new InsertStatement(tableSpace, tableName, record);
        manager.executeUpdate(st, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.AUTOTRANSACTION_TRANSACTION);
        fail();
    } catch (DuplicatePrimaryKeyException ok) {
    }
    assertTrue(manager.getTableSpaceManager(tableSpace).getOpenTransactions().isEmpty());
}
Also used : HashMap(java.util.HashMap) DuplicatePrimaryKeyException(herddb.model.DuplicatePrimaryKeyException) Record(herddb.model.Record) HashMap(java.util.HashMap) Map(java.util.Map) InsertStatement(herddb.model.commands.InsertStatement) Test(org.junit.Test)

Example 5 with DuplicatePrimaryKeyException

use of herddb.model.DuplicatePrimaryKeyException in project herddb by diennea.

the class ServerSideConnectionPeer method handleExecuteStatement.

private void handleExecuteStatement(Message message, Channel _channel) {
    Long tx = (Long) message.parameters.get("tx");
    long txId = tx != null ? tx : TransactionContext.NOTRANSACTION_ID;
    String query = (String) message.parameters.get("query");
    String tableSpace = (String) message.parameters.get("tableSpace");
    Boolean returnValues = (Boolean) message.parameters.get("returnValues");
    if (returnValues == null) {
        returnValues = Boolean.FALSE;
    }
    List<Object> parameters = (List<Object>) message.parameters.get("params");
    if (LOGGER.isLoggable(Level.FINEST)) {
        LOGGER.log(Level.FINEST, "query " + query + " with " + parameters);
    }
    try {
        TransactionContext transactionContext = new TransactionContext(txId);
        TranslatedQuery translatedQuery = server.getManager().getPlanner().translate(tableSpace, query, parameters, false, true, returnValues, -1);
        Statement statement = translatedQuery.plan.mainStatement;
        // LOGGER.log(Level.SEVERE, "query " + query + ", " + parameters + ", plan: " + translatedQuery.plan);
        StatementExecutionResult result = server.getManager().executePlan(translatedQuery.plan, translatedQuery.context, transactionContext);
        // LOGGER.log(Level.SEVERE, "query " + query + ", " + parameters + ", result:" + result);
        if (result instanceof DMLStatementExecutionResult) {
            DMLStatementExecutionResult dml = (DMLStatementExecutionResult) result;
            Map<String, Object> otherData = null;
            if (returnValues && dml.getKey() != null) {
                TableAwareStatement tableStatement = statement.unwrap(TableAwareStatement.class);
                Table table = server.getManager().getTableSpaceManager(statement.getTableSpace()).getTableManager(tableStatement.getTable()).getTable();
                otherData = new HashMap<>();
                Object key = RecordSerializer.deserializePrimaryKey(dml.getKey().data, table);
                otherData.put("key", key);
                if (dml.getNewvalue() != null) {
                    Map<String, Object> newvalue = RecordSerializer.toBean(new Record(dml.getKey(), dml.getNewvalue()), table);
                    otherData.put("newvalue", newvalue);
                }
            }
            _channel.sendReplyMessage(message, Message.EXECUTE_STATEMENT_RESULT(dml.getUpdateCount(), otherData, dml.transactionId));
        } else if (result instanceof GetResult) {
            GetResult get = (GetResult) result;
            if (!get.found()) {
                _channel.sendReplyMessage(message, Message.EXECUTE_STATEMENT_RESULT(0, null, get.transactionId));
            } else {
                Map<String, Object> record = get.getRecord().toBean(get.getTable());
                _channel.sendReplyMessage(message, Message.EXECUTE_STATEMENT_RESULT(1, record, get.transactionId));
            }
        } else if (result instanceof TransactionResult) {
            TransactionResult txresult = (TransactionResult) result;
            Map<String, Object> data = new HashMap<>();
            Set<Long> transactionsForTableSpace = openTransactions.computeIfAbsent(statement.getTableSpace(), k -> new ConcurrentSkipListSet<>());
            switch(txresult.getOutcome()) {
                case BEGIN:
                    {
                        transactionsForTableSpace.add(txresult.getTransactionId());
                        break;
                    }
                case COMMIT:
                case ROLLBACK:
                    transactionsForTableSpace.remove(txresult.getTransactionId());
                    break;
            }
            data.put("tx", txresult.getTransactionId());
            _channel.sendReplyMessage(message, Message.EXECUTE_STATEMENT_RESULT(1, data, txresult.transactionId));
        } else if (result instanceof DDLStatementExecutionResult) {
            DDLStatementExecutionResult ddl = (DDLStatementExecutionResult) result;
            _channel.sendReplyMessage(message, Message.EXECUTE_STATEMENT_RESULT(1, null, ddl.transactionId));
        } else {
            _channel.sendReplyMessage(message, Message.ERROR(null, new Exception("unknown result type " + result.getClass() + " (" + result + ")")));
        }
    } catch (DuplicatePrimaryKeyException err) {
        LOGGER.log(Level.SEVERE, "error on query " + query + ", parameters: " + parameters + ": err", err);
        Message error = Message.ERROR(null, err);
        _channel.sendReplyMessage(message, error);
    } catch (NotLeaderException err) {
        Message error = Message.ERROR(null, err);
        error.setParameter("notLeader", "true");
        _channel.sendReplyMessage(message, error);
    } catch (StatementExecutionException err) {
        Message error = Message.ERROR(null, err);
        _channel.sendReplyMessage(message, error);
    } catch (RuntimeException err) {
        LOGGER.log(Level.SEVERE, "unexpected error on query " + query + ", parameters: " + parameters + ": err", err);
        Message error = Message.ERROR(null, err);
        _channel.sendReplyMessage(message, error);
    }
}
Also used : NotLeaderException(herddb.model.NotLeaderException) Message(herddb.network.Message) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) StatementExecutionException(herddb.model.StatementExecutionException) DDLStatementExecutionResult(herddb.model.DDLStatementExecutionResult) DMLStatementExecutionResult(herddb.model.DMLStatementExecutionResult) StatementExecutionResult(herddb.model.StatementExecutionResult) DuplicatePrimaryKeyException(herddb.model.DuplicatePrimaryKeyException) List(java.util.List) TuplesList(herddb.utils.TuplesList) ArrayList(java.util.ArrayList) Record(herddb.model.Record) TransactionResult(herddb.model.TransactionResult) TranslatedQuery(herddb.sql.TranslatedQuery) Table(herddb.model.Table) GetResult(herddb.model.GetResult) RollbackTransactionStatement(herddb.model.commands.RollbackTransactionStatement) TableAwareStatement(herddb.model.TableAwareStatement) ScanStatement(herddb.model.commands.ScanStatement) Statement(herddb.model.Statement) SQLPlannedOperationStatement(herddb.model.commands.SQLPlannedOperationStatement) DDLStatementExecutionResult(herddb.model.DDLStatementExecutionResult) TableAwareStatement(herddb.model.TableAwareStatement) DuplicatePrimaryKeyException(herddb.model.DuplicatePrimaryKeyException) HerdDBInternalException(herddb.core.HerdDBInternalException) StatementExecutionException(herddb.model.StatementExecutionException) NotLeaderException(herddb.model.NotLeaderException) DataScannerException(herddb.model.DataScannerException) DMLStatementExecutionResult(herddb.model.DMLStatementExecutionResult) TransactionContext(herddb.model.TransactionContext) AtomicLong(java.util.concurrent.atomic.AtomicLong) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap)

Aggregations

DuplicatePrimaryKeyException (herddb.model.DuplicatePrimaryKeyException)5 Record (herddb.model.Record)4 Test (org.junit.Test)3 DMLStatementExecutionResult (herddb.model.DMLStatementExecutionResult)2 StatementExecutionException (herddb.model.StatementExecutionException)2 TransactionContext (herddb.model.TransactionContext)2 InsertStatement (herddb.model.commands.InsertStatement)2 Bytes (herddb.utils.Bytes)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 HerdDBInternalException (herddb.core.HerdDBInternalException)1 CommitLogResult (herddb.log.CommitLogResult)1 LogEntry (herddb.log.LogEntry)1 LogNotAvailableException (herddb.log.LogNotAvailableException)1 MemoryCommitLogManager (herddb.mem.MemoryCommitLogManager)1 MemoryDataStorageManager (herddb.mem.MemoryDataStorageManager)1 MemoryMetadataStorageManager (herddb.mem.MemoryMetadataStorageManager)1 DDLStatementExecutionResult (herddb.model.DDLStatementExecutionResult)1 DataScanner (herddb.model.DataScanner)1 DataScannerException (herddb.model.DataScannerException)1