prestodb/presto · error · NotSupportedException

map key cannot be null or contain nulls

Error message

map key cannot be null or contain nulls

What it means

SingleMapBlock's key lookup (seekKey/seekKeyExact) relies on Boolean equality results for keys. checkNotIndeterminate throws NotSupportedException when the equals comparison returns null, which happens when the key is NULL or contains nulls — map keys in Presto must be determinate (non-null). Equality with indeterminate keys cannot produce a valid true/false answer, so lookup fails fast.

Source

Thrown at presto-common/src/main/java/com/facebook/presto/common/block/SingleMapBlock.java:458

            position++;
            if (position == hashTableSize) {
                position = 0;
            }
        }
    }

    private static RuntimeException handleThrowable(Throwable throwable)
    {
        if (throwable instanceof Error) {
            throw (Error) throwable;
        }
        throw new GenericInternalException(throwable);
    }

    private static void checkNotIndeterminate(Boolean equalsResult)
    {
        if (equalsResult == null) {
            throw new NotSupportedException("map key cannot be null or contain nulls");
        }
    }

    @Override
    public boolean equals(Object obj)
    {
        if (this == obj) {
            return true;
        }
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }
        SingleMapBlock other = (SingleMapBlock) obj;
        return this.positionInMap == other.positionInMap &&
                this.offset == other.offset &&
                this.positionCount == other.positionCount &&
                Objects.equals(this.mapBlock, other.mapBlock);
    }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Filter out NULL keys before lookup: add IS NOT NULL predicate on the key expression.
  2. Use COALESCE to substitute a sentinel non-null value for keys used in lookups.
  3. Avoid indeterminate types (types containing nulls) as map keys; use COALESCE on inner fields of composite keys.
  4. Return NULL from the surrounding operator when the key is indeterminate instead of performing seekKey.

Example fix

// before
// seekKey(keyBlock) where key may be NULL
boolean found = singleMapBlock.seekKeyExact(keyBlock, keyPosition);
// after
if (keyBlock.isNull(keyPosition)) {
    return null; // indeterminate key: no match possible
}
boolean found = singleMapBlock.seekKeyExact(keyBlock, keyPosition);
Defensive patterns

Strategy: validation

Validate before calling

boolean isIndeterminateKey(Block keyBlock, int position) {
    return keyBlock.isNull(position) || containsNull(keyBlock, position);
}
// guard:
if (keyBlock.isNull(keyPosition)) { return null; } // skip lookup

Type guard

boolean isDeterminanteKey(Block keyBlock, int position) {
    return !keyBlock.isNull(position);
}

Try / catch

try {
    return singleMapBlock.seekKeyExact(keyBlock, keyPosition);
} catch (NotSupportedException e) {
    if (e.getMessage().contains("map key cannot be null or contain nulls")) {
        return null; // indeterminate key never matches
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling seekKey or seekKeyExact with a key that is null, or whose type contains null subfields (e.g. a row/array key with null elements), causing the block's equals comparison to return Boolean null.

Common situations: Querying a map column with a NULL key constant, JOIN/filter predicates comparing map keys against nullable expressions, using MAP with ROW keys that have null fields.

Related errors


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