Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 86cee8b

Browse files
Remove redundant selectors in QueryLayer, only sort by ID when pagination enabled (#1735)
1 parent c00f552 commit 86cee8b

File tree

9 files changed

+62
-39
lines changed

9 files changed

+62
-39
lines changed

‎src/JsonApiDotNetCore/Queries/QueryLayer.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ namespace JsonApiDotNetCore.Queries;
1111
[PublicAPI]
1212
public sealed class QueryLayer
1313
{
14+
internal bool IsEmpty => Filter == null && Sort == null && Pagination?.PageSize == null && (Selection == null || Selection.IsEmpty);
15+
1416
public ResourceType ResourceType { get; }
1517

1618
public IncludeExpression? Include { get; set; }

‎src/JsonApiDotNetCore/Queries/QueryLayerComposer.cs

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -173,13 +173,20 @@ private QueryLayer ComposeTopLayer(ImmutableArray<ExpressionInScope> constraints
173173
_paginationContext.PageSize = topPagination.PageSize;
174174
_paginationContext.PageNumber = topPagination.PageNumber;
175175

176-
return new QueryLayer(resourceType)
176+
vartopLayer= new QueryLayer(resourceType)
177177
{
178178
Filter = GetFilter(expressionsInTopScope, resourceType),
179179
Sort = GetSort(expressionsInTopScope, resourceType),
180180
Pagination = topPagination,
181181
Selection = GetSelectionForSparseAttributeSet(resourceType)
182182
};
183+
184+
if (topLayer is { Pagination.PageSize: not null, Sort: null })
185+
{
186+
topLayer.Sort = CreateSortById(resourceType);
187+
}
188+
189+
return topLayer;
183190
}
184191

185192
private IncludeExpression ComposeChildren(QueryLayer topLayer, ImmutableArray<ExpressionInScope> constraints)
@@ -237,17 +244,22 @@ private IImmutableSet<IncludeElementExpression> ProcessIncludeSet(IImmutableSet<
237244
ResourceType resourceType = includeElement.Relationship.RightType;
238245
bool isToManyRelationship = includeElement.Relationship is HasManyAttribute;
239246

240-
var child = new QueryLayer(resourceType)
247+
var subLayer = new QueryLayer(resourceType)
241248
{
242249
Filter = isToManyRelationship ? GetFilter(expressionsInCurrentScope, resourceType) : null,
243250
Sort = isToManyRelationship ? GetSort(expressionsInCurrentScope, resourceType) : null,
244251
Pagination = isToManyRelationship ? GetPagination(expressionsInCurrentScope, resourceType) : null,
245252
Selection = GetSelectionForSparseAttributeSet(resourceType)
246253
};
247254

248-
selectors.IncludeRelationship(includeElement.Relationship, child);
255+
if (subLayer is { Pagination.PageSize: not null, Sort: null })
256+
{
257+
subLayer.Sort = CreateSortById(resourceType);
258+
}
249259

250-
IImmutableSet<IncludeElementExpression> updatedChildren = ProcessIncludeSet(includeElement.Children, child, relationshipChain, constraints);
260+
selectors.IncludeRelationship(includeElement.Relationship, subLayer);
261+
262+
IImmutableSet<IncludeElementExpression> updatedChildren = ProcessIncludeSet(includeElement.Children, subLayer, relationshipChain, constraints);
251263

252264
if (!ReferenceEquals(includeElement.Children, updatedChildren))
253265
{
@@ -256,9 +268,30 @@ private IImmutableSet<IncludeElementExpression> ProcessIncludeSet(IImmutableSet<
256268
}
257269
}
258270

271+
EliminateRedundantSelectors(parentLayer);
272+
259273
return updatesInChildren.Count == 0 ? includeElementsEvaluated : ApplyIncludeElementUpdates(includeElementsEvaluated, updatesInChildren);
260274
}
261275

276+
private static void EliminateRedundantSelectors(QueryLayer parentLayer)
277+
{
278+
if (parentLayer.Selection != null)
279+
{
280+
foreach ((ResourceType resourceType, FieldSelectors selectors) in parentLayer.Selection.ToArray())
281+
{
282+
if (selectors.ContainsOnlyRelationships && selectors.Values.OfType<QueryLayer>().All(subLayer => subLayer.IsEmpty))
283+
{
284+
parentLayer.Selection.Remove(resourceType);
285+
}
286+
}
287+
288+
if (parentLayer.Selection.IsEmpty)
289+
{
290+
parentLayer.Selection = null;
291+
}
292+
}
293+
}
294+
262295
private static ImmutableHashSet<IncludeElementExpression> ApplyIncludeElementUpdates(IImmutableSet<IncludeElementExpression> includeElements,
263296
Dictionary<IncludeElementExpression, IImmutableSet<IncludeElementExpression>> updatesInChildren)
264297
{
@@ -507,23 +540,21 @@ protected virtual IImmutableSet<IncludeElementExpression> GetIncludeElements(IIm
507540
return _resourceDefinitionAccessor.OnApplyFilter(resourceType, filter);
508541
}
509542

510-
protected virtual SortExpression GetSort(IReadOnlyCollection<QueryExpression> expressionsInScope, ResourceType resourceType)
543+
protected virtual SortExpression? GetSort(IReadOnlyCollection<QueryExpression> expressionsInScope, ResourceType resourceType)
511544
{
512545
ArgumentNullException.ThrowIfNull(expressionsInScope);
513546
ArgumentNullException.ThrowIfNull(resourceType);
514547

515548
SortExpression? sort = expressionsInScope.OfType<SortExpression>().FirstOrDefault();
516549

517-
sort = _resourceDefinitionAccessor.OnApplySort(resourceType, sort);
518-
519-
if (sort == null)
520-
{
521-
AttrAttribute idAttribute = GetIdAttribute(resourceType);
522-
var idAscendingSort = new SortElementExpression(new ResourceFieldChainExpression(idAttribute), true);
523-
sort = new SortExpression(ImmutableArray.Create(idAscendingSort));
524-
}
550+
return _resourceDefinitionAccessor.OnApplySort(resourceType, sort);
551+
}
525552

526-
return sort;
553+
private SortExpression CreateSortById(ResourceType resourceType)
554+
{
555+
AttrAttribute idAttribute = GetIdAttribute(resourceType);
556+
var idAscendingSort = new SortElementExpression(new ResourceFieldChainExpression(idAttribute), true);
557+
return new SortExpression(ImmutableArray.Create(idAscendingSort));
527558
}
528559

529560
protected virtual PaginationExpression GetPagination(IReadOnlyCollection<QueryExpression> expressionsInScope, ResourceType resourceType)

‎test/DapperTests/IntegrationTests/QueryStrings/FilterTests.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ SELECT COUNT(*)
7878
FROM "Tags" AS t1
7979
LEFT JOIN "RgbColors" AS t2 ON t1."Id" = t2."TagId"
8080
WHERE t2."Id" = @p1
81-
ORDER BY t1."Id"
8281
"""));
8382

8483
command.Parameters.Should().HaveCount(1);
@@ -144,7 +143,6 @@ SELECT COUNT(*)
144143
FROM "Tags" AS t1
145144
LEFT JOIN "RgbColors" AS t2 ON t1."Id" = t2."TagId"
146145
WHERE t2."Id" IN (@p1, @p2)
147-
ORDER BY t1."Id"
148146
"""));
149147

150148
command.Parameters.Should().HaveCount(2);
@@ -662,7 +660,6 @@ SELECT COUNT(*)
662660
SELECT t1."Id", t1."FirstName", t1."LastName"
663661
FROM "People" AS t1
664662
WHERE (NOT (t1."FirstName" = @p1)) OR (t1."FirstName" IS NULL)
665-
ORDER BY t1."Id"
666663
"""));
667664

668665
command.Parameters.Should().HaveCount(1);
@@ -867,7 +864,6 @@ SELECT COUNT(*)
867864
SELECT t1."Id", t1."Name"
868865
FROM "Tags" AS t1
869866
WHERE (t1."Name" LIKE '%A\%%' ESCAPE '\') OR (t1."Name" LIKE '%A\_%' ESCAPE '\') OR (t1."Name" LIKE '%A\\%' ESCAPE '\') OR (t1."Name" LIKE '%A''%') OR (t1."Name" LIKE '%\%\_\\''%' ESCAPE '\')
870-
ORDER BY t1."Id"
871867
"""));
872868

873869
command.Parameters.Should().BeEmpty();
@@ -1177,7 +1173,6 @@ SELECT 1
11771173
LEFT JOIN "People" AS t3 ON t2."AssigneeId" = t3."Id"
11781174
WHERE (t1."Id" = t2."OwnerId") AND (NOT (t3."Id" IS NULL)) AND (t3."FirstName" IS NULL)
11791175
)
1180-
ORDER BY t1."Id"
11811176
"""));
11821177

11831178
command.Parameters.Should().BeEmpty();

‎test/DapperTests/IntegrationTests/QueryStrings/IncludeTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ SELECT COUNT(*)
165165
INNER JOIN "People" AS t3 ON t1."OwnerId" = t3."Id"
166166
LEFT JOIN "TodoItems" AS t4 ON t3."Id" = t4."AssigneeId"
167167
LEFT JOIN "Tags" AS t5 ON t1."Id" = t5."TodoItemId"
168-
ORDER BY t1."Priority", t1."LastModifiedAt" DESC, t4."Priority", t4."LastModifiedAt" DESC, t5."Id"
168+
ORDER BY t1."Priority", t1."LastModifiedAt" DESC, t4."Priority", t4."LastModifiedAt" DESC
169169
"""));
170170

171171
command.Parameters.Should().BeEmpty();
@@ -231,7 +231,7 @@ SELECT COUNT(*)
231231
FROM "TodoItems" AS t1
232232
LEFT JOIN "Tags" AS t2 ON t1."Id" = t2."TodoItemId"
233233
LEFT JOIN "RgbColors" AS t3 ON t2."Id" = t3."TagId"
234-
ORDER BY t1."Priority", t1."LastModifiedAt" DESC, t2."Id"
234+
ORDER BY t1."Priority", t1."LastModifiedAt" DESC
235235
"""));
236236

237237
command.Parameters.Should().BeEmpty();

‎test/DapperTests/IntegrationTests/QueryStrings/SortTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ ORDER BY (
349349
SELECT COUNT(*)
350350
FROM "Tags" AS t3
351351
WHERE t2."Id" = t3."TodoItemId"
352-
) DESC, t2."Id", t4."Id"
352+
) DESC, t2."Id"
353353
"""));
354354

355355
command.Parameters.Should().HaveCount(1);
@@ -415,7 +415,7 @@ SELECT COUNT(*)
415415
SELECT t1."Id", t1."FirstName", t1."LastName", t2."Id", t2."CreatedAt", t2."Description", t2."DurationInHours", t2."LastModifiedAt", t2."Priority"
416416
FROM "People" AS t1
417417
LEFT JOIN "TodoItems" AS t2 ON t1."Id" = t2."OwnerId"
418-
ORDER BY t1."Id", (
418+
ORDER BY (
419419
SELECT COUNT(*)
420420
FROM "Tags" AS t3
421421
WHERE t2."Id" = t3."TodoItemId"

‎test/DapperTests/IntegrationTests/QueryStrings/SparseFieldSets.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,6 @@ SELECT COUNT(*)
215215
FROM "TodoItems" AS t1
216216
LEFT JOIN "Tags" AS t2 ON t1."Id" = t2."TodoItemId"
217217
WHERE t1."Id" = @p1
218-
ORDER BY t2."Id"
219218
"""));
220219

221220
command.Parameters.Should().HaveCount(1);
@@ -400,7 +399,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext =>
400399
FROM "TodoItems" AS t1
401400
LEFT JOIN "Tags" AS t2 ON t1."Id" = t2."TodoItemId"
402401
WHERE t1."Id" = @p1
403-
ORDER BY t2."Id"
404402
"""));
405403

406404
command.Parameters.Should().HaveCount(1);

‎test/DapperTests/IntegrationTests/ReadWrite/Relationships/FetchRelationshipTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,6 @@ SELECT COUNT(*)
168168
FROM "TodoItems" AS t1
169169
LEFT JOIN "Tags" AS t2 ON t1."Id" = t2."TodoItemId"
170170
WHERE t1."Id" = @p1
171-
ORDER BY t2."Id"
172171
"""));
173172

174173
command.Parameters.Should().HaveCount(1);

‎test/DapperTests/IntegrationTests/ReadWrite/Resources/FetchResourceTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,6 @@ SELECT COUNT(*)
246246
FROM "TodoItems" AS t1
247247
LEFT JOIN "Tags" AS t2 ON t1."Id" = t2."TodoItemId"
248248
WHERE t1."Id" = @p1
249-
ORDER BY t2."Id"
250249
"""));
251250

252251
command.Parameters.Should().HaveCount(1);

‎test/DapperTests/IntegrationTests/Sql/SubQueryInJoinTests.cs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ SELECT COUNT(*)
6262
SELECT t1."Id", t1."FirstName", t1."LastName", t2."Id", t2."LastUsedAt", t2."UserName"
6363
FROM "People" AS t1
6464
LEFT JOIN "LoginAccounts" AS t2 ON t1."AccountId" = t2."Id"
65-
ORDER BY t1."Id"
6665
"""));
6766

6867
command.Parameters.Should().BeEmpty();
@@ -111,7 +110,7 @@ SELECT COUNT(*)
111110
SELECT t1."Id", t1."FirstName", t1."LastName", t2."Id", t2."CreatedAt", t2."Description", t2."DurationInHours", t2."LastModifiedAt", t2."Priority"
112111
FROM "People" AS t1
113112
LEFT JOIN "TodoItems" AS t2 ON t1."Id" = t2."OwnerId"
114-
ORDER BY t1."Id", t2."Priority", t2."LastModifiedAt" DESC
113+
ORDER BY t2."Priority", t2."LastModifiedAt" DESC
115114
"""));
116115

117116
command.Parameters.Should().BeEmpty();
@@ -160,7 +159,7 @@ SELECT COUNT(*)
160159
SELECT t1."Id", t1."FirstName", t1."LastName", t2."Id", t2."CreatedAt", t2."Description", t2."DurationInHours", t2."LastModifiedAt", t2."Priority"
161160
FROM "People" AS t1
162161
LEFT JOIN "TodoItems" AS t2 ON t1."Id" = t2."OwnerId"
163-
ORDER BY t1."Id", t2."Description"
162+
ORDER BY t2."Description"
164163
"""));
165164

166165
command.Parameters.Should().BeEmpty();
@@ -209,7 +208,7 @@ SELECT COUNT(*)
209208
SELECT t1."Id", t1."FirstName", t1."LastName", t2."Id", t2."CreatedAt", t2."Description", t2."DurationInHours", t2."LastModifiedAt", t2."Priority"
210209
FROM "People" AS t1
211210
LEFT JOIN "TodoItems" AS t2 ON t1."Id" = t2."OwnerId"
212-
ORDER BY t1."Id", (
211+
ORDER BY (
213212
SELECT COUNT(*)
214213
FROM "Tags" AS t3
215214
WHERE t2."Id" = t3."TodoItemId"
@@ -263,7 +262,7 @@ SELECT COUNT(*)
263262
FROM "People" AS t1
264263
LEFT JOIN "TodoItems" AS t2 ON t1."Id" = t2."OwnerId"
265264
LEFT JOIN "Tags" AS t4 ON t2."Id" = t4."TodoItemId"
266-
ORDER BY t1."Id", (
265+
ORDER BY (
267266
SELECT COUNT(*)
268267
FROM "Tags" AS t3
269268
WHERE t2."Id" = t3."TodoItemId"
@@ -326,11 +325,11 @@ SELECT COUNT(*)
326325
SELECT COUNT(*)
327326
FROM "Tags" AS t4
328327
WHERE t3."Id" = t4."TodoItemId"
329-
), t5."Id", (
328+
), (
330329
SELECT COUNT(*)
331330
FROM "Tags" AS t7
332331
WHERE t6."Id" = t7."TodoItemId"
333-
), t8."Id"
332+
)
334333
"""));
335334

336335
command.Parameters.Should().BeEmpty();
@@ -383,7 +382,7 @@ LEFT JOIN (
383382
FROM "TodoItems" AS t2
384383
WHERE t2."Description" = @p1
385384
) AS t3 ON t1."Id" = t3."OwnerId"
386-
ORDER BY t1."Id", t3."Priority", t3."LastModifiedAt" DESC
385+
ORDER BY t3."Priority", t3."LastModifiedAt" DESC
387386
"""));
388387

389388
command.Parameters.Should().HaveCount(1);
@@ -441,7 +440,7 @@ SELECT 1
441440
WHERE t2."Id" = t3."TodoItemId"
442441
)
443442
) AS t4 ON t1."Id" = t4."OwnerId"
444-
ORDER BY t1."Id", t4."Priority", t4."LastModifiedAt" DESC
443+
ORDER BY t4."Priority", t4."LastModifiedAt" DESC
445444
"""));
446445

447446
command.Parameters.Should().BeEmpty();
@@ -498,7 +497,7 @@ SELECT COUNT(*)
498497
WHERE t2."Id" = t3."TodoItemId"
499498
) > @p1
500499
) AS t4 ON t1."Id" = t4."OwnerId"
501-
ORDER BY t1."Id", t4."Priority", t4."LastModifiedAt" DESC
500+
ORDER BY t4."Priority", t4."LastModifiedAt" DESC
502501
"""));
503502

504503
command.Parameters.Should().HaveCount(1);
@@ -554,7 +553,7 @@ LEFT JOIN (
554553
LEFT JOIN "Tags" AS t4 ON t2."Id" = t4."TodoItemId"
555554
WHERE t2."Description" = @p1
556555
) AS t5 ON t1."Id" = t5."OwnerId"
557-
ORDER BY t1."Id", (
556+
ORDER BY (
558557
SELECT COUNT(*)
559558
FROM "Tags" AS t3
560559
WHERE t5."Id" = t3."TodoItemId"
@@ -620,7 +619,7 @@ WHERE NOT (t5."Name" = @p2)
620619
) AS t6 ON t2."Id" = t6."TodoItemId"
621620
WHERE NOT (t2."Description" = @p1)
622621
) AS t7 ON t1."Id" = t7."OwnerId"
623-
ORDER BY t1."Id", (
622+
ORDER BY (
624623
SELECT COUNT(*)
625624
FROM "Tags" AS t3
626625
WHERE t7."Id" = t3."TodoItemId"

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /