prestodb/presto · error · SemanticException

MISSING_COLUMN

MISSING_COLUMN

Error message

Column '%s' does not exist

What it means

Before applying a column default, Presto resolves the (normalized) column name to a ColumnHandle via metadata.getColumnHandles. A missing handle means the column is not part of the table, so the ALTER fails with MISSING_COLUMN. Names are normalized per the connector's identifier rules before the lookup.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/execution/SetColumnDefaultTask.java:81

        }

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

        TableHandle tableHandle = tableHandleOptional.get();
        String columnName = metadata.normalizeIdentifier(session, tableName.getCatalogName(), statement.getColumn().getValue());

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

        Map<String, ColumnHandle> columnHandles = metadata.getColumnHandles(session, tableHandle);
        ColumnHandle columnHandle = columnHandles.get(columnName);
        if (columnHandle == null) {
            throw new SemanticException(MISSING_COLUMN, statement, "Column '%s' does not exist", columnName);
        }

        ColumnMetadata columnMetadata = metadata.getColumnMetadata(session, tableHandle, columnHandle);
        if (columnMetadata.isHidden()) {
            throw new SemanticException(NOT_SUPPORTED, statement, "Cannot set default on hidden column");
        }

        // Evaluate the default expression
        Type columnType = columnMetadata.getType();
        Expression defaultExpr = statement.getDefaultExpression();
        Object defaultValue = ExpressionInterpreter.evaluateConstantExpression(defaultExpr, columnType, metadata, session, ImmutableMap.of());

        // Call the metadata method to set the write-default
        metadata.setColumnDefault(session, tableHandle, columnName, defaultValue);

        return immediateFuture(null);
    }
}

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Check the table's column names (DESCRIBE / SHOW COLUMNS) and fix the column name
  2. Quote the identifier if case matters for the connector
  3. Re-add the column if it was dropped

Example fix

// before
ALTER TABLE hive.default.orders ALTER COLUMN ammount SET DEFAULT 0;
// after
ALTER TABLE hive.default.orders ALTER COLUMN amount SET DEFAULT 0;
Defensive patterns

Strategy: validation

Validate before calling

String columnName = metadata.normalizeIdentifier(session, catalog, column.getValue());
Map<String, ColumnHandle> handles = metadata.getColumnHandles(session, tableHandle);
if (!handles.containsKey(columnName)) {
    throw new IllegalArgumentException("Column not found on " + tableName + ": " + columnName);
}

Try / catch

try {
    return task.execute(stmt, ...);
} catch (SemanticException e) {
    if (e.getCode() == SemanticErrorCode.MISSING_COLUMN) {
        // surface a friendly 'column not found' message
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: ALTER TABLE ... ALTER COLUMN <name> SET DEFAULT where columnName is absent from the table's column handle map — misspelled column, wrong case beyond normalization, or the column was dropped.

Common situations: Case-sensitivity mismatches with quoted identifiers; column renamed by a migration; running the ALTER against an older schema version of the table.

Related errors


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