From 2d5e947ef7273032bf0b779265d6996de0402c69 Mon Sep 17 00:00:00 2001 From: Thomas Vincent Date: Sat, 7 Nov 2026 20:29:55 -0800 Subject: [PATCH 1/2] Fix FlowView time range overlap filtering Signed-off-by: Thomas Vincent --- CHANGELOG.md | 1 + includes/functions.php | 4 +--- tests/Unit/QueryBuilderTest.php | 14 ++++++-------- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 954159d7..073867bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ --- develop --- +* issue#306: Include flows spanning the entire report time window * dev: Run the CI poller with the shared runner group so RRD files and structured directories pass permission verification * issue: Remove the Listener and Stream from the report page. They are part of what a Filter materializes, so changing them there ran the report against data that was never materialized. They are now set only in the Filter editor, and the report page reads them straight from the saved Filter. The New button now follows Edit. diff --git a/includes/functions.php b/includes/functions.php index 40d4cb55..4b5cb1fb 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -2708,12 +2708,10 @@ function get_date_filter($sql_range, &$sql_range_params, $start, $end, int $rang switch($range_type) { case 1: // Any part in specified time span - $sql_range = '(`start_time` BETWEEN ? AND ? OR `end_time` BETWEEN ? AND ?)'; + $sql_range = '(`start_time` <= ? AND `end_time` >= ?)'; - $sql_range_params[] = $date1; $sql_range_params[] = $date2; $sql_range_params[] = $date1; - $sql_range_params[] = $date2; break; case 2: // End Time in Specified Time Span diff --git a/tests/Unit/QueryBuilderTest.php b/tests/Unit/QueryBuilderTest.php index 59145707..25b4cf2c 100644 --- a/tests/Unit/QueryBuilderTest.php +++ b/tests/Unit/QueryBuilderTest.php @@ -71,17 +71,15 @@ expect($params)->toBe(array(16, '2001:db8::', '2001:db8::ffff:ffff:ffff:ffff')); }); -it('builds each supported temporal overlap contract', function ($rangeType, $expectedSql, $expectedCount) { +it('builds each supported temporal filter contract', function ($rangeType, $expectedSql, $expectedParams) { $params = array(); $sql = get_date_filter('', $params, 1704067200, 1704070800, $rangeType); expect($sql)->toBe($expectedSql) - ->and($params)->toHaveCount($expectedCount) - ->and($params[0])->toBe('2024-01-01 00:00:00') - ->and($params[1])->toBe('2024-01-01 01:00:00'); + ->and($params)->toBe($expectedParams); })->with(array( - array(1, '(`start_time` BETWEEN ? AND ? OR `end_time` BETWEEN ? AND ?)', 4), - array(2, '(`end_time` BETWEEN ? AND ?)', 2), - array(3, '(`start_time` BETWEEN ? AND ?)', 2), - array(4, '(`start_time` BETWEEN ? AND ? AND `end_time` BETWEEN ? AND ?)', 4), + array(1, '(`start_time` <= ? AND `end_time` >= ?)', array('2024-01-01 01:00:00', '2024-01-01 00:00:00')), + array(2, '(`end_time` BETWEEN ? AND ?)', array('2024-01-01 00:00:00', '2024-01-01 01:00:00')), + array(3, '(`start_time` BETWEEN ? AND ?)', array('2024-01-01 00:00:00', '2024-01-01 01:00:00')), + array(4, '(`start_time` BETWEEN ? AND ? AND `end_time` BETWEEN ? AND ?)', array('2024-01-01 00:00:00', '2024-01-01 01:00:00', '2024-01-01 00:00:00', '2024-01-01 01:00:00')), )); From 0fa09b22c7784c0b403950b7c9a725c626c014ac Mon Sep 17 00:00:00 2001 From: Thomas Vincent Date: Sun, 8 Nov 2026 01:46:09 -0800 Subject: [PATCH 2/2] fix: keep stored FlowView range params ordered start then end The run statistics read map_range_params[0] and [1] as the window start and end for the shard cache lookup. Binding the overlap predicate as (end, start) turned that lookup into BETWEEN end AND start, so the cached size for default-range queries was always 0. Write the overlap test as end_time >= start AND start_time <= end so the params keep the same order as every other range type. Narrow the changelog entry: flows are still read only from the partitions inside the report window. Signed-off-by: Thomas Vincent --- CHANGELOG.md | 2 +- includes/functions.php | 6 ++++-- tests/Unit/QueryBuilderTest.php | 11 ++++++++++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 073867bf..9a3c1344 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ --- develop --- -* issue#306: Include flows spanning the entire report time window +* issue#306: Match flows that start before and end after the report time window; flows are still read only from the partitions inside that window * dev: Run the CI poller with the shared runner group so RRD files and structured directories pass permission verification * issue: Remove the Listener and Stream from the report page. They are part of what a Filter materializes, so changing them there ran the report against data that was never materialized. They are now set only in the Filter editor, and the report page reads them straight from the saved Filter. The New button now follows Edit. diff --git a/includes/functions.php b/includes/functions.php index 4b5cb1fb..55b01f41 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -2708,10 +2708,12 @@ function get_date_filter($sql_range, &$sql_range_params, $start, $end, int $rang switch($range_type) { case 1: // Any part in specified time span - $sql_range = '(`start_time` <= ? AND `end_time` >= ?)'; + // Bind the window start first: the run statistics read the stored + // map_range_params as (start, end) for every range type. + $sql_range = '(`end_time` >= ? AND `start_time` <= ?)'; - $sql_range_params[] = $date2; $sql_range_params[] = $date1; + $sql_range_params[] = $date2; break; case 2: // End Time in Specified Time Span diff --git a/tests/Unit/QueryBuilderTest.php b/tests/Unit/QueryBuilderTest.php index 25b4cf2c..e088ad0c 100644 --- a/tests/Unit/QueryBuilderTest.php +++ b/tests/Unit/QueryBuilderTest.php @@ -78,8 +78,17 @@ expect($sql)->toBe($expectedSql) ->and($params)->toBe($expectedParams); })->with(array( - array(1, '(`start_time` <= ? AND `end_time` >= ?)', array('2024-01-01 01:00:00', '2024-01-01 00:00:00')), + array(1, '(`end_time` >= ? AND `start_time` <= ?)', array('2024-01-01 00:00:00', '2024-01-01 01:00:00')), array(2, '(`end_time` BETWEEN ? AND ?)', array('2024-01-01 00:00:00', '2024-01-01 01:00:00')), array(3, '(`start_time` BETWEEN ? AND ?)', array('2024-01-01 00:00:00', '2024-01-01 01:00:00')), array(4, '(`start_time` BETWEEN ? AND ? AND `end_time` BETWEEN ? AND ?)', array('2024-01-01 00:00:00', '2024-01-01 01:00:00', '2024-01-01 00:00:00', '2024-01-01 01:00:00')), )); + +it('stores every temporal filter with the window start and end first', function ($rangeType) { + // The run statistics query reads map_range_params[0] and [1] as the + // window bounds for the shard cache lookup. + $params = array(); + get_date_filter('', $params, 1704067200, 1704070800, $rangeType); + + expect(array_slice($params, 0, 2))->toBe(array('2024-01-01 00:00:00', '2024-01-01 01:00:00')); +})->with(array(1, 2, 3, 4));