Qualify getTables() with catalog and schema.

Without these qualifiers, the tables returned by the metadata object
will include tables from _all_ databases in the database instance, which
is definitely not something we want. Not only does this pose a potential
performance impact, it can also return very false positives, which then
result in an (inaptly named) SQLSyntaxErrorException when the subsequent
query to the potentially non-existent table fails.

To reproduce the issue:

- Create two new, empty databases in a fresh MySQL/MariaDB instance.
- Point the extension at one of them.
- Spin up the server, let the extension initialize the database.
- Stop the server.
- Point the extension at the other database.
- Spin the server back up and watch it crash.

By qualifying the `getTables()` call with the catalog and schema of the
underlying connection object, we limit the search to _just_ that catalog
and schema, which is what we wanted all along. According to the method
documentation, the args are _patterns_, where `%` matches substrings and
`_` matches "any character". So by being hyper-specific, we shouldn't
get any more false positives. In testing on MySQL and MariaDB, only the
`catalog` value is non-null (matches the database name), while `schema`
remains null.
This commit is contained in:
Andreas Troelsen
2022-07-30 15:58:05 +02:00
parent 3f7796772e
commit 627205d39a
@@ -70,8 +70,10 @@ class SchemaMigrator {
// (available via the underlying JDBC connection object) to find
// out if the schema migrations table exists.
Connection connection = handle.getConnection();
String catalog = connection.getCatalog();
String schema = connection.getSchema();
DatabaseMetaData meta = connection.getMetaData();
try (ResultSet tables = meta.getTables(null, null, "schema_migrations", null)) {
try (ResultSet tables = meta.getTables(catalog, schema, "schema_migrations", null)) {
while (tables.next()) {
String name = tables.getString("TABLE_NAME");
if (name.equals("schema_migrations")) {