{"record":{"id":"f325c766271e9479","repo":"prestodb/presto","slug":"ambiguous-attribute-f325c7","errorCode":"AMBIGUOUS_ATTRIBUTE","errorMessage":"'%s' in ORDER BY is ambiguous","messagePattern":"'(.+?)' in ORDER BY is ambiguous","errorType":"error_code","errorClass":"SemanticException","httpStatus":null,"severity":"error","filePath":"presto-main-base/src/main/java/com/facebook/presto/sql/analyzer/StatementAnalyzer.java","lineNumber":4315,"sourceCode":"        {\n            private final Multimap<QualifiedName, Expression> assignments;\n\n            public OrderByExpressionRewriter(Multimap<QualifiedName, Expression> assignments)\n            {\n                this.assignments = assignments;\n            }\n\n            @Override\n            public Expression rewriteIdentifier(Identifier reference, Void context, ExpressionTreeRewriter<Void> treeRewriter)\n            {\n                // if this is a simple name reference, try to resolve against output columns\n                QualifiedName name = QualifiedName.of(reference.getValue());\n                Set<Expression> expressions = assignments.get(name)\n                        .stream()\n                        .collect(Collectors.toSet());\n\n                if (expressions.size() > 1) {\n                    throw new SemanticException(AMBIGUOUS_ATTRIBUTE, reference, \"'%s' in ORDER BY is ambiguous\", name);\n                }\n\n                if (expressions.size() == 1) {\n                    return expressions.stream().collect(onlyElement());\n                }\n\n                // otherwise, couldn't resolve name against output aliases, so fall through...\n                return reference;\n            }\n        }\n\n        private void checkGroupingSetsCount(GroupBy node)\n        {\n            // If groupBy is distinct then crossProduct will be overestimated if there are duplicate grouping sets.\n            int crossProduct = 1;\n            for (GroupingElement element : node.getGroupingElements()) {\n                try {\n                    int product;","sourceCodeStart":4297,"sourceCodeEnd":4333,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-main-base/src/main/java/com/facebook/presto/sql/analyzer/StatementAnalyzer.java#L4297-L4333","documentation":"Presto throws this during ORDER BY analysis when an output alias in the ORDER BY clause maps to more than one distinct expression in the SELECT list. Because the analyzer resolves ORDER BY ordinals/names against select assignments, a name with multiple candidate expressions is ambiguous and cannot be resolved. This is a semantic validation error raised by StatementAnalyzer's Visitor.","triggerScenarios":"An ORDER BY references a column name or alias that appears multiple times in the SELECT list with different underlying expressions, e.g. SELECT a, b AS x, c AS x FROM t ORDER BY x.","commonSituations":"Queries built by ORMs or query builders that duplicate output column names; hand-written SQL where two select items share the same alias; joins where an unqualified name matches select items from multiple tables after aliasing.","solutions":["Rename one of the duplicate SELECT aliases so each ORDER BY name maps to a single expression.","Replace the ambiguous name in ORDER BY with an explicit ordinal (ORDER BY 2) or a fully qualified column reference (t.col).","Order by an expression directly (ORDER BY a + b) instead of the shared alias."],"exampleFix":"// before\nSELECT price AS v, discount AS v FROM items ORDER BY v;\n// after\nSELECT price AS price_v, discount AS discount_v FROM items ORDER BY price_v;","handlingStrategy":"validation","validationCode":"// Parse the SELECT list and ORDER BY before running; ensure every ORDER BY name maps to exactly one select item.\nSet<String> aliases = selectItems.stream().map(this::outputName).collect(toSet());\nfor (String obName : orderByNames) {\n    if (Collections.frequency(outputNames, obName) > 1) {\n        throw new IllegalArgumentException(\"Ambiguous ORDER BY name: \" + obName);\n    }\n}","typeGuard":null,"tryCatchPattern":"try { queryRunner.execute(sql); } catch (SemanticException e) { if (e.getCode() == SemanticErrorCode.AMBIGUOUS_ATTRIBUTE) { /* rewrite ORDER BY with explicit column or ordinal */ } else { throw e; } }","preventionTips":["Never reuse the same alias for two SELECT items.","Order by qualified column names rather than short aliases in complex queries.","Add a SQL lint step that detects duplicate output column names."],"tags":["sql","presto","semantic-analysis","order-by"],"backgroundTag":"ambiguous-column-reference","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"}