Search in sources :

Example 1 with PreparedQuery

use of com.mysql.cj.PreparedQuery in project ABC by RuiPinto96274.

the class ClientPreparedStatement method executeBatchedInserts.

/**
 * Rewrites the already prepared statement into a multi-value insert
 * statement of 'statementsPerBatch' values and executes the entire batch
 * using this new statement.
 *
 * @param batchTimeout
 *            timeout for the batch execution
 * @return update counts in the same fashion as executeBatch()
 *
 * @throws SQLException
 *             if a database access error occurs or this method is called on a closed PreparedStatement
 */
protected long[] executeBatchedInserts(int batchTimeout) throws SQLException {
    synchronized (checkClosed().getConnectionMutex()) {
        String valuesClause = getParseInfo().getValuesClause();
        JdbcConnection locallyScopedConn = this.connection;
        if (valuesClause == null) {
            return executeBatchSerially(batchTimeout);
        }
        int numBatchedArgs = this.query.getBatchedArgs().size();
        if (this.retrieveGeneratedKeys) {
            this.batchedGeneratedKeys = new ArrayList<>(numBatchedArgs);
        }
        int numValuesPerBatch = ((PreparedQuery<?>) this.query).computeBatchSize(numBatchedArgs);
        if (numBatchedArgs < numValuesPerBatch) {
            numValuesPerBatch = numBatchedArgs;
        }
        JdbcPreparedStatement batchedStatement = null;
        int batchedParamIndex = 1;
        long updateCountRunningTotal = 0;
        int numberToExecuteAsMultiValue = 0;
        int batchCounter = 0;
        CancelQueryTask timeoutTask = null;
        SQLException sqlEx = null;
        long[] updateCounts = new long[numBatchedArgs];
        try {
            try {
                batchedStatement = /* FIXME -if we ever care about folks proxying our JdbcConnection */
                prepareBatchedInsertSQL(locallyScopedConn, numValuesPerBatch);
                timeoutTask = startQueryTimer(batchedStatement, batchTimeout);
                numberToExecuteAsMultiValue = numBatchedArgs < numValuesPerBatch ? numBatchedArgs : numBatchedArgs / numValuesPerBatch;
                int numberArgsToExecute = numberToExecuteAsMultiValue * numValuesPerBatch;
                for (int i = 0; i < numberArgsToExecute; i++) {
                    if (i != 0 && i % numValuesPerBatch == 0) {
                        try {
                            updateCountRunningTotal += batchedStatement.executeLargeUpdate();
                        } catch (SQLException ex) {
                            sqlEx = handleExceptionForBatch(batchCounter - 1, numValuesPerBatch, updateCounts, ex);
                        }
                        getBatchedGeneratedKeys(batchedStatement);
                        batchedStatement.clearParameters();
                        batchedParamIndex = 1;
                    }
                    batchedParamIndex = setOneBatchedParameterSet(batchedStatement, batchedParamIndex, this.query.getBatchedArgs().get(batchCounter++));
                }
                try {
                    updateCountRunningTotal += batchedStatement.executeLargeUpdate();
                } catch (SQLException ex) {
                    sqlEx = handleExceptionForBatch(batchCounter - 1, numValuesPerBatch, updateCounts, ex);
                }
                getBatchedGeneratedKeys(batchedStatement);
                numValuesPerBatch = numBatchedArgs - batchCounter;
            } finally {
                if (batchedStatement != null) {
                    batchedStatement.close();
                    batchedStatement = null;
                }
            }
            try {
                if (numValuesPerBatch > 0) {
                    batchedStatement = prepareBatchedInsertSQL(locallyScopedConn, numValuesPerBatch);
                    if (timeoutTask != null) {
                        timeoutTask.setQueryToCancel(batchedStatement);
                    }
                    batchedParamIndex = 1;
                    while (batchCounter < numBatchedArgs) {
                        batchedParamIndex = setOneBatchedParameterSet(batchedStatement, batchedParamIndex, this.query.getBatchedArgs().get(batchCounter++));
                    }
                    try {
                        updateCountRunningTotal += batchedStatement.executeLargeUpdate();
                    } catch (SQLException ex) {
                        sqlEx = handleExceptionForBatch(batchCounter - 1, numValuesPerBatch, updateCounts, ex);
                    }
                    getBatchedGeneratedKeys(batchedStatement);
                }
                if (sqlEx != null) {
                    throw SQLError.createBatchUpdateException(sqlEx, updateCounts, this.exceptionInterceptor);
                }
                if (numBatchedArgs > 1) {
                    long updCount = updateCountRunningTotal > 0 ? java.sql.Statement.SUCCESS_NO_INFO : 0;
                    for (int j = 0; j < numBatchedArgs; j++) {
                        updateCounts[j] = updCount;
                    }
                } else {
                    updateCounts[0] = updateCountRunningTotal;
                }
                return updateCounts;
            } finally {
                if (batchedStatement != null) {
                    batchedStatement.close();
                }
            }
        } finally {
            stopQueryTimer(timeoutTask, false, false);
            resetCancelledState();
        }
    }
}
Also used : SQLException(java.sql.SQLException) ClientPreparedQuery(com.mysql.cj.ClientPreparedQuery) PreparedQuery(com.mysql.cj.PreparedQuery) CancelQueryTask(com.mysql.cj.CancelQueryTask)

Example 2 with PreparedQuery

use of com.mysql.cj.PreparedQuery in project ABC by RuiPinto96274.

the class ClientPreparedStatement method executePreparedBatchAsMultiStatement.

/**
 * Rewrites the already prepared statement into a multi-statement
 * query of 'statementsPerBatch' values and executes the entire batch
 * using this new statement.
 *
 * @param batchTimeout
 *            timeout for the batch execution
 * @return update counts in the same fashion as executeBatch()
 *
 * @throws SQLException
 *             if a database access error occurs or this method is called on a closed PreparedStatement
 */
protected long[] executePreparedBatchAsMultiStatement(int batchTimeout) throws SQLException {
    synchronized (checkClosed().getConnectionMutex()) {
        // This is kind of an abuse, but it gets the job done
        if (this.batchedValuesClause == null) {
            this.batchedValuesClause = ((PreparedQuery<?>) this.query).getOriginalSql() + ";";
        }
        JdbcConnection locallyScopedConn = this.connection;
        boolean multiQueriesEnabled = locallyScopedConn.getPropertySet().getBooleanProperty(PropertyKey.allowMultiQueries).getValue();
        CancelQueryTask timeoutTask = null;
        try {
            clearWarnings();
            int numBatchedArgs = this.query.getBatchedArgs().size();
            if (this.retrieveGeneratedKeys) {
                this.batchedGeneratedKeys = new ArrayList<>(numBatchedArgs);
            }
            int numValuesPerBatch = ((PreparedQuery<?>) this.query).computeBatchSize(numBatchedArgs);
            if (numBatchedArgs < numValuesPerBatch) {
                numValuesPerBatch = numBatchedArgs;
            }
            java.sql.PreparedStatement batchedStatement = null;
            int batchedParamIndex = 1;
            int numberToExecuteAsMultiValue = 0;
            int batchCounter = 0;
            int updateCountCounter = 0;
            long[] updateCounts = new long[numBatchedArgs * getParseInfo().getNumberOfQueries()];
            SQLException sqlEx = null;
            try {
                if (!multiQueriesEnabled) {
                    ((NativeSession) locallyScopedConn.getSession()).enableMultiQueries();
                }
                batchedStatement = this.retrieveGeneratedKeys ? ((Wrapper) locallyScopedConn.prepareStatement(generateMultiStatementForBatch(numValuesPerBatch), RETURN_GENERATED_KEYS)).unwrap(java.sql.PreparedStatement.class) : ((Wrapper) locallyScopedConn.prepareStatement(generateMultiStatementForBatch(numValuesPerBatch))).unwrap(java.sql.PreparedStatement.class);
                timeoutTask = startQueryTimer((StatementImpl) batchedStatement, batchTimeout);
                numberToExecuteAsMultiValue = numBatchedArgs < numValuesPerBatch ? numBatchedArgs : numBatchedArgs / numValuesPerBatch;
                int numberArgsToExecute = numberToExecuteAsMultiValue * numValuesPerBatch;
                for (int i = 0; i < numberArgsToExecute; i++) {
                    if (i != 0 && i % numValuesPerBatch == 0) {
                        try {
                            batchedStatement.execute();
                        } catch (SQLException ex) {
                            sqlEx = handleExceptionForBatch(batchCounter, numValuesPerBatch, updateCounts, ex);
                        }
                        updateCountCounter = processMultiCountsAndKeys((StatementImpl) batchedStatement, updateCountCounter, updateCounts);
                        batchedStatement.clearParameters();
                        batchedParamIndex = 1;
                    }
                    batchedParamIndex = setOneBatchedParameterSet(batchedStatement, batchedParamIndex, this.query.getBatchedArgs().get(batchCounter++));
                }
                try {
                    batchedStatement.execute();
                } catch (SQLException ex) {
                    sqlEx = handleExceptionForBatch(batchCounter - 1, numValuesPerBatch, updateCounts, ex);
                }
                updateCountCounter = processMultiCountsAndKeys((StatementImpl) batchedStatement, updateCountCounter, updateCounts);
                batchedStatement.clearParameters();
                numValuesPerBatch = numBatchedArgs - batchCounter;
                if (timeoutTask != null) {
                    // we need to check the cancel state now because we loose if after the following batchedStatement.close()
                    ((JdbcPreparedStatement) batchedStatement).checkCancelTimeout();
                }
            } finally {
                if (batchedStatement != null) {
                    batchedStatement.close();
                    batchedStatement = null;
                }
            }
            try {
                if (numValuesPerBatch > 0) {
                    batchedStatement = this.retrieveGeneratedKeys ? locallyScopedConn.prepareStatement(generateMultiStatementForBatch(numValuesPerBatch), RETURN_GENERATED_KEYS) : locallyScopedConn.prepareStatement(generateMultiStatementForBatch(numValuesPerBatch));
                    if (timeoutTask != null) {
                        timeoutTask.setQueryToCancel((Query) batchedStatement);
                    }
                    batchedParamIndex = 1;
                    while (batchCounter < numBatchedArgs) {
                        batchedParamIndex = setOneBatchedParameterSet(batchedStatement, batchedParamIndex, this.query.getBatchedArgs().get(batchCounter++));
                    }
                    try {
                        batchedStatement.execute();
                    } catch (SQLException ex) {
                        sqlEx = handleExceptionForBatch(batchCounter - 1, numValuesPerBatch, updateCounts, ex);
                    }
                    updateCountCounter = processMultiCountsAndKeys((StatementImpl) batchedStatement, updateCountCounter, updateCounts);
                    batchedStatement.clearParameters();
                }
                if (timeoutTask != null) {
                    stopQueryTimer(timeoutTask, true, true);
                    timeoutTask = null;
                }
                if (sqlEx != null) {
                    throw SQLError.createBatchUpdateException(sqlEx, updateCounts, this.exceptionInterceptor);
                }
                return updateCounts;
            } finally {
                if (batchedStatement != null) {
                    batchedStatement.close();
                }
            }
        } finally {
            stopQueryTimer(timeoutTask, false, false);
            resetCancelledState();
            if (!multiQueriesEnabled) {
                ((NativeSession) locallyScopedConn.getSession()).disableMultiQueries();
            }
            clearBatch();
        }
    }
}
Also used : Wrapper(java.sql.Wrapper) SQLException(java.sql.SQLException) ClientPreparedQuery(com.mysql.cj.ClientPreparedQuery) PreparedQuery(com.mysql.cj.PreparedQuery) CancelQueryTask(com.mysql.cj.CancelQueryTask) NativeSession(com.mysql.cj.NativeSession)

Example 3 with PreparedQuery

use of com.mysql.cj.PreparedQuery in project ABC by RuiPinto96274.

the class ClientPreparedStatement method getMetaData.

@Override
public java.sql.ResultSetMetaData getMetaData() throws SQLException {
    synchronized (checkClosed().getConnectionMutex()) {
        if (!isResultSetProducingQuery()) {
            return null;
        }
        JdbcPreparedStatement mdStmt = null;
        java.sql.ResultSet mdRs = null;
        if (this.pstmtResultMetaData == null) {
            try {
                mdStmt = new ClientPreparedStatement(this.connection, ((PreparedQuery<?>) this.query).getOriginalSql(), this.getCurrentDatabase(), getParseInfo());
                mdStmt.setMaxRows(1);
                int paramCount = ((PreparedQuery<?>) this.query).getParameterCount();
                for (int i = 1; i <= paramCount; i++) {
                    mdStmt.setString(i, null);
                }
                boolean hadResults = mdStmt.execute();
                if (hadResults) {
                    mdRs = mdStmt.getResultSet();
                    this.pstmtResultMetaData = mdRs.getMetaData();
                } else {
                    this.pstmtResultMetaData = new ResultSetMetaData(this.session, new Field[0], this.session.getPropertySet().getBooleanProperty(PropertyKey.useOldAliasMetadataBehavior).getValue(), this.session.getPropertySet().getBooleanProperty(PropertyKey.yearIsDateType).getValue(), this.exceptionInterceptor);
                }
            } finally {
                SQLException sqlExRethrow = null;
                if (mdRs != null) {
                    try {
                        mdRs.close();
                    } catch (SQLException sqlEx) {
                        sqlExRethrow = sqlEx;
                    }
                    mdRs = null;
                }
                if (mdStmt != null) {
                    try {
                        mdStmt.close();
                    } catch (SQLException sqlEx) {
                        sqlExRethrow = sqlEx;
                    }
                    mdStmt = null;
                }
                if (sqlExRethrow != null) {
                    throw sqlExRethrow;
                }
            }
        }
        return this.pstmtResultMetaData;
    }
}
Also used : CachedResultSetMetaData(com.mysql.cj.jdbc.result.CachedResultSetMetaData) ResultSetMetaData(com.mysql.cj.jdbc.result.ResultSetMetaData) Field(com.mysql.cj.result.Field) SQLException(java.sql.SQLException) ClientPreparedQuery(com.mysql.cj.ClientPreparedQuery) PreparedQuery(com.mysql.cj.PreparedQuery)

Example 4 with PreparedQuery

use of com.mysql.cj.PreparedQuery in project ABC by RuiPinto96274.

the class ClientPreparedStatement method initializeFromParseInfo.

@SuppressWarnings("unchecked")
private void initializeFromParseInfo() throws SQLException {
    synchronized (checkClosed().getConnectionMutex()) {
        int parameterCount = getParseInfo().getStaticSql().length - 1;
        ((PreparedQuery<?>) this.query).setParameterCount(parameterCount);
        ((PreparedQuery<ClientPreparedQueryBindings>) this.query).setQueryBindings(new ClientPreparedQueryBindings(parameterCount, this.session));
        ((ClientPreparedQuery) this.query).getQueryBindings().setLoadDataQuery(getParseInfo().isLoadData());
        clearParameters();
    }
}
Also used : ClientPreparedQueryBindings(com.mysql.cj.ClientPreparedQueryBindings) ClientPreparedQuery(com.mysql.cj.ClientPreparedQuery) PreparedQuery(com.mysql.cj.PreparedQuery)

Example 5 with PreparedQuery

use of com.mysql.cj.PreparedQuery in project ABC by RuiPinto96274.

the class ClientPreparedStatement method executeBatchSerially.

/**
 * Executes the current batch of statements by executing them one-by-one.
 *
 * @param batchTimeout
 *            timeout for the batch execution
 * @return a list of update counts
 * @throws SQLException
 *             if an error occurs
 */
protected long[] executeBatchSerially(int batchTimeout) throws SQLException {
    synchronized (checkClosed().getConnectionMutex()) {
        if (this.connection == null) {
            checkClosed();
        }
        long[] updateCounts = null;
        if (this.query.getBatchedArgs() != null) {
            int nbrCommands = this.query.getBatchedArgs().size();
            updateCounts = new long[nbrCommands];
            for (int i = 0; i < nbrCommands; i++) {
                updateCounts[i] = -3;
            }
            SQLException sqlEx = null;
            CancelQueryTask timeoutTask = null;
            try {
                timeoutTask = startQueryTimer(this, batchTimeout);
                if (this.retrieveGeneratedKeys) {
                    this.batchedGeneratedKeys = new ArrayList<>(nbrCommands);
                }
                int batchCommandIndex = ((PreparedQuery<?>) this.query).getBatchCommandIndex();
                for (batchCommandIndex = 0; batchCommandIndex < nbrCommands; batchCommandIndex++) {
                    ((PreparedQuery<?>) this.query).setBatchCommandIndex(batchCommandIndex);
                    Object arg = this.query.getBatchedArgs().get(batchCommandIndex);
                    try {
                        if (arg instanceof String) {
                            updateCounts[batchCommandIndex] = executeUpdateInternal((String) arg, true, this.retrieveGeneratedKeys);
                            // limit one generated key per OnDuplicateKey statement
                            getBatchedGeneratedKeys(this.results.getFirstCharOfQuery() == 'I' && containsOnDuplicateKeyInString((String) arg) ? 1 : 0);
                        } else {
                            QueryBindings<?> queryBindings = (QueryBindings<?>) arg;
                            updateCounts[batchCommandIndex] = executeUpdateInternal(queryBindings, true);
                            // limit one generated key per OnDuplicateKey statement
                            getBatchedGeneratedKeys(containsOnDuplicateKeyUpdateInSQL() ? 1 : 0);
                        }
                    } catch (SQLException ex) {
                        updateCounts[batchCommandIndex] = EXECUTE_FAILED;
                        if (this.continueBatchOnError && !(ex instanceof MySQLTimeoutException) && !(ex instanceof MySQLStatementCancelledException) && !hasDeadlockOrTimeoutRolledBackTx(ex)) {
                            sqlEx = ex;
                        } else {
                            long[] newUpdateCounts = new long[batchCommandIndex];
                            System.arraycopy(updateCounts, 0, newUpdateCounts, 0, batchCommandIndex);
                            throw SQLError.createBatchUpdateException(ex, newUpdateCounts, this.exceptionInterceptor);
                        }
                    }
                }
                if (sqlEx != null) {
                    throw SQLError.createBatchUpdateException(sqlEx, updateCounts, this.exceptionInterceptor);
                }
            } catch (NullPointerException npe) {
                try {
                    checkClosed();
                } catch (StatementIsClosedException connectionClosedEx) {
                    int batchCommandIndex = ((PreparedQuery<?>) this.query).getBatchCommandIndex();
                    updateCounts[batchCommandIndex] = EXECUTE_FAILED;
                    long[] newUpdateCounts = new long[batchCommandIndex];
                    System.arraycopy(updateCounts, 0, newUpdateCounts, 0, batchCommandIndex);
                    throw SQLError.createBatchUpdateException(SQLExceptionsMapping.translateException(connectionClosedEx), newUpdateCounts, this.exceptionInterceptor);
                }
                // we don't know why this happened, punt
                throw npe;
            } finally {
                ((PreparedQuery<?>) this.query).setBatchCommandIndex(-1);
                stopQueryTimer(timeoutTask, false, false);
                resetCancelledState();
            }
        }
        return (updateCounts != null) ? updateCounts : new long[0];
    }
}
Also used : SQLException(java.sql.SQLException) QueryBindings(com.mysql.cj.QueryBindings) ClientPreparedQueryBindings(com.mysql.cj.ClientPreparedQueryBindings) ClientPreparedQuery(com.mysql.cj.ClientPreparedQuery) PreparedQuery(com.mysql.cj.PreparedQuery) MySQLTimeoutException(com.mysql.cj.jdbc.exceptions.MySQLTimeoutException) CancelQueryTask(com.mysql.cj.CancelQueryTask) MySQLStatementCancelledException(com.mysql.cj.jdbc.exceptions.MySQLStatementCancelledException) StatementIsClosedException(com.mysql.cj.exceptions.StatementIsClosedException)

Aggregations

PreparedQuery (com.mysql.cj.PreparedQuery)30 ClientPreparedQuery (com.mysql.cj.ClientPreparedQuery)24 SQLException (java.sql.SQLException)18 CancelQueryTask (com.mysql.cj.CancelQueryTask)9 CachedResultSetMetaData (com.mysql.cj.jdbc.result.CachedResultSetMetaData)9 Message (com.mysql.cj.protocol.Message)9 ClientPreparedQueryBindings (com.mysql.cj.ClientPreparedQueryBindings)6 ServerPreparedQuery (com.mysql.cj.ServerPreparedQuery)6 MySQLStatementCancelledException (com.mysql.cj.jdbc.exceptions.MySQLStatementCancelledException)6 MySQLTimeoutException (com.mysql.cj.jdbc.exceptions.MySQLTimeoutException)6 ResultSetInternalMethods (com.mysql.cj.jdbc.result.ResultSetInternalMethods)6 NativeSession (com.mysql.cj.NativeSession)3 QueryBindings (com.mysql.cj.QueryBindings)3 QueryReturnType (com.mysql.cj.QueryReturnType)3 ServerPreparedQueryBindValue (com.mysql.cj.ServerPreparedQueryBindValue)3 CJException (com.mysql.cj.exceptions.CJException)3 StatementIsClosedException (com.mysql.cj.exceptions.StatementIsClosedException)3 WrongArgumentException (com.mysql.cj.exceptions.WrongArgumentException)3 ResultSetMetaData (com.mysql.cj.jdbc.result.ResultSetMetaData)3 Field (com.mysql.cj.result.Field)3