prestodb/presto · error · SemanticException

MISSING_TABLE

MISSING_TABLE

Error message

Table '%s' does not exist

What it means

ALTER TABLE ... ALTER COLUMN <type> (SetColumnType) resolves the target table to a TableHandle before any type change. If the name does not resolve to an existing table and the statement lacks IF EXISTS semantics, it fails with MISSING_TABLE.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/execution/SetColumnTypeTask.java:69

    @Inject
    public SetColumnTypeTask(Metadata metadata)
    {
        this.metadata = requireNonNull(metadata, "metadata is null");
    }

    @Override
    public String getName()
    {
        return "SET COLUMN TYPE";
    }

    public ListenableFuture<Void> execute(SetColumnType statement, TransactionManager transactionManager, Metadata metadata, AccessControl accessControl, Session session, List<Expression> parameters, WarningCollector warningCollector, String query)
    {
        QualifiedObjectName tableName = createQualifiedObjectName(session, statement, statement.getTableName(), metadata);
        Optional<TableHandle> tableHandle = metadata.getMetadataResolver(session).getTableHandle(tableName);
        if (!tableHandle.isPresent()) {
            if (!statement.isTableExists()) {
                throw new SemanticException(MISSING_TABLE, statement, "Table '%s' does not exist", tableName);
            }
            return immediateFuture(null);
        }

        Optional<MaterializedViewDefinition> optionalMaterializedView = metadata.getMetadataResolver(session).getMaterializedView(tableName);
        if (optionalMaterializedView.isPresent()) {
            if (!statement.isTableExists()) {
                throw new SemanticException(SemanticErrorCode.NOT_SUPPORTED, statement, "'%s' is a materialized view, and alter column is not supported", tableName);
            }
            return immediateFuture(null);
        }

        accessControl.checkCanAlterColumn(session.getRequiredTransactionId(), session.getIdentity(), session.getAccessControlContext(), tableName);

        TableHandle tableHandleOptional = tableHandle.get();
        Map<String, ColumnHandle> columnHandles = metadata.getColumnHandles(session, tableHandleOptional);
        ColumnHandle column = columnHandles.get(statement.getColumnName().getValue());
        if (column == null) {

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Verify the fully qualified table name exists before running the ALTER
  2. Correct the catalog/schema/table spelling in the statement
  3. Use IF EXISTS semantics if a silent skip is intended

Example fix

// before
ALTER TABLE hive.default.ordrs ALTER COLUMN id SET DATA TYPE BIGINT;
// after
ALTER TABLE hive.default.orders ALTER COLUMN id SET DATA TYPE BIGINT;
Defensive patterns

Strategy: validation

Validate before calling

QualifiedObjectName name = createQualifiedObjectName(session, stmt, table, metadata);
if (metadata.getMetadataResolver(session).getTableHandle(name).isEmpty()) {
    throw new IllegalArgumentException("Table not found: " + name);
}

Try / catch

try {
    return task.execute(stmt, ...);
} catch (SemanticException e) {
    if (e.getCode() == SemanticErrorCode.MISSING_TABLE) {
        // skip or report missing table
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: ALTER TABLE <qualified name> ALTER COLUMN ... (type change) where getTableHandle returns empty and statement.isTableExists() is false.

Common situations: Typo in table or catalog name; table dropped by a concurrent job; session pointed at the wrong catalog; scripts written for a different environment's schema.

Related errors


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