Просмотр исходного кода

fix(query): matchesFilters handles system fields (_id, _version, _created_at, _updated_at)

The sort path at line ~847 already special-cases DB-system fields (they
live on the Document struct, not inside doc.data). The filter path was
still reading through getJsonPath, which returns nullopt for system
fields — so sorting by _created_at worked but filtering by it always
matched zero rows.

Consequence: cursor-based pagination silently breaks — a query like
"_created_at < last_seen ORDER BY _created_at" returns empty because
the filter runs before the sort and filters everything out.

Also adds _version support (sort path doesn't have it, but it's cheap
and enables useful queries like "docs modified at least N times").

No behavior change for queries that don't filter on system fields.

Bumps VERSION to 1.6.3.
fszontagh 3 месяцев назад
Родитель
Сommit
174d5c22d3
2 измененных файлов с 18 добавлено и 2 удалено
  1. 1 1
      VERSION
  2. 17 1
      service/src/memory_store.cpp

+ 1 - 1
VERSION

@@ -1 +1 @@
-1.6.2
+1.6.3

+ 17 - 1
service/src/memory_store.cpp

@@ -1977,7 +1977,23 @@ uint64_t MemoryStore::currentTimeFor(const std::string& collection) const {
 
 bool MemoryStore::matchesFilters(const Document& doc, const std::vector<Filter>& filters) const {
     for (const auto& filter : filters) {
-        auto value = getJsonPath(doc.data, filter.field);
+        // DB-system fields live on the Document protobuf, not inside doc.data.
+        // The sort path already special-cases them (see line ~847); the filter
+        // path needs the same treatment, otherwise clients can sort by
+        // `_created_at` but never filter by it (cursor-based pagination
+        // breaks — every `_created_at < X` probe returns empty).
+        std::optional<nlohmann::json> value;
+        if (filter.field == "_created_at") {
+            value = nlohmann::json(doc.createdAt);
+        } else if (filter.field == "_updated_at") {
+            value = nlohmann::json(doc.updatedAt);
+        } else if (filter.field == "_id") {
+            value = nlohmann::json(doc.id);
+        } else if (filter.field == "_version") {
+            value = nlohmann::json(doc.version);
+        } else {
+            value = getJsonPath(doc.data, filter.field);
+        }
 
         switch (filter.op) {
             case FilterOp::EXISTS: