diff --git a/CHANGELOG.md b/CHANGELOG.md index 954159d7..9a3c1344 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ --- develop --- +* 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 40d4cb55..55b01f41 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -2708,10 +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 ?)'; + // 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[] = $date1; - $sql_range_params[] = $date2; $sql_range_params[] = $date1; $sql_range_params[] = $date2; diff --git a/tests/Unit/QueryBuilderTest.php b/tests/Unit/QueryBuilderTest.php index 59145707..e088ad0c 100644 --- a/tests/Unit/QueryBuilderTest.php +++ b/tests/Unit/QueryBuilderTest.php @@ -71,17 +71,24 @@ 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, '(`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));