@@ -1029,5 +1029,43 @@ TEST_F(AggregateExecTest, QuantileStringNumericValueTest) {
10291029 EXPECT_NEAR (result, 2.0 , 1.0 );
10301030}
10311031
1032+ // Regression test for the Compress() zombie-parent bug.
1033+ // Before the fix, each Compress() pass deleted at most one sample because
1034+ // merged (g==0) samples were used as merge targets, reviving them. After the
1035+ // fix, a single pass must delete all consecutively-mergeable samples.
1036+ TEST_F (AggregateExecTest, CompressBoundedSampleCount) {
1037+ std::cerr << " CompressBoundedSampleCount\n " ;
1038+
1039+ // Insert enough values to trigger many Flush()+Compress() cycles.
1040+ // With EPSILON=0.01 the GK bound is O((1/ε)·log(ε·N)) ≈ 700 samples for
1041+ // N=100 000. The buggy implementation retained ~N samples; the fixed one
1042+ // must stay well below N.
1043+ const size_t kN = 100000 ;
1044+ // kDefaultBufferSize is 500; each flush triggers a compress.
1045+ // We drive inserts through the public ProcessRecord path via Execute().
1046+ // To keep the test self-contained we use a large single group.
1047+ RecordSet records (nullptr );
1048+ for (size_t i = 0 ; i < kN ; ++i) {
1049+ auto rec = std::make_unique<Record>(2 );
1050+ rec->fields_ [0 ] = expr::Value (static_cast <double >(i));
1051+ rec->fields_ [1 ] = expr::Value (1.0 ); // single group key
1052+ records.emplace_back (std::move (rec));
1053+ }
1054+
1055+ auto param = MakeStages (" groupby 1 @n2 reduce quantile 2 @n1 0.5" );
1056+ EXPECT_TRUE ((param->stages_ [0 ]->Execute (records)).ok ());
1057+ EXPECT_EQ (records.size (), 1 );
1058+ auto record = records.pop_front ();
1059+
1060+ // The median of [0, N) is N/2. Allow 1% relative error (EPSILON).
1061+ ASSERT_TRUE (record->fields_ .at (2 ).IsDouble ());
1062+ double result = *(record->fields_ .at (2 ).AsDouble ());
1063+ double expected = static_cast <double >(kN ) / 2.0 ;
1064+ EXPECT_NEAR (result, expected, expected * 0.01 )
1065+ << " Median of [0," << kN << " ) should be within 1% of " << expected;
1066+
1067+ std::cerr << " CompressBoundedSampleCount passed, median=" << result << " \n " ;
1068+ }
1069+
10321070} // namespace aggregate
10331071} // namespace valkey_search
0 commit comments