Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System.Linq;
using Marten.Services;
using Shouldly;
using Xunit;

namespace Marten.Testing.Linq
{
public class invoking_queryable_any_nopredicate_Tests : DocumentSessionFixture<NulloIdentityMap>
{

[Fact]
public void naked_any_hit()
{
var targetithchildren = new Target {Number = 1};
targetithchildren.Children = new[] {new Target(),};
var nochildrennullarray = new Target { Number = 2 };
var nochildrenemptyarray = new Target { Number = 3 };
nochildrenemptyarray.Children = new Target[] {};
theSession.Store(nochildrennullarray);
theSession.Store(nochildrenemptyarray);
theSession.Store(targetithchildren);
theSession.SaveChanges();

var items = theSession.Query<Target>().Where(x => x.Children.Any()).ToList();

items.Count.ShouldBe(1);
}

}
}
35 changes: 35 additions & 0 deletions src/Marten/Linq/CollectionAnyNoPredicateWhereFragment.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Linq;
using Baseline;
using Npgsql;
using Remotion.Linq.Clauses.Expressions;

namespace Marten.Linq
{
/// <summary>
/// Handle Any() with JSONB_ARRAY_LENGTH introduced in PostgreSQL 9.4
/// </summary>
public class CollectionAnyNoPredicateWhereFragment : IWhereFragment
{
private readonly SubQueryExpression _expression;

public CollectionAnyNoPredicateWhereFragment(SubQueryExpression expression)
{
_expression = expression;
}

public string ToSql(NpgsqlCommand command)
{
var visitor = new FindMembers();
visitor.Visit(_expression.QueryModel.MainFromClause.FromExpression);
var path = visitor.Members.Select(m => m.Name).Join("'->'");

var query = $"JSONB_ARRAY_LENGTH(COALESCE(case when data->>'{path}' is not null then data->'{path}' else '[]' end)) > 0";
return query;
}

public bool Contains(string sqlText)
{
return false;
}
}
}
8 changes: 8 additions & 0 deletions src/Marten/Linq/WhereClauseVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,14 @@ protected override Expression VisitSubQuery(SubQueryExpression expression)

if (expression.QueryModel.ResultOperators.Any(x => x is AnyResultOperator))
{
// Any() without predicate
if (!expression.QueryModel.BodyClauses.Any())
{
var @where_any_nopredicate = new CollectionAnyNoPredicateWhereFragment(expression);

_register.Peek()(@where_any_nopredicate);
return null;
}
var @where = new CollectionAnyContainmentWhereFragment(_parent._serializer, expression);

_register.Peek()(@where);
Expand Down