@@ -1466,6 +1466,79 @@ func TestQueryExecutorShouldConsolidate(t *testing.T) {
14661466 }
14671467}
14681468
1469+ func TestQueryExecutorConsolidatorWaiterCapFallback (t * testing.T ) {
1470+ // Test that when the consolidator waiter cap is reached, queries fall back
1471+ // to independent execution instead of returning empty results.
1472+
1473+ db := setUpQueryExecutorTest (t )
1474+ defer db .Close ()
1475+
1476+ ctx := context .Background ()
1477+ tsv := newTestTabletServer (ctx , enableConsolidator , db )
1478+ defer tsv .StopService ()
1479+
1480+ // Set a waiter cap of 1
1481+ tsv .config .ConsolidatorQueryWaiterCap = 1
1482+
1483+ fakeConsolidator := sync2 .NewFakeConsolidator ()
1484+ tsv .qe .consolidator = fakeConsolidator
1485+
1486+ input := "select * from t limit 10001"
1487+ result := & sqltypes.Result {
1488+ Fields : getTestTableFields (),
1489+ Rows : [][]sqltypes.Value {{
1490+ sqltypes .NewInt32 (1 ), // pk
1491+ sqltypes .NewInt32 (100 ), // name
1492+ sqltypes .NewInt32 (200 ), // addr
1493+ }},
1494+ }
1495+
1496+ // Set up consolidator to simulate an identical query already running (Created=false)
1497+ fakePendingResult := & sync2.FakePendingResult {}
1498+ fakePendingResult .SetResult (result )
1499+ // Start with waiter count above the cap (2 > 1), so the condition fails
1500+ fakePendingResult .WaiterCount = 2
1501+
1502+ fakeConsolidator .CreateReturn = & sync2.FakeConsolidatorCreateReturn {
1503+ Created : false , // Simulate identical query already running
1504+ PendingResult : fakePendingResult ,
1505+ }
1506+
1507+ // Set up database query/response for fallback execution
1508+ db .AddQuery (input , result )
1509+
1510+ qre := newTestQueryExecutor (context .Background (), tsv , input , 0 )
1511+ qre .options = & querypb.ExecuteOptions {Consolidator : querypb .ExecuteOptions_CONSOLIDATOR_ENABLED }
1512+
1513+ // Execute query
1514+ actualResult , err := qre .Execute ()
1515+ require .NoError (t , err )
1516+ require .NotNil (t , actualResult )
1517+
1518+ // Verify we got the correct result (not empty)
1519+ require .Equal (t , result .Fields , actualResult .Fields )
1520+ require .Equal (t , result .Rows , actualResult .Rows )
1521+
1522+ // Verify consolidator was attempted
1523+ require .Len (t , fakeConsolidator .CreateCalls , 1 )
1524+
1525+ // Verify we did NOT wait (because waiter cap was exceeded)
1526+ require .Equal (t , 0 , fakePendingResult .WaitCalls )
1527+
1528+ // Verify we did NOT broadcast (because we're not the original)
1529+ require .Equal (t , 0 , fakePendingResult .BroadcastCalls )
1530+
1531+ // Verify AddWaiterCounter was called: once with 0 (to check count), once with -1 (cleanup)
1532+ require .Len (t , fakePendingResult .AddWaiterCounterCalls , 2 )
1533+ require .Equal (t , int64 (0 ), fakePendingResult .AddWaiterCounterCalls [0 ]) // Check current count
1534+ require .Equal (t , int64 (- 1 ), fakePendingResult .AddWaiterCounterCalls [1 ]) // Decrement
1535+
1536+ // Verify fallback executed the query independently
1537+ require .Equal (t , 1 , db .GetQueryCalledNum (input ))
1538+
1539+ db .VerifyAllExecutedOrFail ()
1540+ }
1541+
14691542func TestGetConnectionLogStats (t * testing.T ) {
14701543 db := setUpQueryExecutorTest (t )
14711544 defer db .Close ()
0 commit comments