Fix orderBy columns missing from SELECT in DISTINCT subquery (#17079)
## Description Fixes a bug where queries with relation field + scalar field ordering would fail with: ``` column distinctAlias.person_position does not exist ``` ## Root Cause When a GraphQL query orders by columns that are **not in the selected fields**, TypeORM's DISTINCT subquery fails because it expects those columns in the inner SELECT with alias format (e.g., `person_position`). The issue only manifests when: 1. A filter is applied (triggers DISTINCT path in TypeORM) 2. OrderBy includes columns NOT in the GraphQL selection 3. Example: query selects only `id`, but orders by `position` ## The Fix `addRelationOrderColumnsToBuilder` now accepts `columnsToSelect` and adds orderBy columns via `addSelect()` only if they're **NOT** already in the selected columns: - **Relation orderBy columns**: Always added (never in columnsToSelect) - **Main entity orderBy columns**: Added only when not already selected This ensures all orderBy columns are present in TypeORM's inner SELECT for the DISTINCT subquery. ## Test Plan Added integration test for the exact failing scenario: - Filter with `neq` (triggers DISTINCT path) - Multiple orderBy: relation field + scalar field - Minimal field selection (only `id`, not `position`) ## Related Regression introduced in #17021 which added nested sort support.
This commit is contained in:
+9
-3
@@ -142,17 +142,23 @@ export class GraphqlQueryParser {
|
||||
queryBuilder: WorkspaceSelectQueryBuilder<any>,
|
||||
parsedOrderBy: Record<string, OrderByClause>,
|
||||
objectNameSingular: string,
|
||||
columnsToSelect: Record<string, boolean>,
|
||||
): void {
|
||||
// Add relation ORDER BY columns with underscore alias for DISTINCT compatibility
|
||||
// Add ORDER BY columns with underscore alias for DISTINCT compatibility
|
||||
// This must be called AFTER setFindOptions because setFindOptions clears addSelect
|
||||
// We need to add columns that are in orderBy but NOT in the selected columns
|
||||
for (const orderByKey of Object.keys(parsedOrderBy)) {
|
||||
const parts = orderByKey.split('.');
|
||||
|
||||
if (parts.length === 2) {
|
||||
const [alias, column] = parts;
|
||||
|
||||
// Only add select for joined relation columns, not main entity columns
|
||||
if (alias !== objectNameSingular) {
|
||||
// For relation columns: always add (they're never in columnsToSelect)
|
||||
// For main entity columns: only add if NOT already in columnsToSelect
|
||||
const isMainEntity = alias === objectNameSingular;
|
||||
const isAlreadySelected = isMainEntity && columnsToSelect[column];
|
||||
|
||||
if (!isAlreadySelected) {
|
||||
queryBuilder.addSelect(
|
||||
`"${alias}"."${column}"`,
|
||||
`${alias}_${column}`,
|
||||
|
||||
Reference in New Issue
Block a user