prestodb/presto · error · IllegalArgumentException

nullsFraction must be between 0 and 1: %s

Error message

nullsFraction must be between 0 and 1: %s

What it means

ColumnStatistics enforces that the nulls fraction is a probability in [0,1] when the estimate is not UNKNOWN. Values outside that range are statistically impossible and indicate a buggy statistics producer.

Source

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

            Estimate dataSize,
            Optional<DoubleRange> range,
            Optional<ConnectorHistogram> histogram)
    {
        this(nullsFraction, distinctValuesCount, dataSize, range, Optional.empty(), histogram);
    }

    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()
    {

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Convert percentage values to fractions (divide by 100) before building ColumnStatistics
  2. Clamp the computed value into [0,1]
  3. Use Estimate.unknown() when the fraction cannot be computed
  4. Fix division-by-zero in the fraction calculation

Example fix

// before
Estimate.nullsFraction(45.0) // percent
// after
Estimate.nullsFraction(0.45)
Defensive patterns

Strategy: validation

Validate before calling

if (fraction != null && !fraction.isUnknown() && (fraction.getValue() < 0 || fraction.getValue() > 1)) { throw new IllegalArgumentException("nullsFraction out of [0,1]: " + fraction.getValue()); }

Prevention

When it happens

Trigger: Calling ColumnStatistics constructor (or a builder producing it) with an Estimate whose value is < 0 or > 1, e.g. nullsFraction from a fraction computed as count/totalCount when totalCount is 0.

Common situations: Connector statistics code dividing by zero counts, computing percentages (0-100) instead of fractions (0-1), or scaling errors in histogram derivation.

Related errors


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