Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connection schema is not recovered to settings value when setSchema is used (underline connection is Postgres). #2170

Open
hondogo opened this issue Feb 9, 2024 · 0 comments

Comments

@hondogo
Copy link

hondogo commented Feb 9, 2024

Reproduction code with explanations in comments:

public static void main(String[] args) throws Exception {
        try (HikariDataSource dataSource = new HikariDataSource()) {
            // configuring connection settings for Postgres
            dataSource.setJdbcUrl("jdbc:postgresql://localhost:5432/postgres"); // change to your Postgres connection settings
            dataSource.setUsername("postgres"); // change to your Postgres connection settings
            dataSource.setPassword("postgres"); // change to your Postgres connection settings
            //
            dataSource.setAutoCommit(false);
            dataSource.setSchema("public");
            dataSource.setMinimumIdle(1); // to be ensured we take the same connection from pool
            dataSource.setMaximumPoolSize(1); // to be ensured we take the same connection from pool
            // preparing for test (creating schema schema1 if not exists)
            try (Connection connection = dataSource.getConnection()) {
                connection.setSchema("schema1");
                if (connection.getSchema() == null) {
                    try (PreparedStatement stm = connection.prepareStatement("create schema schema1")) {
                        stm.executeUpdate();
                    }
                }
                connection.setSchema("public"); 
                connection.commit();
            }
            // start of test
            try (Connection connection = dataSource.getConnection()) {
                if (!"public".equals(connection.getSchema())) { // OK (skip if)
                    throw new AssertionError(connection.getSchema());
                }
                connection.setSchema("schema1");
                if (!"schema1".equals(connection.getSchema())) { // OK (skip if)
                    throw new AssertionError(connection.getSchema());
                }
                connection.commit(); // Postgres save default schema in session scope on commit
                connection.setSchema("public");
                connection.rollback(); // Postgres restore default schema in session from last commit (schema1) but com.zaxxer.hikari.pool.ProxyConnection::dbschema is still equals to "public" schema
                if ("public".equals(connection.getSchema())) { // OK (skip if) ProxyConnection.getSchema is directly calling Postgres connection getSchema() that is schema1 after rollback
                    throw new AssertionError(connection.getSchema());
                }
            } // while on close there is code in com.zaxxer.hikari.pool.PoolBase :
            /*
                // This if statement will be skipped case proxyConnection.getSchemaState() will return not actual schema from variable com.zaxxer.hikari.pool.ProxyConnection::dbschema, so schema in settings is equals to not actual value
                if ((dirtyBits & 32) != 0 && this.schema != null && !this.schema.equals(proxyConnection.getSchemaState())) {
                    connection.setSchema(this.schema);
                    resetBits |= 32;
                }
                // proposed solution is to change call to proxyConnection.getSchemaState() to connection.getSchema()
                // or may be needed to assign actual schema to com.zaxxer.hikari.pool.ProxyConnection::dbschema after rollback to make it sync (if default schema is specified in settings)
             */
            try (Connection connection = dataSource.getConnection()) {
                if (!"public".equals(connection.getSchema())) { // FAIL (execute if body) cause actual Postgres connection schema is "schema1" (it was not reset on previous ProxyConnection::close)
                    throw new AssertionError(connection.getSchema());
                }
            }
        }
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant