{"record":{"id":"9c9486e8b2ddcca3","repo":"prestodb/presto","slug":"invalid-arguments-9c9486","errorCode":"INVALID_ARGUMENTS","errorMessage":"Missing variable: ","messagePattern":"Missing variable: ","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-main-base/src/main/java/com/facebook/presto/sql/planner/optimizations/PushdownSubfields.java","lineNumber":389,"sourceCode":"        public PlanNode visitTableScan(TableScanNode node, RewriteContext<Context> context)\n        {\n            if (context.get().subfields.isEmpty()) {\n                return node;\n            }\n\n            ImmutableMap.Builder<VariableReferenceExpression, ColumnHandle> newAssignments = ImmutableMap.builder();\n\n            for (Map.Entry<VariableReferenceExpression, ColumnHandle> entry : node.getAssignments().entrySet()) {\n                VariableReferenceExpression variable = entry.getKey();\n                if (context.get().variables.contains(variable)) {\n                    newAssignments.put(entry);\n                    continue;\n                }\n\n                List<Subfield> subfields = context.get().findSubfields(variable.getName());\n\n                if (subfields.isEmpty()) {\n                    throw new PrestoException(INVALID_ARGUMENTS, \"Missing variable: \" + variable);\n                }\n\n                String columnName = getColumnName(session, metadata, node.getTable(), entry.getValue());\n\n                List<Subfield> subfieldsWithoutNoSubfield = subfields.stream().filter(subfield -> !containsNoSubfieldPathElement(subfield)).collect(toList());\n                List<Subfield> subfieldsWithNoSubfield = subfields.stream().filter(subfield -> containsNoSubfieldPathElement(subfield)).collect(toList());\n\n                // Prune subfields: if one subfield is a prefix of another subfield, keep the shortest one.\n                // Example: {a.b.c, a.b} -> {a.b}\n                List<Subfield> columnSubfields = subfieldsWithoutNoSubfield.stream()\n                        .filter(subfield -> !prefixExists(subfield, subfieldsWithoutNoSubfield))\n                        .map(Subfield::getPath)\n                        .map(path -> new Subfield(columnName, path))\n                        .collect(toList());\n\n                columnSubfields.addAll(subfieldsWithNoSubfield.stream()\n                        .filter(subfield -> !isPrefixOf(dropNoSubfield(subfield), subfieldsWithoutNoSubfield))\n                        .map(Subfield::getPath)","sourceCodeStart":371,"sourceCodeEnd":407,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-main-base/src/main/java/com/facebook/presto/sql/planner/optimizations/PushdownSubfields.java#L371-L407","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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).","File a bug with the query and EXPLAIN so PushdownSubfields can be extended for the missed pattern.","Disable the subfield pushdown optimization for the session to unblock the query."],"exampleFix":"// before\nSELECT CAST(nested_col AS ROW(a INTEGER)).a FROM t;\n// after\nSELECT nested_col.a FROM t; -- keeps subfield tracking on the variable","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    plan = planQuery(sql);\n} catch (PrestoException e) {\n    if (\"INVALID_ARGUMENTS\".equals(e.getErrorCode().getName()) && e.getMessage().startsWith(\"Missing variable:\")) {\n        plan = planQuery(sql, /* disableSubfieldPushdown */ true);\n    } else throw e;\n}","preventionTips":["Prefer direct nested-field references (row_col.a) over casts of whole nested columns","Keep nested-type expressions simple; precompute complex expressions in inner queries","Report queries that trigger it so PushdownSubfields coverage improves"],"tags":["planner","subfield-pushdown","nested-types","invalid-arguments"],"backgroundTag":"missing-subfield-variable","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}