Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot get result using CBLQueryBuilder with NSSortDescriptor #857

Closed
ufosky opened this issue Aug 11, 2015 · 4 comments
Closed

Cannot get result using CBLQueryBuilder with NSSortDescriptor #857

ufosky opened this issue Aug 11, 2015 · 4 comments
Assignees
Milestone

Comments

@ufosky
Copy link
Contributor

ufosky commented Aug 11, 2015

I write this test case in file QueryBuilder_Tests.m for reappearing my issue:

- (void)testSort {
  [db inTransaction:^BOOL{
    for (unsigned i=0; i<100; i++) {
      @autoreleasepool {
        NSDictionary* properties = @{@"name": [NSString stringWithFormat:@"%d", i*773%100], @"uid": @(i), @"model_type":@"member"};
        [self createDocumentWithProperties: properties];
      }
    }
    return YES;
  }];
  NSMutableArray *predicates = [[NSMutableArray alloc] init];
  NSString *where = [NSString stringWithFormat:@"%@=='%@'", @"model_type", @"member"];
  NSPredicate *typePredicate = [NSPredicate predicateWithFormat:where];
  [predicates addObject:typePredicate];
  NSPredicate *idsPredicate = [NSPredicate predicateWithFormat:@"uid in $uids"];
  [predicates addObject:idsPredicate];
  NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:predicates];
  NSError *error = nil;
  NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
  CBLQueryBuilder* b = [[CBLQueryBuilder alloc] initWithDatabase: db
                                                          select: nil
                                                  wherePredicate:predicate
                                                         orderBy: @[sort]
                                                           error: &error];
  Assert(b, @"Failed to build: %@", error);
  Log(@"%@", b.explanation);
  NSArray *uids = @[@(7), @(13), @(67), @(88), @(56)];
  NSDictionary *context = @{@"uids":uids};
  CBLQueryEnumerator *e = [b runQueryWithContext:context error:&error];
  Assert(e.count == uids.count, @"Query failed: %@", error);
  for (CBLQueryRow* row in e) {
    Log(@"%@",row.document.properties);
  }
}
@ufosky
Copy link
Contributor Author

ufosky commented Aug 12, 2015

When I don't pass nil for the param orderBy,the result is correct,and the log for explanation print this:

// view "builder-vzfjWFAKeE8u9aIQf6/TRj7lDz0=":
view.map = {
    if (model_type == "member")
        emit(uid, (null));
};
query.keys = $uids;

but when I pass @[sort] as param,the result is wrong with error is nil,and the log for explanation print this:

// view "builder-FlU0gOZU+ubVRgTwuNmHYayqIBc=":
view.map = {
    if (model_type == "member")
        emit([uid, name], (null));
};
query.keys = $uids;

@pasin
Copy link
Contributor

pasin commented Aug 12, 2015

Thanks for reporting. I think this is a bug in the query builder. When the sort is used, the composite key [uid, name] is emitted but the query keys is non composite keys.

@snej
Copy link
Contributor

snej commented Aug 12, 2015

Yes, the bug is that the builder tries to do the sort at index time by adding the sort key to the emitted key, but that's not compatible with using an IN test in the predicate, because that requires exact key equality.

I've fixed the builder code to leave the emitted key alone if the predicate uses IN. Thanks a lot for providing a unit test! That made this a lot easier to debug and verify. I'm checking in in a modified version of the test.

@snej snej closed this as completed in b8556fa Aug 12, 2015
@snej
Copy link
Contributor

snej commented Aug 12, 2015

The best workaround I can think of is to leave out the sort descriptor in the query builder, and then sort the returned rows yourself. For example you can do [e.allObjects sortedArrayUsingDescriptors: ...]. This is basically what the query builder would be doing anyway.

@snej snej added this to the 1.2 milestone Aug 12, 2015
@snej snej self-assigned this Aug 12, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants