Describe the bug
When multiple schemas/databases on the same MySQL instance each have an iceberg_tables table with different schema versions (V0 vs V1), JdbcCatalog incorrectly detects the iceberg_type column from a different schema, causing schemaVersion to be wrongly set to V1 while the actual table in the current connection's schema is V0.
This results in SQLSyntaxErrorException: Unknown column 'iceberg_type' in 'where clause' when creating or loading tables.
Root Cause
In JdbcCatalog.java, both updateSchemaIfRequired() and atomicCreateTable() call DatabaseMetaData.getColumns() / getTables() with null as the catalog parameter:
// updateSchemaIfRequired() — line 234
dbMeta.getColumns(
null, // ← scans ALL schemas on the server
null,
JdbcUtil.CATALOG_TABLE_VIEW_NAME, // "iceberg_tables" — '_' is a LIKE wildcard
JdbcUtil.RECORD_TYPE); // "iceberg_type"
// atomicCreateTable() — line 171
dbMeta.getTables(
null, // ← scans ALL schemas on the server
null,
name,
null);
Per JDBC spec, null for the catalog parameter means "no limitation" — the driver scans all schemas/databases on the server. When another schema on the same MySQL instance has an iceberg_tables table with the iceberg_type column (V1 schema), getColumns() returns that column even though the current connection's schema has a V0 table (without iceberg_type). This causes schemaVersion to be incorrectly set to V1, and subsequent V1 SQL queries fail with Unknown column 'iceberg_type'.
Additionally, iceberg_tables contains underscores (_), which are single-character wildcards in SQL LIKE matching, potentially causing further false matches.
To Reproduce
Environment: A single MySQL instance with two schemas:
metaservice_db — has iceberg_tables with iceberg_type column (V1 schema)
iceberg_catalog_db — has iceberg_tables without iceberg_type column (V0 schema)
Flink SQL:
create catalog custom_iceberg_jdbc with (
'type' = 'iceberg',
'catalog-impl' = 'org.apache.iceberg.jdbc.JdbcCatalog',
'catalog-name' = 'custom_iceberg_jdbc',
'uri' = 'jdbc:mysql://host:port/iceberg_catalog_db',
'jdbc.user' = 'root',
'jdbc.password' = '***',
'jdbc.schema-version' = 'V0',
'warehouse' = 'hdfs://...'
);
create table if not exists custom_iceberg_jdbc.my_db.my_table (id int, name string);
Even though jdbc.schema-version=V0 is set, the error still occurs:
Caused by: java.sql.SQLSyntaxErrorException: Unknown column 'iceberg_type' in 'where clause'
at org.apache.iceberg.jdbc.JdbcUtil.lambda$tableOrView$2(JdbcUtil.java:614)
at org.apache.iceberg.jdbc.JdbcUtil.tableOrView(JdbcUtil.java:602)
at org.apache.iceberg.jdbc.JdbcUtil.loadTable(JdbcUtil.java:641)
at org.apache.iceberg.jdbc.JdbcTableOperations.doRefresh(JdbcTableOperations.java:74)
Verification on MySQL
-- Simulating getColumns(null, null, 'iceberg_tables', 'iceberg_type') — scans ALL schemas
SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME
FROM information_schema.COLUMNS
WHERE TABLE_NAME LIKE 'iceberg\_tables' AND COLUMN_NAME LIKE 'iceberg_type';
-- Result: metaservice_db | iceberg_tables | iceberg_type ← false positive from another schema!
-- Simulating getColumns('iceberg_catalog_db', null, 'iceberg_tables', 'iceberg_type') — limited to current schema
SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'iceberg_catalog_db' AND TABLE_NAME LIKE 'iceberg\_tables' AND COLUMN_NAME LIKE 'iceberg_type';
-- Result: (empty) ← correct, no iceberg_type column in this schema
-- Current schema's iceberg_tables table structure:
DESCRIBE iceberg_catalog_db.iceberg_tables;
-- Only 5 columns: catalog_name, table_namespace, table_name, metadata_location, previous_metadata_location
-- No iceberg_type column (V0 schema)
Expected behavior
JdbcCatalog should only check for the iceberg_type column within the schema/database specified in the JDBC connection URL, not across all schemas on the server. The jdbc.schema-version=V0 setting should be respected, and schemaVersion should remain V0 when the current schema's iceberg_tables table lacks the iceberg_type column.
Proposed Fix
Use conn.getCatalog() to limit the getColumns / getTables search scope to the current schema, and escape underscores in the table name pattern to prevent LIKE wildcard matching:
// updateSchemaIfRequired()
String catalog = conn.getCatalog();
String escapedTableName = JdbcUtil.CATALOG_TABLE_VIEW_NAME.replace("_", "\\_");
ResultSet typeColumn = dbMeta.getColumns(catalog, null, escapedTableName, JdbcUtil.RECORD_TYPE);
// atomicCreateTable()
String catalog = conn.getCatalog();
String escapedName = name.replace("_", "\\_");
ResultSet result = dbMeta.getTables(catalog, null, escapedName, null);
Why existing tests didn't catch this
All existing JdbcCatalog tests use SQLite (in-memory or file-based). SQLite does not have the concept of multiple schemas/databases on the same server in the same way MySQL does, so getColumns(null, null, ...) in SQLite only sees the current database. The bug only manifests with multi-schema databases like MySQL or PostgreSQL when multiple schemas coexist on the same instance.
Impact
This bug affects any deployment where multiple schemas on the same database instance have iceberg_tables tables with different schema versions. This is common in:
- Shared database instances (e.g., a metaservice schema and user catalog schemas coexisting on the same MySQL instance)
- Multi-tenant environments where different tenants use different schemas on the same database server
The same class of bug has been reported in other Iceberg language implementations:
Environment
- Iceberg version: 1.10.x (also confirmed present on
main branch as of July 2026)
- Database: MySQL 8.0
- Compute engine: Flink 1.20
Describe the bug
When multiple schemas/databases on the same MySQL instance each have an
iceberg_tablestable with different schema versions (V0 vs V1),JdbcCatalogincorrectly detects theiceberg_typecolumn from a different schema, causingschemaVersionto be wrongly set to V1 while the actual table in the current connection's schema is V0.This results in
SQLSyntaxErrorException: Unknown column 'iceberg_type' in 'where clause'when creating or loading tables.Root Cause
In
JdbcCatalog.java, bothupdateSchemaIfRequired()andatomicCreateTable()callDatabaseMetaData.getColumns()/getTables()withnullas the catalog parameter:Per JDBC spec,
nullfor the catalog parameter means "no limitation" — the driver scans all schemas/databases on the server. When another schema on the same MySQL instance has aniceberg_tablestable with theiceberg_typecolumn (V1 schema),getColumns()returns that column even though the current connection's schema has a V0 table (withouticeberg_type). This causesschemaVersionto be incorrectly set toV1, and subsequent V1 SQL queries fail withUnknown column 'iceberg_type'.Additionally,
iceberg_tablescontains underscores (_), which are single-character wildcards in SQLLIKEmatching, potentially causing further false matches.To Reproduce
Environment: A single MySQL instance with two schemas:
metaservice_db— hasiceberg_tableswithiceberg_typecolumn (V1 schema)iceberg_catalog_db— hasiceberg_tableswithouticeberg_typecolumn (V0 schema)Flink SQL:
Even though
jdbc.schema-version=V0is set, the error still occurs:Verification on MySQL
Expected behavior
JdbcCatalogshould only check for theiceberg_typecolumn within the schema/database specified in the JDBC connection URL, not across all schemas on the server. Thejdbc.schema-version=V0setting should be respected, andschemaVersionshould remain V0 when the current schema'siceberg_tablestable lacks theiceberg_typecolumn.Proposed Fix
Use
conn.getCatalog()to limit thegetColumns/getTablessearch scope to the current schema, and escape underscores in the table name pattern to prevent LIKE wildcard matching:Why existing tests didn't catch this
All existing
JdbcCatalogtests use SQLite (in-memory or file-based). SQLite does not have the concept of multiple schemas/databases on the same server in the same way MySQL does, sogetColumns(null, null, ...)in SQLite only sees the current database. The bug only manifests with multi-schema databases like MySQL or PostgreSQL when multiple schemas coexist on the same instance.Impact
This bug affects any deployment where multiple schemas on the same database instance have
iceberg_tablestables with different schema versions. This is common in:The same class of bug has been reported in other Iceberg language implementations:
Environment
mainbranch as of July 2026)