prestodb/presto · error · IllegalArgumentException

distinctValuesCount must be greater than or equal to 0: %s

Error message

distinctValuesCount must be greater than or equal to 0: %s

What it means

Constructor invariant check in ColumnStatistics: the provided distinctValuesCount Estimate is known but negative, which is impossible for a cardinality statistic. This IllegalArgumentException enforces valid optimizer statistics produced by connectors.

Source

Thrown at presto-spi/src/main/java/com/facebook/presto/spi/statistics/ColumnStatistics.java:78

    }

    public ColumnStatistics(
            Estimate nullsFraction,
            Estimate distinctValuesCount,
            Estimate dataSize,
            Optional<DoubleRange> range,
            Optional<StringRange> stringRange,
            Optional<ConnectorHistogram> histogram)
    {
        this.nullsFraction = requireNonNull(nullsFraction, "nullsFraction is null");
        if (!nullsFraction.isUnknown()) {
            if (nullsFraction.getValue() < 0 || nullsFraction.getValue() > 1) {
                throw new IllegalArgumentException(format("nullsFraction must be between 0 and 1: %s", nullsFraction.getValue()));
            }
        }
        this.distinctValuesCount = requireNonNull(distinctValuesCount, "distinctValuesCount is null");
        if (!distinctValuesCount.isUnknown() && distinctValuesCount.getValue() < 0) {
            throw new IllegalArgumentException(format("distinctValuesCount must be greater than or equal to 0: %s", distinctValuesCount.getValue()));
        }
        this.dataSize = requireNonNull(dataSize, "dataSize is null");
        if (!dataSize.isUnknown() && dataSize.getValue() < 0) {
            throw new IllegalArgumentException(format("dataSize must be greater than or equal to 0: %s", dataSize.getValue()));
        }
        this.range = requireNonNull(range, "range is null");
        this.stringRange = requireNonNull(stringRange, "string range is null");
        this.histogram = requireNonNull(histogram, "histogram is null");
    }

    @JsonProperty
    public Estimate getNullsFraction()
    {
        return nullsFraction;
    }

    @JsonProperty
    public Estimate getDistinctValuesCount()

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Fix the connector's statistics computation so distinct values counts are never negative
  2. Clamp or mark the estimate as unknown when a valid value cannot be computed

Example fix

// before
Estimate.of(rowCount - nullCount)
// after
Estimate.of(Math.max(0, rowCount - nullCount))
Defensive patterns

Strategy: validation

Validate before calling

if (ndv != null && !ndv.isUnknown() && ndv.getValue() < 0) { throw new IllegalArgumentException("distinctValuesCount negative: " + ndv.getValue()); }

Prevention

When it happens

Trigger: Constructing ColumnStatistics with a distinctValuesCount Estimate whose value is negative, often from a subtraction like (rowCount - nullCount) that went below zero.

Common situations: Connectors computing NDV estimates via subtraction under rounding, or misparsed external stats (e.g. negative NDV from Hive metastore).

Related errors


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