prestodb/presto · error · PrestoException

INVALID_ARGUMENTS

INVALID_ARGUMENTS

Error message

Missing variable: 

What it means

PushdownSubfields rewrites table scans to push down only the subfields (nested column paths) actually referenced by the query. For every scan output variable it looks up tracked subfields; if a variable has no recorded subfields it throws INVALID_ARGUMENTS 'Missing variable: <name>'. This indicates the subfield tracking pass missed a variable the scan exposes.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/sql/planner/optimizations/PushdownSubfields.java:389

        public PlanNode visitTableScan(TableScanNode node, RewriteContext<Context> context)
        {
            if (context.get().subfields.isEmpty()) {
                return node;
            }

            ImmutableMap.Builder<VariableReferenceExpression, ColumnHandle> newAssignments = ImmutableMap.builder();

            for (Map.Entry<VariableReferenceExpression, ColumnHandle> entry : node.getAssignments().entrySet()) {
                VariableReferenceExpression variable = entry.getKey();
                if (context.get().variables.contains(variable)) {
                    newAssignments.put(entry);
                    continue;
                }

                List<Subfield> subfields = context.get().findSubfields(variable.getName());

                if (subfields.isEmpty()) {
                    throw new PrestoException(INVALID_ARGUMENTS, "Missing variable: " + variable);
                }

                String columnName = getColumnName(session, metadata, node.getTable(), entry.getValue());

                List<Subfield> subfieldsWithoutNoSubfield = subfields.stream().filter(subfield -> !containsNoSubfieldPathElement(subfield)).collect(toList());
                List<Subfield> subfieldsWithNoSubfield = subfields.stream().filter(subfield -> containsNoSubfieldPathElement(subfield)).collect(toList());

                // Prune subfields: if one subfield is a prefix of another subfield, keep the shortest one.
                // Example: {a.b.c, a.b} -> {a.b}
                List<Subfield> columnSubfields = subfieldsWithoutNoSubfield.stream()
                        .filter(subfield -> !prefixExists(subfield, subfieldsWithoutNoSubfield))
                        .map(Subfield::getPath)
                        .map(path -> new Subfield(columnName, path))
                        .collect(toList());

                columnSubfields.addAll(subfieldsWithNoSubfield.stream()
                        .filter(subfield -> !isPrefixOf(dropNoSubfield(subfield), subfieldsWithoutNoSubfield))
                        .map(Subfield::getPath)

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Reduce the query to identify which expression over the nested column loses subfield tracking, and rewrite it (e.g. extract the needed subfield earlier into a subquery).
  2. File a bug with the query and EXPLAIN so PushdownSubfields can be extended for the missed pattern.
  3. Disable the subfield pushdown optimization for the session to unblock the query.

Example fix

// before
SELECT CAST(nested_col AS ROW(a INTEGER)).a FROM t;
// after
SELECT nested_col.a FROM t; -- keeps subfield tracking on the variable
Defensive patterns

Strategy: fallback

Try / catch

try {
    plan = planQuery(sql);
} catch (PrestoException e) {
    if ("INVALID_ARGUMENTS".equals(e.getErrorCode().getName()) && e.getMessage().startsWith("Missing variable:")) {
        plan = planQuery(sql, /* disableSubfieldPushdown */ true);
    } else throw e;
}

Prevention

When it happens

Trigger: A table scan output variable is not present in the subfield context built by this optimizer — typically a nested-row/column variable referenced by the query for which findSubfields returns empty during visitTableScan.

Common situations: Queries over nested row types / complex columns where the subfield extraction rules do not cover an expression referencing the variable; planner rule interaction bugs; casting or function usage that strips subfield association.

Related errors


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