Search in sources :

Example 1 with OperationCancelledException

use of com.mysql.cj.exceptions.OperationCancelledException in project aws-mysql-jdbc by awslabs.

the class AbstractQuery method checkCancelTimeout.

@Override
public void checkCancelTimeout() {
    synchronized (this.cancelTimeoutMutex) {
        if (this.cancelStatus != CancelStatus.NOT_CANCELED) {
            CJException cause = this.cancelStatus == CancelStatus.CANCELED_BY_TIMEOUT ? new CJTimeoutException() : new OperationCancelledException();
            resetCancelledState();
            throw cause;
        }
    }
}
Also used : OperationCancelledException(com.mysql.cj.exceptions.OperationCancelledException) CJTimeoutException(com.mysql.cj.exceptions.CJTimeoutException) CJException(com.mysql.cj.exceptions.CJException)

Example 2 with OperationCancelledException

use of com.mysql.cj.exceptions.OperationCancelledException in project aws-mysql-jdbc by awslabs.

the class StatementImpl method executeQuery.

@Override
public java.sql.ResultSet executeQuery(String sql) throws SQLException {
    synchronized (checkClosed().getConnectionMutex()) {
        JdbcConnection locallyScopedConn = this.connection;
        this.retrieveGeneratedKeys = false;
        checkNullOrEmptyQuery(sql);
        resetCancelledState();
        implicitlyCloseAllOpenResults();
        if (sql.charAt(0) == '/') {
            if (sql.startsWith(PING_MARKER)) {
                doPingInstead();
                return this.results;
            }
        }
        setupStreamingTimeout(locallyScopedConn);
        if (this.doEscapeProcessing) {
            Object escapedSqlResult = EscapeProcessor.escapeSQL(sql, this.session.getServerSession().getSessionTimeZone(), this.session.getServerSession().getCapabilities().serverSupportsFracSecs(), this.session.getServerSession().isServerTruncatesFracSecs(), getExceptionInterceptor());
            sql = escapedSqlResult instanceof String ? (String) escapedSqlResult : ((EscapeProcessorResult) escapedSqlResult).escapedSql;
        }
        if (!isResultSetProducingQuery(sql)) {
            throw SQLError.createSQLException(Messages.getString("Statement.57"), MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor());
        }
        CachedResultSetMetaData cachedMetaData = null;
        if (useServerFetch()) {
            this.results = createResultSetUsingServerFetch(sql);
            return this.results;
        }
        CancelQueryTask timeoutTask = null;
        String oldDb = null;
        try {
            timeoutTask = startQueryTimer(this, getTimeoutInMillis());
            if (!locallyScopedConn.getDatabase().equals(getCurrentDatabase())) {
                oldDb = locallyScopedConn.getDatabase();
                locallyScopedConn.setDatabase(getCurrentDatabase());
            }
            // 
            if (locallyScopedConn.getPropertySet().getBooleanProperty(PropertyKey.cacheResultSetMetadata).getValue()) {
                cachedMetaData = locallyScopedConn.getCachedMetaData(sql);
            }
            locallyScopedConn.setSessionMaxRows(this.maxRows);
            statementBegins();
            this.results = ((NativeSession) locallyScopedConn.getSession()).execSQL(this, sql, this.maxRows, null, createStreamingResultSet(), getResultSetFactory(), cachedMetaData, false);
            if (timeoutTask != null) {
                stopQueryTimer(timeoutTask, true, true);
                timeoutTask = null;
            }
        } catch (CJTimeoutException | OperationCancelledException e) {
            throw SQLExceptionsMapping.translateException(e, this.exceptionInterceptor);
        } finally {
            this.query.getStatementExecuting().set(false);
            stopQueryTimer(timeoutTask, false, false);
            if (oldDb != null) {
                locallyScopedConn.setDatabase(oldDb);
            }
        }
        this.lastInsertId = this.results.getUpdateID();
        if (cachedMetaData != null) {
            locallyScopedConn.initializeResultsMetadataFromCache(sql, cachedMetaData, this.results);
        } else {
            if (this.connection.getPropertySet().getBooleanProperty(PropertyKey.cacheResultSetMetadata).getValue()) {
                locallyScopedConn.initializeResultsMetadataFromCache(sql, null, /* will be created */
                this.results);
            }
        }
        return this.results;
    }
}
Also used : CachedResultSetMetaData(com.mysql.cj.jdbc.result.CachedResultSetMetaData) OperationCancelledException(com.mysql.cj.exceptions.OperationCancelledException) CancelQueryTask(com.mysql.cj.CancelQueryTask) CJTimeoutException(com.mysql.cj.exceptions.CJTimeoutException)

Example 3 with OperationCancelledException

use of com.mysql.cj.exceptions.OperationCancelledException in project aws-mysql-jdbc by awslabs.

the class CancelQueryTaskImpl method run.

@Override
public void run() {
    Thread cancelThread = new Thread() {

        @Override
        public void run() {
            Query localQueryToCancel = CancelQueryTaskImpl.this.queryToCancel;
            if (localQueryToCancel == null) {
                return;
            }
            NativeSession session = (NativeSession) localQueryToCancel.getSession();
            if (session == null) {
                return;
            }
            try {
                if (CancelQueryTaskImpl.this.queryTimeoutKillsConnection) {
                    localQueryToCancel.setCancelStatus(CancelStatus.CANCELED_BY_TIMEOUT);
                    session.invokeCleanupListeners(new OperationCancelledException(Messages.getString("Statement.ConnectionKilledDueToTimeout")));
                } else {
                    synchronized (localQueryToCancel.getCancelTimeoutMutex()) {
                        long origConnId = session.getThreadId();
                        HostInfo hostInfo = session.getHostInfo();
                        String database = hostInfo.getDatabase();
                        String user = hostInfo.getUser();
                        String password = hostInfo.getPassword();
                        NativeSession newSession = null;
                        try {
                            newSession = new NativeSession(hostInfo, session.getPropertySet());
                            newSession.connect(hostInfo, user, password, database, 30000, new TransactionEventHandler() {

                                @Override
                                public void transactionCompleted() {
                                }

                                public void transactionBegun() {
                                }
                            });
                            newSession.sendCommand(new NativeMessageBuilder(newSession.getServerSession().supportsQueryAttributes()).buildComQuery(newSession.getSharedSendPacket(), "KILL QUERY " + origConnId), false, 0);
                        } finally {
                            try {
                                newSession.forceClose();
                            } catch (Throwable t) {
                            // no-op.
                            }
                        }
                        localQueryToCancel.setCancelStatus(CancelStatus.CANCELED_BY_TIMEOUT);
                    }
                }
            // } catch (NullPointerException npe) {
            // Case when connection closed while starting to cancel.
            // We can't easily synchronize this, because then one thread can't cancel() a running query.
            // Ignore, we shouldn't re-throw this, because the connection's already closed, so the statement has been timed out.
            } catch (Throwable t) {
                CancelQueryTaskImpl.this.caughtWhileCancelling = t;
            } finally {
                setQueryToCancel(null);
            }
        }
    };
    cancelThread.start();
}
Also used : OperationCancelledException(com.mysql.cj.exceptions.OperationCancelledException) NativeMessageBuilder(com.mysql.cj.protocol.a.NativeMessageBuilder) HostInfo(com.mysql.cj.conf.HostInfo)

Example 4 with OperationCancelledException

use of com.mysql.cj.exceptions.OperationCancelledException in project aws-mysql-jdbc by awslabs.

the class StatementImpl method executeUpdateInternal.

protected long executeUpdateInternal(String sql, boolean isBatch, boolean returnGeneratedKeys) throws SQLException {
    synchronized (checkClosed().getConnectionMutex()) {
        JdbcConnection locallyScopedConn = this.connection;
        checkNullOrEmptyQuery(sql);
        resetCancelledState();
        char firstStatementChar = ParseInfo.firstCharOfStatementUc(sql, this.session.getServerSession().isNoBackslashEscapesSet());
        if (!isNonResultSetProducingQuery(sql)) {
            throw SQLError.createSQLException(Messages.getString("Statement.46"), "01S03", getExceptionInterceptor());
        }
        this.retrieveGeneratedKeys = returnGeneratedKeys;
        this.lastQueryIsOnDupKeyUpdate = returnGeneratedKeys && firstStatementChar == 'I' && containsOnDuplicateKeyInString(sql);
        ResultSetInternalMethods rs = null;
        if (this.doEscapeProcessing) {
            Object escapedSqlResult = EscapeProcessor.escapeSQL(sql, this.session.getServerSession().getSessionTimeZone(), this.session.getServerSession().getCapabilities().serverSupportsFracSecs(), this.session.getServerSession().isServerTruncatesFracSecs(), getExceptionInterceptor());
            sql = escapedSqlResult instanceof String ? (String) escapedSqlResult : ((EscapeProcessorResult) escapedSqlResult).escapedSql;
        }
        if (locallyScopedConn.isReadOnly(false)) {
            throw SQLError.createSQLException(Messages.getString("Statement.42") + Messages.getString("Statement.43"), MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor());
        }
        implicitlyCloseAllOpenResults();
        // The checking and changing of databases must happen in sequence, so synchronize on the same mutex that _conn is using
        CancelQueryTask timeoutTask = null;
        String oldDb = null;
        try {
            timeoutTask = startQueryTimer(this, getTimeoutInMillis());
            if (!locallyScopedConn.getDatabase().equals(getCurrentDatabase())) {
                oldDb = locallyScopedConn.getDatabase();
                locallyScopedConn.setDatabase(getCurrentDatabase());
            }
            // 
            // Only apply max_rows to selects
            // 
            locallyScopedConn.setSessionMaxRows(-1);
            statementBegins();
            // null database: force read of field info on DML
            rs = ((NativeSession) locallyScopedConn.getSession()).execSQL(this, sql, -1, null, false, getResultSetFactory(), null, isBatch);
            if (timeoutTask != null) {
                stopQueryTimer(timeoutTask, true, true);
                timeoutTask = null;
            }
        } catch (CJTimeoutException | OperationCancelledException e) {
            throw SQLExceptionsMapping.translateException(e, this.exceptionInterceptor);
        } finally {
            stopQueryTimer(timeoutTask, false, false);
            if (oldDb != null) {
                locallyScopedConn.setDatabase(oldDb);
            }
            if (!isBatch) {
                this.query.getStatementExecuting().set(false);
            }
        }
        this.results = rs;
        rs.setFirstCharOfQuery(firstStatementChar);
        this.updateCount = rs.getUpdateCount();
        this.lastInsertId = rs.getUpdateID();
        return this.updateCount;
    }
}
Also used : ResultSetInternalMethods(com.mysql.cj.jdbc.result.ResultSetInternalMethods) OperationCancelledException(com.mysql.cj.exceptions.OperationCancelledException) CancelQueryTask(com.mysql.cj.CancelQueryTask) CJTimeoutException(com.mysql.cj.exceptions.CJTimeoutException)

Example 5 with OperationCancelledException

use of com.mysql.cj.exceptions.OperationCancelledException in project aws-mysql-jdbc by awslabs.

the class StatementImpl method executeInternal.

private boolean executeInternal(String sql, boolean returnGeneratedKeys) throws SQLException {
    JdbcConnection locallyScopedConn = checkClosed();
    synchronized (locallyScopedConn.getConnectionMutex()) {
        checkClosed();
        checkNullOrEmptyQuery(sql);
        resetCancelledState();
        implicitlyCloseAllOpenResults();
        if (sql.charAt(0) == '/') {
            if (sql.startsWith(PING_MARKER)) {
                doPingInstead();
                return true;
            }
        }
        this.retrieveGeneratedKeys = returnGeneratedKeys;
        this.lastQueryIsOnDupKeyUpdate = returnGeneratedKeys && ParseInfo.firstCharOfStatementUc(sql, this.session.getServerSession().isNoBackslashEscapesSet()) == 'I' && containsOnDuplicateKeyInString(sql);
        if (!ParseInfo.isReadOnlySafeQuery(sql, this.session.getServerSession().isNoBackslashEscapesSet()) && locallyScopedConn.isReadOnly()) {
            throw SQLError.createSQLException(Messages.getString("Statement.27") + Messages.getString("Statement.28"), MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor());
        }
        try {
            setupStreamingTimeout(locallyScopedConn);
            if (this.doEscapeProcessing) {
                Object escapedSqlResult = EscapeProcessor.escapeSQL(sql, this.session.getServerSession().getSessionTimeZone(), this.session.getServerSession().getCapabilities().serverSupportsFracSecs(), this.session.getServerSession().isServerTruncatesFracSecs(), getExceptionInterceptor());
                sql = escapedSqlResult instanceof String ? (String) escapedSqlResult : ((EscapeProcessorResult) escapedSqlResult).escapedSql;
            }
            CachedResultSetMetaData cachedMetaData = null;
            ResultSetInternalMethods rs = null;
            this.batchedGeneratedKeys = null;
            if (useServerFetch()) {
                rs = createResultSetUsingServerFetch(sql);
            } else {
                CancelQueryTask timeoutTask = null;
                String oldDb = null;
                try {
                    timeoutTask = startQueryTimer(this, getTimeoutInMillis());
                    if (!locallyScopedConn.getDatabase().equals(getCurrentDatabase())) {
                        oldDb = locallyScopedConn.getDatabase();
                        locallyScopedConn.setDatabase(getCurrentDatabase());
                    }
                    // Check if we have cached metadata for this query...
                    if (locallyScopedConn.getPropertySet().getBooleanProperty(PropertyKey.cacheResultSetMetadata).getValue()) {
                        cachedMetaData = locallyScopedConn.getCachedMetaData(sql);
                    }
                    // Only apply max_rows to selects
                    locallyScopedConn.setSessionMaxRows(isResultSetProducingQuery(sql) ? this.maxRows : -1);
                    statementBegins();
                    rs = ((NativeSession) locallyScopedConn.getSession()).execSQL(this, sql, this.maxRows, null, createStreamingResultSet(), getResultSetFactory(), cachedMetaData, false);
                    if (timeoutTask != null) {
                        stopQueryTimer(timeoutTask, true, true);
                        timeoutTask = null;
                    }
                } catch (CJTimeoutException | OperationCancelledException e) {
                    throw SQLExceptionsMapping.translateException(e, this.exceptionInterceptor);
                } finally {
                    stopQueryTimer(timeoutTask, false, false);
                    if (oldDb != null) {
                        locallyScopedConn.setDatabase(oldDb);
                    }
                }
            }
            if (rs != null) {
                this.lastInsertId = rs.getUpdateID();
                this.results = rs;
                rs.setFirstCharOfQuery(ParseInfo.firstCharOfStatementUc(sql, this.session.getServerSession().isNoBackslashEscapesSet()));
                if (rs.hasRows()) {
                    if (cachedMetaData != null) {
                        locallyScopedConn.initializeResultsMetadataFromCache(sql, cachedMetaData, this.results);
                    } else if (this.session.getPropertySet().getBooleanProperty(PropertyKey.cacheResultSetMetadata).getValue()) {
                        locallyScopedConn.initializeResultsMetadataFromCache(sql, null, /* will be created */
                        this.results);
                    }
                }
            }
            return ((rs != null) && rs.hasRows());
        } finally {
            this.query.getStatementExecuting().set(false);
        }
    }
}
Also used : ResultSetInternalMethods(com.mysql.cj.jdbc.result.ResultSetInternalMethods) CachedResultSetMetaData(com.mysql.cj.jdbc.result.CachedResultSetMetaData) OperationCancelledException(com.mysql.cj.exceptions.OperationCancelledException) CancelQueryTask(com.mysql.cj.CancelQueryTask) CJTimeoutException(com.mysql.cj.exceptions.CJTimeoutException)

Aggregations

OperationCancelledException (com.mysql.cj.exceptions.OperationCancelledException)5 CJTimeoutException (com.mysql.cj.exceptions.CJTimeoutException)4 CancelQueryTask (com.mysql.cj.CancelQueryTask)3 CachedResultSetMetaData (com.mysql.cj.jdbc.result.CachedResultSetMetaData)2 ResultSetInternalMethods (com.mysql.cj.jdbc.result.ResultSetInternalMethods)2 HostInfo (com.mysql.cj.conf.HostInfo)1 CJException (com.mysql.cj.exceptions.CJException)1 NativeMessageBuilder (com.mysql.cj.protocol.a.NativeMessageBuilder)1