prestodb/presto · error · SemanticException

NOT_SUPPORTED

NOT_SUPPORTED

Error message

'%s' is a materialized view, and drop column is not supported

What it means

DropColumnTask.execute detects that the resolved object is a materialized view and refuses to drop columns from it, throwing SemanticException(NOT_SUPPORTED). Materialized views are derived definitions, so their columns cannot be altered with DROP COLUMN. Note the guard honors statement.isTableExists() (IF EXISTS), returning silently in that case.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/execution/DropColumnTask.java:65

    }

    @Override
    public ListenableFuture<?> execute(DropColumn statement, TransactionManager transactionManager, Metadata metadata, AccessControl accessControl, Session session, List<Expression> parameters, WarningCollector warningCollector, String query)
    {
        QualifiedObjectName tableName = createQualifiedObjectName(session, statement, statement.getTable(), metadata);
        Optional<TableHandle> tableHandleOptional = metadata.getMetadataResolver(session).getTableHandle(tableName);

        if (!tableHandleOptional.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(NOT_SUPPORTED, statement, "'%s' is a materialized view, and drop column is not supported", tableName);
            }
            return immediateFuture(null);
        }

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

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

        ColumnHandle columnHandle = metadata.getColumnHandles(session, tableHandle).get(column);
        if (columnHandle == null) {
            if (!statement.isColumnExists()) {
                throw new SemanticException(MISSING_COLUMN, statement, "Column '%s' does not exist", column);
            }
            return immediateFuture(null);
        }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Alter the columns of the base table the materialized view selects from, then refresh/recreate the view.
  2. Drop and recreate the materialized view with the desired column set.
  3. Verify the object type before altering (system.metadata.materialized_views or SHOW CREATE).

Example fix

// before
ALTER TABLE hive.default.sales_mv DROP COLUMN legacy_col; -- is a materialized view
// after
ALTER TABLE hive.default.sales DROP COLUMN legacy_col;
-- then recreate/refresh the materialized view
Defensive patterns

Strategy: validation

Validate before calling

-- Detect materialized views before ALTER TABLE ... DROP COLUMN
SELECT name FROM system.metadata.materialized_views
WHERE catalog = 'hive' AND schema = 'default' AND name = 'sales_mv';

Type guard

function isTable(session, qname) {
  const isMv = session.execute(
    'SELECT count(*) FROM system.metadata.materialized_views WHERE catalog=? AND schema=? AND name=?',
    [qname.catalog, qname.schema, qname.table]);
  const isTbl = session.execute(
    'SELECT count(*) FROM information_schema.tables WHERE table_catalog=? AND table_schema=? AND table_name=? AND table_type=\'BASE TABLE\'',
    [qname.catalog, qname.schema, qname.table]);
  return !isMv && isTbl;
}

Try / catch

try {
  session.execute(alterSql);
} catch (e) {
  if (/is a materialized view, and drop column is not supported/.test(e.message)) {
    // recreate the materialized view with the desired columns instead
  }
  throw e;
}

Prevention

When it happens

Trigger: ALTER TABLE <mv_name> DROP COLUMN <col> where getMaterializedView(tableName) is present.

Common situations: Name shadowing between a table and a materialized view; scripts generated for tables reused against materialized views; assuming materialized views are mutable like tables in Iceberg/Delta connectors.

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/9e74a0a05cf7e49c. Report an issue: GitHub.