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
42 changes: 42 additions & 0 deletions C/tests/c4QueryTest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,48 @@ N_WAY_TEST_CASE_METHOD(C4QueryTest, "C4Query partial value index", "[Query][C]")
}
}

N_WAY_TEST_CASE_METHOD(C4QueryTest, "C4Query partial value index with compound expressions", "[Query][C]") {
C4Error err;
auto defaultColl = getCollection(db, kC4DefaultCollectionSpec);

// First add some documents with specific fields to test
{
TransactionHelper t(db);
createFleeceRev(db, "compound1"_sl, kRevID,
R"({"locationID": "store1", "status": "active", "isPurged": false})"_sl);
createFleeceRev(db, "compound2"_sl, kRevID,
R"({"locationID": "store2", "status": "inactive", "isPurged": true})"_sl);
createFleeceRev(db, "compound3"_sl, kRevID,
R"({"locationID": "store1", "status": "active", "isPurged": true})"_sl);
}

// Create a partial value index with compound expressions
C4IndexOptions options{};
options.where = R"(["=", [".isPurged"], false])";

// This is what was causing the bug - a value index with multiple expressions and a WHERE clause
REQUIRE(c4coll_createIndex(defaultColl, C4STR("compound_idx"), c4str(R"([".locationID", ".status", ".isPurged"])"),
kC4JSONQuery, kC4ValueIndex, &options, WITH_ERROR(&err)));

// Verify that the index works by running a query that would use it
compileSelect("SELECT META().id FROM _ WHERE locationID = 'store1' AND status = 'active' AND isPurged = false",
kC4N1QLQuery);
REQUIRE(query);
CHECK(run() == (vector<string>{"compound1"}));

// Create another index with N1QL syntax to verify that works too
C4IndexOptions options2{};
options2.where = "isPurged = true";
REQUIRE(c4coll_createIndex(defaultColl, C4STR("compound_idx2"), c4str("locationID, status, isPurged"), kC4N1QLQuery,
kC4ValueIndex, &options2, WITH_ERROR(&err)));

// Verify the second index works
compileSelect("SELECT META().id FROM _ WHERE locationID = 'store1' AND status = 'active' AND isPurged = true",
kC4N1QLQuery);
REQUIRE(query);
CHECK(run() == (vector<string>{"compound3"}));
}

static bool lookForIndex(C4Database* db, slice name) {
bool found = false;
auto defaultColl = C4QueryTest::getCollection(db, kC4DefaultCollectionSpec);
Expand Down
4 changes: 2 additions & 2 deletions LiteCore/Query/IndexSpec.cc
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ namespace litecore {
std::stringstream ss;
if ( canPartialIndex() && !whereClause.empty() ) {
hasWhere = true;
ss << "SELECT ( " << expression.asString() << " ) FROM _ WHERE ( "
<< whereClause.asString() << " )";
ss << "SELECT " << expression.asString() << " FROM _ WHERE ( " << whereClause.asString()
<< " )";
result = n1ql::parse(ss.str(), &errPos);
} else {
result = n1ql::parse(expression.asString(), &errPos);
Expand Down
Loading