@@ -78,13 +78,39 @@ TEST_CASE("NextDesiredBatchSize doubles geometrically while keeping ROWSKIPS val
7878 REQUIRE (size == SM ::MAX_BATCH_SIZE );
7979}
8080
81+ TEST_CASE (" A single-column scan honours a small budget instead of ignoring it" ,
82+ " [erpl_rfc][batching]" ) {
83+ using SM = RfcReadColumnStateMachine;
84+
85+ // ResolveEffectiveMaxBatchSize divides the budget across partition workers so that
86+ // peak memory does not scale with the worker count. A single-column scan used to
87+ // short-circuit to MAX_BATCH_SIZE before the divided budget was ever consulted, so
88+ // every worker asked SAP for ROWCOUNT=32768 no matter what erpl_rfc_fetch_size or
89+ // partitions said -- confirmed on a4h by heaptrack, which showed 32768-row batches
90+ // under partitions=8. Narrow scans are exactly what partitioning is for, so this is
91+ // the case where the budget matters most.
92+ REQUIRE (SM::MaxBatchSizeForColumnCount (1 , 2048 ) == (unsigned int )STANDARD_VECTOR_SIZE );
93+ REQUIRE (SM::MaxBatchSizeForColumnCount (1 , 8192 ) == 8192u );
94+
95+ // The default fetch size (16384 concurrent rows) split across 8 workers.
96+ REQUIRE (SM::MaxBatchSizeForColumnCount (1 , 16384u / 8u ) == (unsigned int )STANDARD_VECTOR_SIZE );
97+
98+ // A budget large enough for the full batch still yields it -- the cap binds, it does
99+ // not shrink for its own sake.
100+ REQUIRE (SM::MaxBatchSizeForColumnCount (1 , 256u * 1024u ) == SM ::MAX_BATCH_SIZE );
101+
102+ // Zero columns still means "no projection to bound"; a zero budget still disables it.
103+ REQUIRE (SM::MaxBatchSizeForColumnCount (0 , 2048 ) == SM ::MAX_BATCH_SIZE );
104+ REQUIRE (SM::MaxBatchSizeForColumnCount (1 , 0 ) == SM ::MAX_BATCH_SIZE );
105+ }
106+
81107TEST_CASE (" MaxBatchSizeForColumnCount bounds the SDK buffer on wide scans" ,
82108 " [erpl_rfc][batching]" ) {
83109 using SM = RfcReadColumnStateMachine;
84110 // Use an explicit budget so the test is independent of the runtime default.
85111 constexpr unsigned int BUDGET = 256u * 1024u ;
86112
87- // Narrow scans keep the full batch for throughput .
113+ // Narrow scans keep the full batch when the budget is large enough to allow it .
88114 REQUIRE (SM::MaxBatchSizeForColumnCount (0 , BUDGET ) == SM ::MAX_BATCH_SIZE );
89115 REQUIRE (SM::MaxBatchSizeForColumnCount (1 , BUDGET ) == SM ::MAX_BATCH_SIZE );
90116 REQUIRE (SM::MaxBatchSizeForColumnCount (2 , BUDGET ) == SM ::MAX_BATCH_SIZE );
0 commit comments