Skip to content

Commit 89e0d52

Browse files
rojiCopilot
andcommitted
Fix GIN index detection for views
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent 6547cdd commit 89e0d52

2 files changed

Lines changed: 27 additions & 6 deletions

File tree

src/EFCore.PG/Query/Internal/NpgsqlQueryableMethodTranslatingExpressionVisitor.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -703,12 +703,12 @@ protected override ShapedQueryExpression TransformJsonQueryToTable(JsonQueryExpr
703703
return array switch
704704
{
705705
// For array columns which have a GIN index, we translate to array containment (with @>) which uses that index.
706-
ColumnExpression { Column: IColumn column }
707-
when column.Table.Indexes
708-
.Any(i =>
709-
i.Columns.Count > 0
710-
&& i.Columns[0] == column
711-
&& i.MappedIndexes.Any(mi => mi.GetMethod()?.Equals("GIN", StringComparison.OrdinalIgnoreCase) == true))
706+
ColumnExpression { Column: IColumnBase column }
707+
when column.PropertyMappings.Any(
708+
m => m.Property.GetContainingIndexes().Any(
709+
i => i.Properties.Count > 0
710+
&& i.Properties[0] == m.Property
711+
&& i.GetMethod()?.Equals("GIN", StringComparison.OrdinalIgnoreCase) == true))
712712
=> BuildSimplifiedShapedQuery(
713713
source,
714714
_sqlExpressionFactory.Contains(

test/EFCore.PG.FunctionalTests/Query/NonSharedPrimitiveCollectionsQueryNpgsqlTest.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,27 @@ LIMIT 2
135135
""");
136136
}
137137

138+
[ConditionalFact]
139+
public virtual async Task View_column_collection_Contains_with_GIN_index_uses_containment()
140+
{
141+
var contextFactory = await InitializeAsync<TestContext>(
142+
onModelCreating: mb => mb.Entity<TestEntity>()
143+
.ToView("TestView")
144+
.HasIndex(e => e.Ints)
145+
.HasMethod("GIN"),
146+
onConfiguring: b => b.ConfigureWarnings(w => w.Ignore(RelationalEventId.AllIndexPropertiesNotToMappedToAnyTable)));
147+
148+
await using var context = contextFactory.CreateContext();
149+
150+
Assert.Equal(
151+
"""
152+
SELECT t."Id", t."Ints"
153+
FROM "TestView" AS t
154+
WHERE t."Ints" @> ARRAY[4]::integer[]
155+
""",
156+
context.Set<TestEntity>().Where(c => c.Ints!.Contains(4)).ToQueryString());
157+
}
158+
138159
[ConditionalFact]
139160
public virtual async Task Column_collection_Contains_with_btree_index_does_not_use_containment()
140161
{

0 commit comments

Comments
 (0)