prestodb/presto · error · SemanticException
NON_NUMERIC_SAMPLE_PERCENTAGE
NON_NUMERIC_SAMPLE_PERCENTAGE
Error message
Sample percentage cannot contain column references
What it means
TABLESAMPLE's sample percentage must be a constant expression; Presto extracts column references from the sample percentage expression and throws NON_NUMERIC_SAMPLE_PERCENTAGE if any are found. Allowing column references would make the sample ratio row-dependent, which the sampling implementation does not support.
Source
Thrown at presto-main-base/src/main/java/com/facebook/presto/sql/analyzer/StatementAnalyzer.java:3172
.map(Field::getName)
.filter(Optional::isPresent)
.map(Optional::get)
// field names are resolved case-insensitive
.map(name -> name.toLowerCase(ENGLISH))
.forEach(name -> {
if (!names.add(name)) {
throw new SemanticException(DUPLICATE_COLUMN_NAME, relation.getRelation(), "Duplicate name of table function proper column: " + name);
}
});
return new RelationType(fields);
}
@Override
protected Scope visitSampledRelation(SampledRelation relation, Optional<Scope> scope)
{
if (!VariablesExtractor.extractNames(relation.getSamplePercentage(), analysis.getColumnReferences()).isEmpty()) {
throw new SemanticException(NON_NUMERIC_SAMPLE_PERCENTAGE, relation.getSamplePercentage(), "Sample percentage cannot contain column references");
}
Map<NodeRef<Expression>, Type> expressionTypes = getExpressionTypes(
session,
metadata,
sqlParser,
TypeProvider.empty(),
relation.getSamplePercentage(),
analysis.getParameters(),
warningCollector,
analysis.isDescribe());
ExpressionInterpreter samplePercentageEval = expressionOptimizer(relation.getSamplePercentage(), metadata, session, expressionTypes);
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,View on GitHub (pinned to 55bb57d202)
Solutions
- Use a literal numeric percentage, e.g. TABLESAMPLE BERNOULLI (10)
- Inline the desired value as a constant before running the query
- Use a session-level parameter substituted at query construction time
- If row-dependent sampling is needed, implement it with rand() <= ratio in a WHERE clause instead
Example fix
-- before SELECT * FROM t TABLESAMPLE BERNOULLI (pct) -- after SELECT * FROM t TABLESAMPLE BERNOULLI (10)
Defensive patterns
Strategy: validation
Validate before calling
// sample percentage must be column-free before sending SQL
Set<NodeRef<Expression>> cols = VariablesExtractor.extractNames(samplePctExpr, analysisRefs);
if (!cols.isEmpty()) throw new IllegalArgumentException("sample percentage must be constant"); Type guard
boolean isLiteralPercentage(Expression e) {
return e instanceof DoubleLiteral || e instanceof LongLiteral || e instanceof DecimalLiteral;
} Try / catch
try {
return engine.execute(sql);
} catch (SemanticException e) {
if (e.getCode() == SemanticErrorCode.NON_NUMERIC_SAMPLE_PERCENTAGE) {
sql = replaceSamplePctWithLiteral(sql, fixedPct); // retry with constant
} else { throw e; }
} Prevention
- Always use numeric literals for TABLESAMPLE percentages
- Do not reference columns (even from other tables) in the sample percentage
- For per-row sampling, use WHERE rand() <= ratio instead of TABLESAMPLE
- Validate generated SQL templates to ensure sample rate substitution is constant
When it happens
Trigger: SELECT * FROM t TABLESAMPLE BERNOULLI (pct) where pct is a column of t; referencing any column (even from another table) inside the sample percentage expression.
Common situations: Trying to parameterize sample rate per row; storing sample sizes in a config table and referencing it in the query; misunderstanding that the percentage must be a literal/constant.
Related errors
- SAMPLE_PERCENTAGE_OUT_OF_RANGE
- INVALID_TABLE_PROPERTY
- Invalid time from server:
- Expected column to be a time type but is
- Invalid timestamp from server:
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/a75dae9e51e01d91.
Report an issue: GitHub.