I have a CBL query that uses ArrayExpressions. It worked perfectly in 2.1.5, but fails with “datatype mismatch” in 2.5.
All of my local documents have a channels array (“channels”). In the code below, I have a separate array containing a set of channel names I’m looking for (“hunt_channels”). I want to find any documents where any entry from the channel array matches any entry from the hunt_channels list, and return a list of their IDs.
So if hunt_channels = [“a”, “b”, “c”]
and my documents are:
doc1: { channels: [“d”], …}
doc2: { channels: [“b”, “e”], …}
doc3: { channels: [“a”], …}
the search should return doc2, doc3.
I was guided in the creation of this code by this excellent document on ArrayExpressions:
The code works like this:
We create an array of IExpressions containing the channel values I am looking for (channel_list).
Then we create a variable to represent each element of the channels for each document (channel_variable).
And we look for documents that satisfy channel_variable in channel_list.
This works well and is fast in CBL 2.1.5.
This generates a “datatype mismatch” exception in CBL2.5. I’ve included the exception details at the bottom.
Have I done something stupid?
Here is the code:
public List<string> ListDocumentsWithChannelAccess(List<string> hunt_channels)
{
List<string> ids = new List<string>();
try
{
var channel_variable = ArrayExpression.Variable("the_channel");
IExpression[] channel_list = new IExpression[hunt_channels.Count];
for (var i = 0; i < hunt_channels.Count; i++)
channel_list[i] = Expression.String(hunt_channels[i]);
var query = QueryBuilder.Select(SelectResult.Expression(Meta.ID))
.From(DataSource.Database(database))
.Where(ArrayExpression.Any(channel_variable)
.In(Expression.Property("channels"))
.Satisfies(channel_variable.In(channel_list)));
foreach (var result in query.Execute())
{
var id = result.GetString("id");
ids.Add(id);
}
}
catch (Exception e)
{
log.Error(e, "Failure in listing documents");
}
return ids;
}
It fails with the exception at the query.Execute()
.
The exception details are:
Couchbase.Lite.CouchbaseSQLiteException: CouchbaseLiteException (SQLiteDomain / 20): datatype mismatch.
at LiteCore.Interop.NativeHandler.ThrowOrHandle () [0x00089] in C:\Jenkins\workspace\couchbase-lite-net-edition-build\couchbase-lite-net-ee\couchbase-lite-net\src\LiteCore\src\LiteCore.Shared\Interop\NativeHandler.cs:257
at LiteCore.Interop.NativeHandler.Execute (LiteCore.Interop.C4TryLogicDelegate2 block) [0x0002c] in C:\Jenkins\workspace\couchbase-lite-net-edition-build\couchbase-lite-net-ee\couchbase-lite-net\src\LiteCore\src\LiteCore.Shared\Interop\NativeHandler.cs:203
at LiteCore.LiteCoreBridge.Check (LiteCore.Interop.C4TryLogicDelegate2 block) [0x00000] in C:\Jenkins\workspace\couchbase-lite-net-edition-build\couchbase-lite-net-ee\couchbase-lite-net\src\LiteCore\src\LiteCore.Shared\Interop\LiteCoreBridge.cs:57
at Couchbase.Lite.Support.ThreadSafety.DoLockedBridge (LiteCore.Interop.C4TryLogicDelegate2 a) [0x00011] in C:\Jenkins\workspace\couchbase-lite-net-edition-build\couchbase-lite-net-ee\couchbase-lite-net\src\Couchbase.Lite.Shared\Support\ThreadSafety.cs:72
at Couchbase.Lite.Internal.Query.XQuery.Execute () [0x00059] in C:\Jenkins\workspace\couchbase-lite-net-edition-build\couchbase-lite-net-ee\couchbase-lite-net\src\Couchbase.Lite.Shared\Query\XQuery.cs:417
at CoreLibrary.DB.ListDocumentsWithChannelAccess (System.Collections.Generic.List`1[T] channels) [0x000c2] in /Users/Paul/Dev/CoreLibrary/DB.cs:971
Side Note: the original reason for this code is that prior to 2.5, you had to manually remove local documents if you lost access to their channel from the server end (i.e. your list of accessible channels changed at the server). This code looks for docs I no longer have access to so I can manually remove them, and I run it when I notice any channel access changes.
In 2.5, one of the awesome new features is “Automatic purge of removed documents”. In theory I shouldn’t need this function going forward. Sadly, for some reason, local docs that I no longer have access to are not being removed. However I haven’t tracked that down yet so am loathe to report a bug until I’m sure.