prestodb/presto · error

NOT_SUPPORTED

NOT_SUPPORTED

Error message

Multiple tables matched: ${schemaTableName}

What it means

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.

Source

Thrown at presto-base-jdbc/src/main/java/com/facebook/presto/plugin/jdbc/BaseJdbcClient.java:229

    {
        try (Connection connection = connectionFactory.openConnection(identity)) {
            String remoteSchema = toRemoteSchemaName(session, identity, connection, schemaTableName.getSchemaName());
            String remoteTable = toRemoteTableName(session, identity, connection, remoteSchema, schemaTableName.getTableName());
            try (ResultSet resultSet = getTables(connection, Optional.of(remoteSchema), Optional.of(remoteTable))) {
                List<JdbcTableHandle> tableHandles = new ArrayList<>();
                while (resultSet.next()) {
                    tableHandles.add(new JdbcTableHandle(
                            connectorId,
                            schemaTableName,
                            resultSet.getString("TABLE_CAT"),
                            resultSet.getString("TABLE_SCHEM"),
                            resultSet.getString("TABLE_NAME")));
                }
                if (tableHandles.isEmpty()) {
                    return null;
                }
                if (tableHandles.size() > 1) {
                    throw new PrestoException(NOT_SUPPORTED, "Multiple tables matched: " + schemaTableName);
                }
                return getOnlyElement(tableHandles);
            }
        }
        catch (SQLException e) {
            throw new PrestoException(JDBC_ERROR, e);
        }
    }

    @Override
    public List<JdbcColumnHandle> getColumns(ConnectorSession session, JdbcTableHandle tableHandle)
    {
        try (Connection connection = connectionFactory.openConnection(JdbcIdentity.from(session))) {
            try (ResultSet resultSet = getColumns(tableHandle, connection.getMetaData())) {
                int allColumns = 0;
                List<JdbcColumnHandle> columns = new ArrayList<>();
                while (resultSet.next()) {
                    allColumns++;

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Rename or drop the duplicate/synonym on the remote database so exactly one object matches the name.
  2. Quote the identifier with the exact remote casing in the query so the connector resolves it unambiguously.
  3. Check DB case-sensitivity settings (e.g. MySQL lower_case_table_names, Oracle case handling) that make two names collide.
  4. Inspect which rows matched by running the same getTables lookup via the JDBC driver to identify the duplicates.
  5. Upgrade the specific JdbcClient implementation if it has improved identifier normalization.

Example fix

-- before: matches both EMPLOYEES and employees on Oracle
SELECT * FROM jdbc.oracle.employees;
-- after: quote to match exactly one
SELECT * FROM jdbc.oracle."EMPLOYEES";
Defensive patterns

Strategy: try-catch

Validate before calling

-- Check for duplicate matching objects on the remote DB before resolving the handle
SELECT table_name FROM information_schema.tables
WHERE lower(table_name) = lower('employees') AND table_schema = 'myschema';
-- more than one row means getTableHandle will throw NOT_SUPPORTED

Try / catch

try {
    JdbcTableHandle h = client.getTableHandle(session, identity, schemaTableName);
} catch (PrestoException e) {
    if (e.getErrorCode().getCode() == NOT_SUPPORTED.getCode()
            && e.getMessage().startsWith("Multiple tables matched:")) {
        // list matches via JDBC metadata, disambiguate or fix remote duplicates, retry
    }
    throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Presto NOT_SUPPORTED error: what "not supported" means and how to fix it — this error's family across 3 libraries.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/ca2d95b0653fdc99. Report an issue: GitHub.