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:
+6
-7
@@ -31,10 +31,6 @@ import {
|
||||
} from 'src/engine/api/common/types/common-query-args.type';
|
||||
import { CommonSelectedFieldsResult } from 'src/engine/api/common/types/common-selected-fields-result.type';
|
||||
import { getPageInfo } from 'src/engine/api/common/utils/get-page-info.util';
|
||||
import {
|
||||
GraphqlQueryRunnerException,
|
||||
GraphqlQueryRunnerExceptionCode,
|
||||
} from 'src/engine/api/graphql/graphql-query-runner/errors/graphql-query-runner.exception';
|
||||
import { ProcessAggregateHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/process-aggregate.helper';
|
||||
import { buildColumnsToSelect } from 'src/engine/api/graphql/graphql-query-runner/utils/build-columns-to-select';
|
||||
import { getCursor } from 'src/engine/api/graphql/graphql-query-runner/utils/cursors.util';
|
||||
@@ -112,11 +108,12 @@ export class CommonFindManyQueryRunnerService extends CommonBaseQueryRunnerServi
|
||||
fieldIdByName,
|
||||
)
|
||||
) {
|
||||
throw new GraphqlQueryRunnerException(
|
||||
// Not throwing exception because still used on record show page
|
||||
/* throw new GraphqlQueryRunnerException(
|
||||
'Cursor-based pagination is not supported with relation field ordering. Use offset pagination instead.',
|
||||
GraphqlQueryRunnerExceptionCode.INVALID_CURSOR,
|
||||
{ userFriendlyMessage: STANDARD_ERROR_MESSAGE },
|
||||
);
|
||||
); */
|
||||
}
|
||||
|
||||
const cursorArgFilter = computeCursorArgFilter(
|
||||
@@ -172,11 +169,13 @@ export class CommonFindManyQueryRunnerService extends CommonBaseQueryRunnerServi
|
||||
queryBuilder.setFindOptions({ select: columnsToSelect });
|
||||
queryBuilder.take(limit + 1);
|
||||
|
||||
// Add relation order columns AFTER setFindOptions (setFindOptions clears addSelect)
|
||||
// Add order columns AFTER setFindOptions (setFindOptions clears addSelect)
|
||||
// Pass columnsToSelect so we only add columns that aren't already selected
|
||||
commonQueryParser.addRelationOrderColumnsToBuilder(
|
||||
queryBuilder,
|
||||
parsedOrderBy,
|
||||
flatObjectMetadata.nameSingular,
|
||||
columnsToSelect,
|
||||
);
|
||||
|
||||
const objectRecords = (await queryBuilder.getMany()) as ObjectRecord[];
|
||||
|
||||
Reference in New Issue
Block a user