{"record":{"id":"ed060d647b300e8f","repo":"apache/seatunnel","slug":"no-columns-found-for-catalog-schema-ta-ed060d","errorCode":null,"errorMessage":"No columns found for catalog '{}', schema '{}', table '{}'. Filtered {} rows returned by JDBC driver. The table may not exist or the database requires exact identifier case.","messagePattern":"No columns found for catalog '(.+?)', schema '(.+?)', table '(.+?)'\\. Filtered (.+?) rows returned by JDBC driver\\. The table may not exist or the database requires exact identifier case\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/JdbcDialectTypeMapper.java","lineNumber":145,"sourceCode":"                String comment = rs.getString(\"REMARKS\");\n\n                BasicTypeDefine typeDefine =\n                        BasicTypeDefine.builder()\n                                .name(columnName)\n                                .columnType(nativeType)\n                                .dataType(nativeType)\n                                .sqlType(sqlType)\n                                .length((long) columnSize)\n                                .precision((long) columnSize)\n                                .scale(decimalDigits)\n                                .nullable(nullable == DatabaseMetaData.columnNullable)\n                                .comment(comment)\n                                .build();\n                columns.add(mappingColumn(typeDefine));\n            }\n        }\n        if (columns.isEmpty() && filteredRows > 0) {\n            LOG.warn(\n                    \"No columns found for catalog '{}', schema '{}', table '{}'. Filtered {} rows returned by JDBC driver. \"\n                            + \"The table may not exist or the database requires exact identifier case.\",\n                    catalog,\n                    schemaPattern,\n                    tableNamePattern,\n                    filteredRows);\n        }\n        return columns;\n    }\n\n    default List<Column> mappingColumn(ResultSetMetaData metadata) throws SQLException {\n        List<Column> columns = new ArrayList<>();\n        for (int index = 1; index <= metadata.getColumnCount(); index++) {\n            Column column = mappingColumn(metadata, index);\n            columns.add(column);\n        }\n        return columns;\n    }","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/JdbcDialectTypeMapper.java#L127-L163","documentation":"When mapping a JDBC ResultSet metadata row set into SeaTunnel columns, the dialect's type mapper filters out rows whose types it cannot map. If every returned row was filtered and no columns remain, this warning is logged: the JDBC driver returned metadata rows (filteredRows > 0) but none produced a column, typically because the table name/schema/catalog identifiers did not match in case, or the table does not actually exist. getTableSchema will then produce an empty column list.","triggerScenarios":"getTableSchema calls mappingColumn for each metadata row; rows for unrecognized SQL types are skipped. If the table was looked up with wrong-case identifiers (e.g. lowercase 'mytable' on an upper-case-only DB2/Oracle catalog) or the table is missing, the driver returns rows that are all filtered, leaving columns empty.","commonSituations":"Connecting to DB2/Oracle/DM where unquoted identifiers are stored uppercase but configured lowercase in the SeaTunnel table path; typos in catalog/schema/table options; querying a table that was dropped or exists only in another schema; driver returning odd types for temporal/XML columns that the mapper filters.","solutions":["Quote or match the exact identifier case in the table path / catalog, schema, table options (e.g. use MYTABLE for DB2)","Verify the table exists: run the same catalog/schema/table lookup via the driver or 'SELECT ... FROM syscat.tables'","Update the connector/dialect version if the column types are new and being filtered as unsupported","Enable driver-level metadata logging to inspect which rows and types were filtered"],"exampleFix":"// before\ntable_path = \"mydb.public.orders\"\n// after (exact case as stored by the database, e.g. DB2 uppercase)\ntable_path = \"MYDB.PUBLIC.ORDERS\"","handlingStrategy":"validation","validationCode":"// before getTableSchema, verify identifier case against the database\ntry (Connection c = dataSource.getConnection()) {\n    ResultSet rs = c.getMetaData().getTables(catalog, schemaPattern, tableNamePattern, null);\n    if (!rs.next()) {\n        throw new IllegalStateException(\"Table not found; check exact case of \" + catalog + \".\" + schemaPattern + \".\" + tableNamePattern);\n    }\n}","typeGuard":"boolean hasUsableColumns(TableSchema s) {\n    return s != null && s.getColumns() != null && !s.getColumns().isEmpty();\n}","tryCatchPattern":"try {\n    TableSchema schema = catalog.getTableSchema(tablePath);\n    if (schema.getColumns().isEmpty()) {\n        throw new IllegalStateException(\"Empty schema for \" + tablePath + \"; check identifier case\");\n    }\n} catch (RuntimeException e) {\n    // fall back to explicit case-quoted identifiers and retry once\n}","preventionTips":["Always match the database's stored identifier case (DB2/Oracle: usually uppercase)","Quote identifiers in the table path when the DB supports mixed case","Confirm the table exists in the expected schema before starting the job","Keep connector versions current so new column types aren't filtered as unknown"],"tags":["jdbc","metadata","case-sensitivity","empty-schema"],"backgroundTag":"empty-result-set","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}