class QueryStatementCallback implements StatementCallback {

        private final SqlStatement sql;
        private final List<SqlVisitor> sqlVisitors;
        private final ResultSetExtractor rse;

        private QueryStatementCallback(SqlStatement sql, ResultSetExtractor rse, List<SqlVisitor> sqlVisitors) {
            this.sql = sql;
            this.rse = rse;
            this.sqlVisitors = sqlVisitors;
        }


        /**
         * 1. Applies all SqlVisitor to the stmt
         * 2. Executes the (possibly modified) stmt
         * 3. Reads all data from the java.sql.ResultSet into an Object and returns the Object.
         *
         * @param stmt A JDBC Statement that is expected to return a ResultSet (e.g. SELECT)
         * @return An object representing all data from the result set.
         * @throws SQLException      If an error occurs during SQL processing
         * @throws DatabaseException If an error occurs in the DBMS-specific program code
         */
        @Override
        // Incorrect warning, at least at this point. The situation here is not that we inject some unsanitised
        // parameter into a query. Instead, we process a whole query. The check should be performed at the places where
        // the query is composed.
        @SuppressWarnings("squid:S2077")
        public Object doInStatement(Statement stmt) throws SQLException, DatabaseException {<FILL_FUNCTION_BODY>}


        @Override
        public SqlStatement getStatement() {
            return sql;
        }
    }

            ResultSet rs = null;
            try {
                String[] sqlToExecute = applyVisitors(sql, sqlVisitors);

                if (sqlToExecute.length != 1) {
                    throw new DatabaseException("Can only query with statements that return one sql statement");
                }

                try {
                    rs = stmt.executeQuery(sqlToExecute[0]);
                    ResultSet rsToUse = rs;
                    return rse.extractData(rsToUse);
                } finally {
                    for (SqlListener listener : Scope.getCurrentScope().getListeners(SqlListener.class)) {
                        listener.readSqlWillRun(sqlToExecute[0]);
                    }
                }
            } finally {
                if (rs != null) {
                    JdbcUtil.closeResultSet(rs);
                }
            }
        
<methods>public non-sealed void <init>() ,public void execute(liquibase.change.Change) throws liquibase.exception.DatabaseException,public void execute(liquibase.change.Change, List<liquibase.sql.visitor.SqlVisitor>) throws liquibase.exception.DatabaseException,public abstract java.lang.String getName() ,public abstract int getPriority() ,public void modifyChangeSet(liquibase.changelog.ChangeSet) ,public void setDatabase(liquibase.database.Database) ,public void setResourceAccessor(liquibase.resource.ResourceAccessor) ,public liquibase.exception.ValidationErrors validate(liquibase.changelog.ChangeSet) <variables>protected liquibase.database.Database database,protected liquibase.resource.ResourceAccessor resourceAccessor