commit 0ade5f71d24f9290d056d0924527fdae45a853c7
parent 1de48346a94b188deadd5de29ffdd9a52652f052
Author: Christian Grothoff <christian@grothoff.org>
Date: Thu, 6 Aug 2026 00:10:42 +0200
fix statistics selection when slug is registered for both types
Diffstat:
2 files changed, 54 insertions(+), 2 deletions(-)
diff --git a/src/backenddb/pg_statistics_helpers.sql b/src/backenddb/pg_statistics_helpers.sql
@@ -30,7 +30,8 @@ DECLARE
my_curs CURSOR (arg_slug TEXT)
FOR SELECT UNNEST(ranges)
FROM merchant_statistic_bucket_meta
- WHERE slug=arg_slug;
+ WHERE slug=arg_slug
+ AND stype='number'; -- a slug may be registered for both types
BEGIN
SELECT bmeta_serial_id
INTO my_meta
@@ -89,7 +90,8 @@ DECLARE
my_curs CURSOR (arg_slug TEXT)
FOR SELECT UNNEST(ranges)
FROM merchant_statistic_bucket_meta
- WHERE slug=arg_slug;
+ WHERE slug=arg_slug
+ AND stype='amount'; -- a slug may be registered for both types
BEGIN
SELECT bmeta_serial_id
INTO my_meta
diff --git a/src/backenddb/test_merchantdb.c b/src/backenddb/test_merchantdb.c
@@ -10085,6 +10085,55 @@ test_statistics_amount_slug_collected (const struct InstanceData *instance,
/**
+ * Tests that bumping a statistic only uses the bucket ranges of the
+ * registration with the matching type. Regression test: the cursor
+ * over the ranges did not filter on the type, so a slug registered
+ * both as a number and as an amount statistic got buckets for the
+ * union of both range sets.
+ *
+ * @param instance the instance to collect statistics for.
+ * @return 0 on success, 1 otherwise.
+ */
+static int
+test_statistics_dual_type_slug (const struct InstanceData *instance)
+{
+ unsigned int count;
+
+ TEST_SET_INSTANCE (instance->instance.id,
+ GNUNET_DB_STATUS_SUCCESS_ONE_RESULT);
+ TEST_RET_ON_FAIL (statistics_exec_sql (
+ "INSERT INTO merchant_statistic_bucket_meta"
+ " (slug"
+ " ,description"
+ " ,stype"
+ " ,ranges"
+ " ,ages)"
+ " VALUES"
+ " ('test-dual-type'"
+ " ,'registered as a number statistic'"
+ " ,'number'"
+ " ,ARRAY['hour'::merchant.statistic_range]"
+ " ,ARRAY[72])"
+ " ,('test-dual-type'"
+ " ,'registered as an amount statistic'"
+ " ,'amount'"
+ " ,ARRAY['day'::merchant.statistic_range,'week','month']"
+ " ,ARRAY[14,12,24])"));
+ TEST_RET_ON_FAIL (statistics_exec_sql (
+ "CALL merchant_do_bump_number_stat"
+ " ('test-dual-type'"
+ " ,CURRENT_TIMESTAMP(0)::TIMESTAMP"
+ " ,1)"));
+ TEST_RET_ON_FAIL (count_bucket_counters (instance,
+ "test-dual-type",
+ &count));
+ TEST_COND_RET_ON_FAIL (1 == count,
+ "Bump used the ranges of the wrong registration\n");
+ return 0;
+}
+
+
+/**
* Determines how many interval events are stored for @a slug.
*
* @param instance the instance to look at.
@@ -10251,6 +10300,7 @@ run_test_statistics (struct TestStatistics_Closure *cls)
&cls->instance,
"deposits-fees-paid"));
TEST_RET_ON_FAIL (test_statistics_counter_gc_delimiter (&cls->instance));
+ TEST_RET_ON_FAIL (test_statistics_dual_type_slug (&cls->instance));
return 0;
}