{"record":{"id":"ca2d95b0653fdc99","repo":"prestodb/presto","slug":"not-supported-ca2d95","errorCode":"NOT_SUPPORTED","errorMessage":"Multiple tables matched: ${schemaTableName}","messagePattern":"Multiple tables matched: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"presto-base-jdbc/src/main/java/com/facebook/presto/plugin/jdbc/BaseJdbcClient.java","lineNumber":229,"sourceCode":"    {\n        try (Connection connection = connectionFactory.openConnection(identity)) {\n            String remoteSchema = toRemoteSchemaName(session, identity, connection, schemaTableName.getSchemaName());\n            String remoteTable = toRemoteTableName(session, identity, connection, remoteSchema, schemaTableName.getTableName());\n            try (ResultSet resultSet = getTables(connection, Optional.of(remoteSchema), Optional.of(remoteTable))) {\n                List<JdbcTableHandle> tableHandles = new ArrayList<>();\n                while (resultSet.next()) {\n                    tableHandles.add(new JdbcTableHandle(\n                            connectorId,\n                            schemaTableName,\n                            resultSet.getString(\"TABLE_CAT\"),\n                            resultSet.getString(\"TABLE_SCHEM\"),\n                            resultSet.getString(\"TABLE_NAME\")));\n                }\n                if (tableHandles.isEmpty()) {\n                    return null;\n                }\n                if (tableHandles.size() > 1) {\n                    throw new PrestoException(NOT_SUPPORTED, \"Multiple tables matched: \" + schemaTableName);\n                }\n                return getOnlyElement(tableHandles);\n            }\n        }\n        catch (SQLException e) {\n            throw new PrestoException(JDBC_ERROR, e);\n        }\n    }\n\n    @Override\n    public List<JdbcColumnHandle> getColumns(ConnectorSession session, JdbcTableHandle tableHandle)\n    {\n        try (Connection connection = connectionFactory.openConnection(JdbcIdentity.from(session))) {\n            try (ResultSet resultSet = getColumns(tableHandle, connection.getMetaData())) {\n                int allColumns = 0;\n                List<JdbcColumnHandle> columns = new ArrayList<>();\n                while (resultSet.next()) {\n                    allColumns++;","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-base-jdbc/src/main/java/com/facebook/presto/plugin/jdbc/BaseJdbcClient.java#L211-L247","documentation":"BaseJdbcClient.getTableHandle resolves a Presto schema/table name to a remote JDBC table by querying DatabaseMetaData.getTables with the normalized remote schema and table name. The JDBC lookup is expected to return at most one row; if more than one table matches (e.g. case-insensitive matching collides with two distinct remote tables, or views and tables share the name), it throws PrestoException(NOT_SUPPORTED, 'Multiple tables matched: <schemaTableName>') because the connector cannot disambiguate.","triggerScenarios":"Calling getTableHandle when getTables(...) returns multiple rows for the same schema+table pattern — typically duplicate identifiers differing only in case on a case-insensitive database (Oracle/MySQL lower_case_table_names), or a table and synonym/view with the same resolved name.","commonSituations":"Remote database contains TABLE and Table in the same schema; identifier case-folding by the connector makes two distinct remote names normalize identically; DBA created a synonym with the same name as a table; after a DB migration that changed case sensitivity settings.","solutions":["Rename or drop the duplicate/synonym on the remote database so exactly one object matches the name.","Quote the identifier with the exact remote casing in the query so the connector resolves it unambiguously.","Check DB case-sensitivity settings (e.g. MySQL lower_case_table_names, Oracle case handling) that make two names collide.","Inspect which rows matched by running the same getTables lookup via the JDBC driver to identify the duplicates.","Upgrade the specific JdbcClient implementation if it has improved identifier normalization."],"exampleFix":"-- before: matches both EMPLOYEES and employees on Oracle\nSELECT * FROM jdbc.oracle.employees;\n-- after: quote to match exactly one\nSELECT * FROM jdbc.oracle.\"EMPLOYEES\";","handlingStrategy":"try-catch","validationCode":"-- Check for duplicate matching objects on the remote DB before resolving the handle\nSELECT table_name FROM information_schema.tables\nWHERE lower(table_name) = lower('employees') AND table_schema = 'myschema';\n-- more than one row means getTableHandle will throw NOT_SUPPORTED","typeGuard":null,"tryCatchPattern":"try {\n    JdbcTableHandle h = client.getTableHandle(session, identity, schemaTableName);\n} catch (PrestoException e) {\n    if (e.getErrorCode().getCode() == NOT_SUPPORTED.getCode()\n            && e.getMessage().startsWith(\"Multiple tables matched:\")) {\n        // list matches via JDBC metadata, disambiguate or fix remote duplicates, retry\n    }\n    throw e;\n}","preventionTips":["Enforce unique case-insensitive table names (no synonyms/views colliding with tables).","Use quoted exact-case identifiers when querying case-folding databases.","Audit remote schemas for duplicate names after migrations.","Align DB case-sensitivity settings (e.g. lower_case_table_names) across environments."],"tags":["presto","jdbc","identifier","case-sensitivity","not-supported"],"backgroundTag":"ambiguous-table-identifier","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}