Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/EFCore.PG/Internal/EnumerableMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ internal static class EnumerableMethods

public static MethodInfo All { get; }

// public static MethodInfo AnyWithoutPredicate { get; }
public static MethodInfo AnyWithoutPredicate { get; }

public static MethodInfo AnyWithPredicate { get; }

Expand Down Expand Up @@ -259,8 +259,9 @@ static EnumerableMethods()
nameof(Enumerable.All), 1,
types => [typeof(IEnumerable<>).MakeGenericType(types[0]), typeof(Func<,>).MakeGenericType(types[0], typeof(bool))]);

// AnyWithoutPredicate = GetMethod(nameof(Enumerable.Any), 1,
// types => new[] { typeof(IEnumerable<>).MakeGenericType(types[0]) });
AnyWithoutPredicate = GetMethod(
nameof(Enumerable.Any), 1,
types => [typeof(IEnumerable<>).MakeGenericType(types[0])]);

AnyWithPredicate = GetMethod(
nameof(Enumerable.Any), 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,18 @@ public NpgsqlByteArrayMethodTranslator(ISqlExpressionFactory sqlExpressionFactor
// Note: we only translate if the array argument is a column mapped to bytea. There are various other
// cases (e.g. Where(b => new byte[] { 1, 2, 3 }.Contains(b.SomeByte))) where we prefer to translate via
// regular PostgreSQL array logic.
if (method.GetGenericMethodDefinition().Equals(EnumerableMethods.AnyWithoutPredicate))
Comment thread
georg-jung marked this conversation as resolved.
Outdated
Comment thread
georg-jung marked this conversation as resolved.
Outdated
{
return _sqlExpressionFactory.GreaterThan(
_sqlExpressionFactory.Function(
"octet_length",
[arguments[0]],
nullable: true,
argumentsPropagateNullability: TrueArrays[1],
typeof(int)),
_sqlExpressionFactory.Constant(0));
Comment thread
roji marked this conversation as resolved.
Outdated
}

if (method.GetGenericMethodDefinition().Equals(EnumerableMethods.Contains))
{
var source = arguments[0];
Expand Down
13 changes: 13 additions & 0 deletions test/EFCore.PG.FunctionalTests/Query/ArrayArrayQueryTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,19 @@ WHERE cardinality(s."IntArray") = 2
""");
}

[ConditionalFact]
public virtual async Task Bytea_Length_greater_than_zero()
{
await AssertQuery(ss => ss.Set<ArrayEntity>().Where(e => e.Bytea.Length > 0));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this test for Any(), rather than for Length > 0?

Also, can you please move this test to ByteArrayTranslationsNpgsqlTest? The latter is then newer place for this kind of test (ArrayArrayQueryTest should eventually disappear).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I'm slightly confused, as #3816 talks about Length > 0 not working, but this PR implements support for Any() - are both broken, or just one of them? I'm noting that ByteArrayTranslationsNpgsqlTest does have test coverage for Length, so I assume it's working and the problem is only with Any?

@georg-jung georg-jung Apr 26, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What caused the regression is that .Length > 0 was translated similar to .Length == 7 until incl. EF8, but as far as I understand it, EF started to rewrite .Length > 0 to .Any internally from EF 9. Thus, to effectively fix .Length > 0, this PR implements .Any.

Options include:

  • test .Length > 0 (what we currently have); goes through the .Any path internally but the expression and the sql both use Length
  • also test .Any in the expression, same translation, two tests
  • only test .Any, also same translation

@georg-jung georg-jung Apr 26, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went for

also test .Any in the expression, same translation, two tests

in 05db0b8 now.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably dotnet/efcore#33644 introduced this


AssertSql(
"""
SELECT s."Id", s."ArrayContainerEntityId", s."ArrayOfStringConvertedToDelimitedString", s."Byte", s."ByteArray", s."Bytea", s."EnumConvertedToInt", s."EnumConvertedToString", s."IList", s."IntArray", s."IntList", s."ListOfStringConvertedToDelimitedString", s."NonNullableText", s."NullableEnumConvertedToString", s."NullableEnumConvertedToStringWithNonNullableLambda", s."NullableIntArray", s."NullableIntList", s."NullableStringArray", s."NullableStringList", s."NullableText", s."StringArray", s."StringList", s."ValueConvertedArrayOfEnum", s."ValueConvertedListOfEnum", s."Varchar10", s."Varchar15"
FROM "SomeEntities" AS s
WHERE octet_length(s."Bytea") > 0
""");
}
Comment thread
roji marked this conversation as resolved.
Outdated

#endregion Length/Count

#region Any/All
Expand Down
Loading