Changeset

13847:cbd234461c41 13.0

mod_storage_internal: Fix queries with only start returning extra items Queries with start > last item would return one item, because there's some boundary condition in binary_search(). This is here fixed by always applying filters that omit items outside the requested range. See also 2374c7665d0b
author Kim Alvefur <zash@zash.se>
date Mon, 14 Apr 2025 15:10:29 +0200
parents 13845:2558be2daaca
children 13848:45c508a12865 13849:068e77bf91b9
files plugins/mod_storage_internal.lua spec/core_storagemanager_spec.lua
diffstat 2 files changed, 46 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/plugins/mod_storage_internal.lua	Fri Apr 11 09:45:04 2025 +0200
+++ b/plugins/mod_storage_internal.lua	Mon Apr 14 15:10:29 2025 +0200
@@ -205,12 +205,11 @@
 					return query.start - when;
 				end);
 				i = wi - 1;
-			else
-				iter = it.filter(function(item)
-					local when = item.when or datetime.parse(item.attr.stamp);
-					return when >= query.start;
-				end, iter);
 			end
+			iter = it.filter(function(item)
+				local when = item.when or datetime.parse(item.attr.stamp);
+				return when >= query.start;
+			end, iter);
 		end
 		if query["end"] then
 			if query.reverse then
@@ -221,12 +220,11 @@
 				if wi then
 					i = wi + 1;
 				end
-			else
-				iter = it.filter(function(item)
-					local when = item.when or datetime.parse(item.attr.stamp);
-					return when <= query["end"];
-				end, iter);
 			end
+			iter = it.filter(function(item)
+				local when = item.when or datetime.parse(item.attr.stamp);
+				return when <= query["end"];
+			end, iter);
 		end
 		if query.after then
 			local found = false;
--- a/spec/core_storagemanager_spec.lua	Fri Apr 11 09:45:04 2025 +0200
+++ b/spec/core_storagemanager_spec.lua	Mon Apr 14 15:10:29 2025 +0200
@@ -436,6 +436,44 @@
 						assert.equal(#test_data - 3, count);
 					end);
 
+					it("by time (start before first item)", function ()
+						-- luacheck: ignore 211/err
+						local data, err = archive:find("user", {
+							["start"] = test_time-5;
+						});
+						assert.truthy(data);
+						local count = 0;
+						for id, item, when in data do
+							count = count + 1;
+							assert.truthy(id);
+							assert(st.is_stanza(item));
+							assert.equal("test", item.name);
+							assert.equal("urn:example:foo", item.attr.xmlns);
+							assert.equal(2, #item.tags);
+							assert(when >= test_time-5, ("%d >= %d"):format(when, test_time-5));
+						end
+						assert.equal(#test_data, count);
+					end);
+
+					it("by time (start after last item)", function ()
+						-- luacheck: ignore 211/err
+						local data, err = archive:find("user", {
+							["start"] = test_time+5;
+						});
+						assert.truthy(data);
+						local count = 0;
+						for id, item, when in data do
+							count = count + 1;
+							assert.truthy(id);
+							assert(st.is_stanza(item));
+							assert.equal("test", item.name);
+							assert.equal("urn:example:foo", item.attr.xmlns);
+							assert.equal(2, #item.tags);
+							assert(when >= test_time+5, ("%d >= %d"):format(when, test_time+5));
+						end
+						assert.equal(0, count);
+					end);
+
 					it("by time (start+end)", function ()
 						-- luacheck: ignore 211/err
 						local data, err = archive:find("user", {