prestodb/presto · error · PrestoException

DRUID_QUERY_GENERATOR_FAILURE

DRUID_QUERY_GENERATOR_FAILURE

Error message

Invalid limit: 

What it means

withLimit validates the LIMIT value before embedding it in the generated Druid query. A non-positive value or one exceeding Long.MAX_VALUE is rejected with DRUID_QUERY_GENERATOR_FAILURE, since Druid queries require a valid positive limit.

Source

Thrown at presto-druid/src/main/java/com/facebook/presto/druid/DruidQueryGeneratorContext.java:147

    public DruidQueryGeneratorContext withProject(Map<VariableReferenceExpression, Selection> newSelections)
    {
        return new DruidQueryGeneratorContext(
                newSelections,
                from,
                filter,
                limit,
                aggregations,
                groupByColumns,
                variablesInAggregation,
                hiddenColumnSet,
                tableScanNodeId);
    }

    public DruidQueryGeneratorContext withLimit(long limit)
    {
        if (limit <= 0 || limit > Long.MAX_VALUE) {
            throw new PrestoException(DRUID_QUERY_GENERATOR_FAILURE, "Invalid limit: " + limit);
        }
        checkState(!hasLimit(), "Limit already exists. Druid doesn't support limit on top of another limit");
        return new DruidQueryGeneratorContext(
                selections,
                from,
                filter,
                OptionalLong.of(limit),
                aggregations,
                groupByColumns,
                variablesInAggregation,
                hiddenColumnSet,
                tableScanNodeId);
    }

    public DruidQueryGeneratorContext withAggregation(
            Map<VariableReferenceExpression, Selection> newSelections,
            Map<VariableReferenceExpression, Selection> newGroupByColumns,
            int newAggregations,

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Remove LIMIT 0 from the query or let the optimizer replace it with an empty relation before pushdown
  2. Use a positive LIMIT value in the query
  3. Guard at the connector level: convert limit <= 0 to a zero-row plan instead of throwing in the generator
  4. Upgrade Presto so the optimizer eliminates 0-limit nodes before Druid plan matching

Example fix

// before
SELECT k FROM druid_table LIMIT 0; -- throws Invalid limit: 0
// after
SELECT k FROM druid_table LIMIT 1; -- or issue a metadata-only probe
Defensive patterns

Strategy: validation

Validate before calling

void validateLimit(long limit) {
    if (limit <= 0 || limit > Long.MAX_VALUE) {
        throw new IllegalArgumentException("LIMIT must be positive, got: " + limit);
    }
}

Type guard

boolean isValidLimit(Long limit) { return limit != null && limit > 0 && limit < Long.MAX_VALUE; }

Try / catch

try { return context.withLimit(limit); }
catch (PrestoException e) {
    if (DRUID_QUERY_GENERATOR_FAILURE.getCode().equals(e.getErrorCode().getCode())) {
        return emptyResultPlan(); // limit <= 0 yields no rows
    }
    throw e;
}

Prevention

When it happens

Trigger: visitLimit pushes a LimitNode whose count is <= 0 (degenerate plan after optimization) or, defensively, a limit greater than Long.MAX_VALUE — practically only the limit <= 0 path is reachable from normal planning.

Common situations: Queries with LIMIT 0 (e.g. generated by tools or schema-exploration probes); plans where optimizer-produced limits of 0 were still routed to pushdown rather than an empty-result node.

Related errors


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