prestodb/presto · error · SemanticException

SAMPLE_PERCENTAGE_OUT_OF_RANGE

SAMPLE_PERCENTAGE_OUT_OF_RANGE

Error message

Sample percentage must be greater than or equal to 0

What it means

Once the sample percentage evaluates to a double, Presto validates its range: values below 0 are rejected with SAMPLE_PERCENTAGE_OUT_OF_RANGE because a negative sample fraction is meaningless. Valid percentages are 0 through 100 inclusive.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/sql/analyzer/StatementAnalyzer.java:3203

            Object samplePercentageObject = samplePercentageEval.optimize(symbol -> {
                throw new SemanticException(NON_NUMERIC_SAMPLE_PERCENTAGE, relation.getSamplePercentage(), "Sample percentage cannot contain column references");
            });
            try {
                samplePercentageObject = evaluateConstantExpression(relation.getSamplePercentage(), DOUBLE, metadata, session,
                        analysis.getParameters());
            }
            catch (SemanticException e) {
                if (e.getCode() == TYPE_MISMATCH) {
                    throw new SemanticException(NON_NUMERIC_SAMPLE_PERCENTAGE, relation.getSamplePercentage(), "Sample percentage should evaluate to a double");
                }
                throw e;
            }

            double samplePercentageValue = (Double) samplePercentageObject;

            if (samplePercentageValue < 0.0) {
                throw new SemanticException(SemanticErrorCode.SAMPLE_PERCENTAGE_OUT_OF_RANGE, relation.getSamplePercentage(), "Sample percentage must be greater than or equal to 0");
            }
            if ((samplePercentageValue > 100.0)) {
                throw new SemanticException(SemanticErrorCode.SAMPLE_PERCENTAGE_OUT_OF_RANGE, relation.getSamplePercentage(), "Sample percentage must be less than or equal to 100");
            }

            analysis.setSampleRatio(relation, samplePercentageValue / 100);
            Scope relationScope = process(relation.getRelation(), scope);

            // TABLESAMPLE cannot be applied to a polymorphic table function (SQL standard ISO/IEC 9075-2, 7.6 <table reference>, p. 409)
            // Note: the below method finds a table function immediately nested in SampledRelation, or aliased.
            // Potentially, a table function could be also nested with intervening PatternRecognitionRelation.
            // Such case is handled in visitPatternRecognitionRelation().
            validateNoNestedTableFunction(relation.getRelation(), "sample");

            return createAndAssignScope(relation, scope, relationScope.getRelationType());
        }

        // this method should run after the `base` relation is processed, so that it is

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Clamp the percentage to [0, 100] before generating the query
  2. Validate the sampling configuration value before substitution
  3. Use 0 to express 'no rows' rather than a negative value

Example fix

// before
double pct = config.getSamplePct(); // could be -5
// after
double pct = Math.max(0.0, Math.min(100.0, config.getSamplePct()));
Defensive patterns

Strategy: validation

Validate before calling

double pct = resolveSamplePercentage(config);
if (pct < 0.0) {
    throw new IllegalArgumentException("sample percentage must be >= 0, got " + pct);
}

Type guard

boolean isValidSamplePct(double pct) { return pct >= 0.0 && pct <= 100.0; }

Try / catch

try {
    return engine.execute(sql);
} catch (SemanticException e) {
    if (e.getCode() == SemanticErrorCode.SAMPLE_PERCENTAGE_OUT_OF_RANGE) {
        sql = clampSamplePct(sql, 0.0, 100.0); // clamp and retry once
    } else { throw e; }
}

Prevention

When it happens

Trigger: SELECT * FROM t TABLESAMPLE BERNOULLI (-5); a computed constant expression folding to a negative number; a query template where a variable is substituted with a negative value.

Common situations: Off-by-sign bugs in generated SQL; parameterized sampling where a caller passes negative rates; misconfigured sampling jobs writing bad percentages into query templates.

Related errors


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