Both tests at the end crash the request. Haven't tested ContainsAll.
On 3.0.30143 it crashes with something similar to:
Url: "/indexes/Index?&query=%28IsDeleted%3Afalse%29%20AND%20%28%20%40in%3C__document_id%3E%3A%28users%2F42%29%20%20OR%20%29&pageSize=128&SortHint-IsDeleted=String"
Lucene.Net.QueryParsers.ParseException: Could not parse: '(IsDeleted:false) AND ( @in<__document_id>:(users/42) OR )' ---> Lucene.Net.QueryParsers.ParseException: Cannot parse '(IsDeleted:false) AND ( @in<__document_id>:(users/42) OR )': Encountered " ")" ") "" at line 1, column 58.
On 3.5.0-rc-35161 it crashes with:
Url: "/indexes/Index?&query=%28IsDeleted%3Afalse%29%20AND%20%28%20%20OR%20%40in%3C__document_id%3E%3A%28users%2F42%29%20%29&pageSize=128&SortHint-IsDeleted=String"
Lucene.Net.QueryParsers.ParseException: Could not parse: '(IsDeleted:false) AND ( OR @in<__document_id>:(users/42) )' ---> Lucene.Net.QueryParsers.ParseException: Syntax error, unexpected OR
This is because enumerable.ContainsAny(x) generates an empty clause, which is an issue when it's part of an ||.
It's not a major issue (I can work around it by checking the array before the condition), but it can surprise someone who's not expecting it.
Code:
public class Class1 : RavenTestBase
{
[Fact]
public void WhenArgumentForContainsAnyIsEmptyAndIsFirstArgumentOfOr_DoesNotProduceEmptyClause()
{
var store = NewDocumentStore();
new Index().Execute(store);
using (var session = store.OpenSession())
{
IEnumerable<string> rolesToSearch = new string[] {};
IEnumerable<string> userIdsToSearch = new string[] {"users/42"};
session.Query<User, Index>()
.Where(user => !user.IsDeleted)
.Where(user => user.RoleIds.ContainsAny(rolesToSearch) ||
user.Id.In(userIdsToSearch))
.ToList();
}
}
[Fact]
public void WhenArgumentForContainsAnyIsEmptyAndIsLastArgumentOfOr_DoesNotProduceEmptyClause()
{
var store = NewDocumentStore();
new Index().Execute(store);
using (var session = store.OpenSession())
{
IEnumerable<string> rolesToSearch = new string[] {};
IEnumerable<string> userIdsToSearch = new string[] {"users/42"};
session.Query<User, Index>()
.Where(user => !user.IsDeleted)
.Where(user =>
user.Id.In(userIdsToSearch) || user.RoleIds.ContainsAny(rolesToSearch))
.ToList();
}
}
class User
{
public string Id { get; set; }
public string UserName { get; set; }
public string[] RoleIds { get; set; }
public bool IsDeleted { get; set; }
}
class Index : AbstractIndexCreationTask<User>
{
public Index()
{
Map = users => from user in users
select new
{
user.UserName,
user.RoleIds,
user.IsDeleted
};
}
}