prestodb/presto · error · SemanticException

MISSING_COLUMN

MISSING_COLUMN

Error message

Column '%s' does not exist

What it means

After access-control checks, DropColumnTask looks up the column in metadata.getColumnHandles(session, tableHandle). A null/absent handle means the column does not exist on the table; without IF COLUMN EXISTS (isColumnExists), it throws SemanticException(MISSING_COLUMN) naming the column.

Source

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

        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);
        }

        if (metadata.getColumnMetadata(session, tableHandle, columnHandle).isHidden()) {
            throw new SemanticException(NOT_SUPPORTED, statement, "Cannot drop hidden column");
        }

        if (metadata.getTableMetadata(session, tableHandle).getColumns().stream()
                .filter(info -> !info.isHidden()).count() <= 1) {
            throw new SemanticException(NOT_SUPPORTED, statement, "Cannot drop the only column in a table");
        }

        metadata.dropColumn(session, tableHandle, columnHandle);

        return immediateFuture(null);
    }
}

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Check the exact column name with SHOW COLUMNS FROM <table> and correct casing/spelling (quote the identifier if needed).
  2. Add IF EXISTS for the column to make repeated migrations idempotent.
  3. If the column was already dropped, skip the statement in your migration logic.

Example fix

// before
ALTER TABLE hive.default.events DROP COLUMN TempFlag; -- actual name: tempflag
// after
ALTER TABLE hive.default.events DROP COLUMN IF EXISTS tempflag;
Defensive patterns

Strategy: validation

Validate before calling

-- Verify the column exists before DROP COLUMN
SELECT column_name FROM information_schema.columns
WHERE table_catalog='hive' AND table_schema='default'
  AND table_name='events' AND lower(column_name) = 'tempflag';

Type guard

function columnExists(session, qname, col) {
  return session.execute(
    'SELECT count(*) FROM information_schema.columns WHERE table_catalog=? AND table_schema=? AND table_name=? AND lower(column_name)=lower(?)',
    [qname.catalog, qname.schema, qname.table, col]) > 0;
}

Try / catch

try {
  session.execute(`ALTER TABLE ${t} DROP COLUMN IF EXISTS ${c}`);
} catch (e) {
  if (/Column '.*' does not exist/.test(e.message)) {
    log.info(`Column ${c} already absent; continuing migration`);
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: ALTER TABLE <table> DROP COLUMN <col> where <col> is not among the table's column handles and the statement did not use IF EXISTS for the column.

Common situations: Column already dropped in a prior run of a migration script; case-sensitivity mismatch (quoted vs unquoted identifiers); column renamed upstream; dropping a column that only exists in a view definition, not the table.

Related errors


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