Search in sources :

Example 1 with RunningStatementsStats

use of herddb.core.RunningStatementsStats in project herddb by diennea.

the class ServerSideConnectionPeer method handleExecuteStatements.

private void handleExecuteStatements(Pdu message, Channel channel) {
    long transactionId = PduCodec.ExecuteStatements.readTx(message);
    String tableSpace = PduCodec.ExecuteStatements.readTablespace(message);
    long statementId = PduCodec.ExecuteStatements.readStatementId(message);
    String query = statementId > 0 ? preparedStatements.resolveQuery(tableSpace, statementId) : PduCodec.ExecuteStatements.readQuery(message);
    if (query == null) {
        ByteBuf error = PduCodec.ErrorResponse.writeMissingPreparedStatementError(message.messageId, "bad statement id: " + statementId);
        channel.sendReplyMessage(message.messageId, error);
        message.close();
        return;
    }
    boolean returnValues = PduCodec.ExecuteStatements.readReturnValues(message);
    PduCodec.ListOfListsReader statementParameters = PduCodec.ExecuteStatements.startReadStatementsParameters(message);
    int numStatements = statementParameters.getNumLists();
    List<List<Object>> batch = new ArrayList<>(numStatements);
    for (int i = 0; i < numStatements; i++) {
        PduCodec.ObjectListReader parametersReader = statementParameters.nextList();
        List<Object> batchParams = new ArrayList<>(parametersReader.getNumParams());
        for (int j = 0; j < parametersReader.getNumParams(); j++) {
            batchParams.add(parametersReader.nextObject());
        }
        batch.add(batchParams);
    }
    RunningStatementsStats runningStatements = server.getManager().getRunningStatements();
    RunningStatementInfo statementInfo = new RunningStatementInfo(query, System.currentTimeMillis(), tableSpace, "", numStatements);
    try {
        List<TranslatedQuery> queries = new ArrayList<>();
        for (int i = 0; i < numStatements; i++) {
            List<Object> parameters = batch.get(i);
            TranslatedQuery translatedQuery = server.getManager().getPlanner().translate(tableSpace, query, parameters, false, true, returnValues, -1);
            queries.add(translatedQuery);
        }
        List<Long> updateCounts = new CopyOnWriteArrayList<>();
        List<Map<String, Object>> otherDatas = new CopyOnWriteArrayList<>();
        class ComputeNext implements BiConsumer<StatementExecutionResult, Throwable> {

            int current;

            public ComputeNext(int current) {
                this.current = current;
            }

            @Override
            public void accept(StatementExecutionResult result, Throwable error) {
                if (error != null) {
                    ByteBuf errorMsg = composeErrorResponse(message.messageId, error);
                    channel.sendReplyMessage(message.messageId, errorMsg);
                    message.close();
                    runningStatements.unregisterRunningStatement(statementInfo);
                    return;
                }
                if (result instanceof DMLStatementExecutionResult) {
                    DMLStatementExecutionResult dml = (DMLStatementExecutionResult) result;
                    Map<String, Object> otherData = Collections.emptyMap();
                    if (returnValues && dml.getKey() != null) {
                        TranslatedQuery translatedQuery = queries.get(current - 1);
                        Statement statement = translatedQuery.plan.mainStatement;
                        TableAwareStatement tableStatement = (TableAwareStatement) statement;
                        Table table = server.getManager().getTableSpaceManager(statement.getTableSpace()).getTableManager(tableStatement.getTable()).getTable();
                        Object key = RecordSerializer.deserializePrimaryKey(dml.getKey(), table);
                        otherData = new HashMap<>();
                        otherData.put("_key", key);
                        if (dml.getNewvalue() != null) {
                            Map<String, Object> newvalue = RecordSerializer.toBean(new Record(dml.getKey(), dml.getNewvalue()), table);
                            otherData.putAll(newvalue);
                        }
                    }
                    updateCounts.add((long) dml.getUpdateCount());
                    otherDatas.add(otherData);
                } else if (result instanceof DDLStatementExecutionResult) {
                    Map<String, Object> otherData = Collections.emptyMap();
                    updateCounts.add(1L);
                    otherDatas.add(otherData);
                } else {
                    ByteBuf response = PduCodec.ErrorResponse.write(message.messageId, "bad result type " + result.getClass() + " (" + result + ")");
                    channel.sendReplyMessage(message.messageId, response);
                    message.close();
                    runningStatements.unregisterRunningStatement(statementInfo);
                    return;
                }
                long newTransactionId = result.transactionId;
                if (current == queries.size()) {
                    try {
                        ByteBuf response = PduCodec.ExecuteStatementsResult.write(message.messageId, updateCounts, otherDatas, newTransactionId);
                        channel.sendReplyMessage(message.messageId, response);
                        message.close();
                        runningStatements.unregisterRunningStatement(statementInfo);
                    } catch (Throwable t) {
                        LOGGER.log(Level.SEVERE, "Internal error", t);
                    }
                    return;
                }
                TranslatedQuery nextPlannedQuery = queries.get(current);
                TransactionContext transactionContext = new TransactionContext(newTransactionId);
                CompletableFuture<StatementExecutionResult> nextPromise = server.getManager().executePlanAsync(nextPlannedQuery.plan, nextPlannedQuery.context, transactionContext);
                nextPromise.whenComplete(new ComputeNext(current + 1));
            }
        }
        TransactionContext transactionContext = new TransactionContext(transactionId);
        TranslatedQuery firstTranslatedQuery = queries.get(0);
        server.getManager().executePlanAsync(firstTranslatedQuery.plan, firstTranslatedQuery.context, transactionContext).whenComplete(new ComputeNext(1));
    } catch (HerdDBInternalException err) {
        ByteBuf response = composeErrorResponse(message.messageId, err);
        channel.sendReplyMessage(message.messageId, response);
        message.close();
        runningStatements.unregisterRunningStatement(statementInfo);
    }
}
Also used : HerdDBInternalException(herddb.core.HerdDBInternalException) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) RawString(herddb.utils.RawString) ByteBuf(io.netty.buffer.ByteBuf) RunningStatementInfo(herddb.core.RunningStatementInfo) DDLStatementExecutionResult(herddb.model.DDLStatementExecutionResult) DMLStatementExecutionResult(herddb.model.DMLStatementExecutionResult) StatementExecutionResult(herddb.model.StatementExecutionResult) List(java.util.List) TuplesList(herddb.utils.TuplesList) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) Record(herddb.model.Record) RunningStatementsStats(herddb.core.RunningStatementsStats) TranslatedQuery(herddb.sql.TranslatedQuery) Table(herddb.model.Table) CommitTransactionStatement(herddb.model.commands.CommitTransactionStatement) RollbackTransactionStatement(herddb.model.commands.RollbackTransactionStatement) BeginTransactionStatement(herddb.model.commands.BeginTransactionStatement) TableAwareStatement(herddb.model.TableAwareStatement) ScanStatement(herddb.model.commands.ScanStatement) Statement(herddb.model.Statement) SQLPlannedOperationStatement(herddb.model.commands.SQLPlannedOperationStatement) DDLStatementExecutionResult(herddb.model.DDLStatementExecutionResult) PduCodec(herddb.proto.PduCodec) TableAwareStatement(herddb.model.TableAwareStatement) 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) BiConsumer(java.util.function.BiConsumer) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList)

Example 2 with RunningStatementsStats

use of herddb.core.RunningStatementsStats in project herddb by diennea.

the class ServerSideConnectionPeer method handleOpenScanner.

private void handleOpenScanner(Pdu message, Channel channel) {
    long txId = PduCodec.OpenScanner.readTx(message);
    String tableSpace = PduCodec.OpenScanner.readTablespace(message);
    long statementId = PduCodec.OpenScanner.readStatementId(message);
    String query = statementId > 0 ? preparedStatements.resolveQuery(tableSpace, statementId) : PduCodec.OpenScanner.readQuery(message);
    if (query == null) {
        ByteBuf error = PduCodec.ErrorResponse.writeMissingPreparedStatementError(message.messageId, "bad statement id: " + statementId);
        channel.sendReplyMessage(message.messageId, error);
        return;
    }
    long scannerId = PduCodec.OpenScanner.readScannerId(message);
    int fetchSize = PduCodec.OpenScanner.readFetchSize(message);
    if (fetchSize <= 0) {
        fetchSize = 10;
    }
    // default 0
    int maxRows = PduCodec.OpenScanner.readMaxRows(message);
    PduCodec.ObjectListReader parametersReader = PduCodec.OpenScanner.startReadParameters(message);
    List<Object> parameters = new ArrayList<>(parametersReader.getNumParams());
    for (int i = 0; i < parametersReader.getNumParams(); i++) {
        parameters.add(parametersReader.nextObject());
    }
    // with clients older than 0.20.0 keepReadLocks will be always true
    byte trailer = parametersReader.readTrailer();
    boolean keepReadLocks = !isDontKeepReadLocks(trailer);
    if (LOGGER.isLoggable(Level.FINER)) {
        LOGGER.log(Level.FINER, "openScanner txId+" + txId + ", fetchSize " + fetchSize + ", maxRows " + maxRows + ", keepReadLocks " + keepReadLocks + ", " + query + " with " + parameters);
    }
    RunningStatementsStats runningStatements = server.getManager().getRunningStatements();
    RunningStatementInfo statementInfo = new RunningStatementInfo(query, System.currentTimeMillis(), tableSpace, "", 1);
    try {
        TranslatedQuery translatedQuery = server.getManager().getPlanner().translate(tableSpace, query, parameters, true, true, false, maxRows);
        translatedQuery.context.setForceRetainReadLock(keepReadLocks);
        if (LOGGER.isLoggable(Level.FINEST)) {
            LOGGER.log(Level.FINEST, "{0} -> {1}", new Object[] { query, translatedQuery.plan.mainStatement });
        }
        TransactionContext transactionContext = new TransactionContext(txId);
        if (translatedQuery.plan.mainStatement instanceof SQLPlannedOperationStatement || translatedQuery.plan.mainStatement instanceof ScanStatement) {
            runningStatements.registerRunningStatement(statementInfo);
            ScanResult scanResult = (ScanResult) server.getManager().executePlan(translatedQuery.plan, translatedQuery.context, transactionContext);
            DataScanner dataScanner = scanResult.dataScanner;
            ServerSideScannerPeer scanner = new ServerSideScannerPeer(dataScanner);
            String[] columns = dataScanner.getFieldNames();
            List<DataAccessor> records = dataScanner.consume(fetchSize);
            TuplesList tuplesList = new TuplesList(columns, records);
            boolean last = dataScanner.isFinished();
            if (LOGGER.isLoggable(Level.FINEST)) {
                LOGGER.log(Level.FINEST, "sending first {0} records to scanner {1} query {2}", new Object[] { records.size(), scannerId, query });
            }
            if (!last) {
                scanners.put(scannerId, scanner);
            }
            try {
                ByteBuf result = PduCodec.ResultSetChunk.write(message.messageId, tuplesList, last, dataScanner.getTransactionId());
                channel.sendReplyMessage(message.messageId, result);
            } catch (HerdDBInternalException err) {
                // do not leak an unserializable scanner
                scanner.close();
                throw err;
            }
            if (last) {
                // no need to hold the scanner anymore
                scanner.close();
            }
        } else {
            ByteBuf error = PduCodec.ErrorResponse.write(message.messageId, "unsupported query type for scan " + query + ": PLAN is " + translatedQuery.plan);
            channel.sendReplyMessage(message.messageId, error);
        }
    } catch (DataScannerException | HerdDBInternalException err) {
        if (err.getCause() != null && err.getCause() instanceof ValidationException) {
            // no stacktraces for bad queries
            LOGGER.log(Level.FINE, "SQL error on scanner " + scannerId + ": " + err);
        } else {
            LOGGER.log(Level.SEVERE, "error on scanner " + scannerId + ": " + err, err);
        }
        scanners.remove(scannerId);
        ByteBuf error = composeErrorResponse(message.messageId, err);
        channel.sendReplyMessage(message.messageId, error);
    } finally {
        runningStatements.unregisterRunningStatement(statementInfo);
    }
}
Also used : HerdDBInternalException(herddb.core.HerdDBInternalException) ValidationException(org.apache.calcite.tools.ValidationException) DataAccessor(herddb.utils.DataAccessor) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) RawString(herddb.utils.RawString) ByteBuf(io.netty.buffer.ByteBuf) RunningStatementInfo(herddb.core.RunningStatementInfo) SQLPlannedOperationStatement(herddb.model.commands.SQLPlannedOperationStatement) DataScanner(herddb.model.DataScanner) RunningStatementsStats(herddb.core.RunningStatementsStats) ScanStatement(herddb.model.commands.ScanStatement) TuplesList(herddb.utils.TuplesList) DataScannerException(herddb.model.DataScannerException) ScanResult(herddb.model.ScanResult) TranslatedQuery(herddb.sql.TranslatedQuery) PduCodec(herddb.proto.PduCodec) TransactionContext(herddb.model.TransactionContext)

Example 3 with RunningStatementsStats

use of herddb.core.RunningStatementsStats in project herddb by diennea.

the class ServerSideConnectionPeer method handleExecuteStatement.

private void handleExecuteStatement(Pdu message, Channel channel) {
    long txId = PduCodec.ExecuteStatement.readTx(message);
    String tablespace = PduCodec.ExecuteStatement.readTablespace(message);
    long statementId = PduCodec.ExecuteStatement.readStatementId(message);
    String query = statementId > 0 ? preparedStatements.resolveQuery(tablespace, statementId) : PduCodec.ExecuteStatement.readQuery(message);
    if (query == null) {
        ByteBuf error = PduCodec.ErrorResponse.writeMissingPreparedStatementError(message.messageId, "bad statement id: " + statementId);
        channel.sendReplyMessage(message.messageId, error);
        message.close();
        return;
    }
    boolean returnValues = PduCodec.ExecuteStatement.readReturnValues(message);
    PduCodec.ObjectListReader parametersReader = PduCodec.ExecuteStatement.startReadParameters(message);
    List<Object> parameters = new ArrayList<>(parametersReader.getNumParams());
    for (int i = 0; i < parametersReader.getNumParams(); i++) {
        parameters.add(parametersReader.nextObject());
    }
    if (LOGGER.isLoggable(Level.FINEST)) {
        LOGGER.log(Level.FINEST, "query {0} with {1}", new Object[] { query, parameters });
    }
    RunningStatementInfo statementInfo = new RunningStatementInfo(query, System.currentTimeMillis(), tablespace, "", 1);
    TransactionContext transactionContext = new TransactionContext(txId);
    TranslatedQuery translatedQuery;
    try {
        translatedQuery = server.getManager().getPlanner().translate(tablespace, query, parameters, false, true, returnValues, -1);
    } catch (StatementExecutionException ex) {
        ByteBuf error = composeErrorResponse(message.messageId, ex);
        channel.sendReplyMessage(message.messageId, error);
        message.close();
        return;
    }
    Statement statement = translatedQuery.plan.mainStatement;
    // LOGGER.log(Level.SEVERE, "query " + query + ", " + parameters + ", plan: " + translatedQuery.plan);
    RunningStatementsStats runningStatements = server.getManager().getRunningStatements();
    runningStatements.registerRunningStatement(statementInfo);
    CompletableFuture<StatementExecutionResult> res = server.getManager().executePlanAsync(translatedQuery.plan, translatedQuery.context, transactionContext);
    // LOGGER.log(Level.SEVERE, "query " + query + ", " + parameters + ", result:" + result);
    res.whenComplete((result, err) -> {
        try {
            runningStatements.unregisterRunningStatement(statementInfo);
            if (err != null) {
                while (err instanceof CompletionException) {
                    err = err.getCause();
                }
                if (err instanceof DuplicatePrimaryKeyException) {
                    ByteBuf error = PduCodec.ErrorResponse.writeSqlIntegrityConstraintsViolation(message.messageId, new SQLIntegrityConstraintViolationException(err));
                    channel.sendReplyMessage(message.messageId, error);
                } else if (err instanceof NotLeaderException) {
                    ByteBuf error = composeErrorResponse(message.messageId, err);
                    channel.sendReplyMessage(message.messageId, error);
                } else if (err instanceof StatementExecutionException) {
                    ByteBuf error = composeErrorResponse(message.messageId, err);
                    channel.sendReplyMessage(message.messageId, error);
                } else {
                    LOGGER.log(Level.SEVERE, "unexpected error on query " + query + ", parameters: " + parameters + ":" + err, err);
                    ByteBuf error = composeErrorResponse(message.messageId, err);
                    channel.sendReplyMessage(message.messageId, error);
                }
                return;
            }
            if (result instanceof DMLStatementExecutionResult) {
                DMLStatementExecutionResult dml = (DMLStatementExecutionResult) result;
                Map<String, Object> newRecord = null;
                if (returnValues && dml.getKey() != null) {
                    TableAwareStatement tableStatement = statement.unwrap(TableAwareStatement.class);
                    Table table = server.getManager().getTableSpaceManager(statement.getTableSpace()).getTableManager(tableStatement.getTable()).getTable();
                    newRecord = new HashMap<>();
                    Object newKey = RecordSerializer.deserializePrimaryKey(dml.getKey(), table);
                    newRecord.put("_key", newKey);
                    if (dml.getNewvalue() != null) {
                        newRecord.putAll(RecordSerializer.toBean(new Record(dml.getKey(), dml.getNewvalue()), table));
                    }
                }
                channel.sendReplyMessage(message.messageId, PduCodec.ExecuteStatementResult.write(message.messageId, dml.getUpdateCount(), dml.transactionId, newRecord));
            } else if (result instanceof GetResult) {
                GetResult get = (GetResult) result;
                if (!get.found()) {
                    channel.sendReplyMessage(message.messageId, PduCodec.ExecuteStatementResult.write(message.messageId, 0, get.transactionId, null));
                } else {
                    Map<String, Object> record = get.getRecord().toBean(get.getTable());
                    channel.sendReplyMessage(message.messageId, PduCodec.ExecuteStatementResult.write(message.messageId, 1, get.transactionId, record));
                }
            } else if (result instanceof TransactionResult) {
                TransactionResult txresult = (TransactionResult) result;
                channel.sendReplyMessage(message.messageId, PduCodec.ExecuteStatementResult.write(message.messageId, 1, txresult.getTransactionId(), null));
            } else if (result instanceof DDLStatementExecutionResult) {
                DDLStatementExecutionResult ddl = (DDLStatementExecutionResult) result;
                channel.sendReplyMessage(message.messageId, PduCodec.ExecuteStatementResult.write(message.messageId, 1, ddl.transactionId, null));
            } else if (result instanceof DataConsistencyStatementResult) {
                channel.sendReplyMessage(message.messageId, PduCodec.ExecuteStatementResult.write(message.messageId, 0, 0, null));
            } else {
                ByteBuf error = PduCodec.ErrorResponse.write(message.messageId, "unknown result type:" + result);
                channel.sendReplyMessage(message.messageId, error);
            }
        } finally {
            message.close();
        }
    });
}
Also used : NotLeaderException(herddb.model.NotLeaderException) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) DataConsistencyStatementResult(herddb.model.DataConsistencyStatementResult) RawString(herddb.utils.RawString) ByteBuf(io.netty.buffer.ByteBuf) RunningStatementInfo(herddb.core.RunningStatementInfo) StatementExecutionException(herddb.model.StatementExecutionException) DDLStatementExecutionResult(herddb.model.DDLStatementExecutionResult) DMLStatementExecutionResult(herddb.model.DMLStatementExecutionResult) StatementExecutionResult(herddb.model.StatementExecutionResult) DuplicatePrimaryKeyException(herddb.model.DuplicatePrimaryKeyException) Record(herddb.model.Record) RunningStatementsStats(herddb.core.RunningStatementsStats) TransactionResult(herddb.model.TransactionResult) TranslatedQuery(herddb.sql.TranslatedQuery) Table(herddb.model.Table) GetResult(herddb.model.GetResult) CommitTransactionStatement(herddb.model.commands.CommitTransactionStatement) RollbackTransactionStatement(herddb.model.commands.RollbackTransactionStatement) BeginTransactionStatement(herddb.model.commands.BeginTransactionStatement) TableAwareStatement(herddb.model.TableAwareStatement) ScanStatement(herddb.model.commands.ScanStatement) Statement(herddb.model.Statement) SQLPlannedOperationStatement(herddb.model.commands.SQLPlannedOperationStatement) DDLStatementExecutionResult(herddb.model.DDLStatementExecutionResult) PduCodec(herddb.proto.PduCodec) TableAwareStatement(herddb.model.TableAwareStatement) DMLStatementExecutionResult(herddb.model.DMLStatementExecutionResult) TransactionContext(herddb.model.TransactionContext) CompletionException(java.util.concurrent.CompletionException) SQLIntegrityConstraintViolationException(java.sql.SQLIntegrityConstraintViolationException) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap)

Aggregations

RunningStatementInfo (herddb.core.RunningStatementInfo)3 RunningStatementsStats (herddb.core.RunningStatementsStats)3 TransactionContext (herddb.model.TransactionContext)3 SQLPlannedOperationStatement (herddb.model.commands.SQLPlannedOperationStatement)3 ScanStatement (herddb.model.commands.ScanStatement)3 PduCodec (herddb.proto.PduCodec)3 TranslatedQuery (herddb.sql.TranslatedQuery)3 RawString (herddb.utils.RawString)3 ByteBuf (io.netty.buffer.ByteBuf)3 ArrayList (java.util.ArrayList)3 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)3 HerdDBInternalException (herddb.core.HerdDBInternalException)2 DDLStatementExecutionResult (herddb.model.DDLStatementExecutionResult)2 DMLStatementExecutionResult (herddb.model.DMLStatementExecutionResult)2 Record (herddb.model.Record)2 Statement (herddb.model.Statement)2 StatementExecutionResult (herddb.model.StatementExecutionResult)2 Table (herddb.model.Table)2 TableAwareStatement (herddb.model.TableAwareStatement)2 BeginTransactionStatement (herddb.model.commands.BeginTransactionStatement)2