Couchbase Lite C: assertion error when querying fields that are missing from documents

I have two documents in my test database:

{“name”: “Rudolf”}
{“name”: “Rudolf”, “email”: “”}

This is the query I’m trying to run:

SELECT name, email where name ="Rudolf"

I get this error and the app crashes.

4:11:00.949073| [Query]: {Query#9} Compiling N1QL query: SELECT name, email where name =“Rudolf”
04:11:00.950533| [Query]: {QueryEnum#10}==> class litecore::SQLiteQueryEnumerator 000001DA72455E40 @000001DA72455E40
04:11:00.950977| [Query]: {QueryEnum#10} Created on {Query#7} with 2 rows (44 bytes) in 0.324ms
04:11:00.951288| [Query]: {Query#9} Compiled as SELECT fl_result(fl_value(_doc.body, ‘name’)), fl_result(fl_value(_doc.body, ‘email’)) FROM kv_default AS _doc WHERE (fl_value(_doc.body, ‘name’) = ‘Rudolf’) AND (_doc.flags & 1 = 0)
FAILED ASSERTION n == 2*_count in class fleece::impl::internal::HeapArray *__cdecl fleece::impl::internal::HeapDict::kvArray(void) (at line 216)
04:11:00.952932| [Query]: {QueryEnum#11}==> class litecore::SQLiteQueryEnumerator 000001DA72455F20 @000001DA72455F20
04:11:00.953306| [Query]: {QueryEnum#11} Created on {Query#9} with 2 rows (44 bytes) in 0.292ms
04:11:00.953700| [Query]: {LiveQuerier#8} Results changed at seq 32 (5.165ms)
Lost connection to device.

These queries work as expected, the error seems to happen only if some of the documents are missing some of the fields.

SELECT name WHERE name =“Rudolf”
SELECT * WHERE name =“Rudolf”

Hey @Rudolf_Martincsek: what version of CBL-C are you using?

This is the revision I’m using to build the library.

I’m using ‘CBLResultSet_RowDict(results);’ to retrieve the results, if it matters.

    final rows = [];
    while (CBLResultSet_Next(results) != 0) {
      final row = CBLResultSet_RowDict(results);
      final json = FLDict.fromPointer(row).json;

I’m writing a Dart/Flutter package which is almost complete, except I haven’t implemented the CBLQuery_ColumnCount, CBLQuery_ColumnName and the various CBLResultSet_Value… methods. Maybe I should, because probably I could parse the results with those.
It would be nice if CBLResultSet_RowDict() could handle results with variable fields, though.

That’s definitely a bug, of course. Could you file an issue in the Github repo, please? And if it’s possible to get a backtrace of the exception (i.e. set a breakpoint on throw), that would be great.

I went digging and in fact is in the CBLResultSet._asDict method setting a value as null if a colum is missing.

Doing a null check fixes the bug, for example:

       for (unsigned i = 0; i < nCols; ++i) {
          Value val = column(i);
          if (val) {
             slice key = _query->columnName(i);
             dict[key] = val;

Edit: I’m not familiar with C, I wonder if this would remove “empty” values too?
Edit2: Nope, 0, false and empty string seem to be treated fine :slight_smile: