@@ -391,3 +391,79 @@ func TestHexadecimalLiteral(t *testing.T) {
391391 }
392392 }
393393}
394+
395+ func TestScannerPoolCleanupAndThreshold (t * testing.T ) {
396+ // Case 1: normal small SQL should be pooled and fields cleared
397+ s := NewScanner (dialect .MYSQL , "select 1" )
398+ // grow strBuilder a little to ensure it is cleared on Put
399+ s .strBuilder .WriteString ("abc" )
400+ PutScanner (s )
401+
402+ // Fetch again to see if we receive a cleared scanner from pool
403+ s2 := NewScanner (dialect .MYSQL , "select 2" )
404+ if s2 .LastToken != "" || s2 .LastError != nil || s2 .MysqlSpecialComment != nil || s2 .Pos != 0 || s2 .Line != 0 || s2 .Col != 0 || s2 .PrePos != 0 {
405+ t .Fatalf ("pooled scanner should be reset: %+v" , s2 )
406+ }
407+ if s2 .strBuilder .Len () != 0 {
408+ t .Fatalf ("strBuilder should be cleared" )
409+ }
410+ PutScanner (s2 )
411+
412+ // Case 2: big SQL (>1MiB) should NOT be pooled
413+ big := make ([]byte , (1 << 20 )+ 10 )
414+ for i := range big {
415+ big [i ] = 'a'
416+ }
417+ sbig := NewScanner (dialect .MYSQL , string (big ))
418+ // also grow internal builder to simulate expansion
419+ sbig .strBuilder .Grow (1 << 20 )
420+ PutScanner (sbig )
421+
422+ // Next Get should not necessarily return the same oversized instance; at least, it must be a clean one
423+ s3 := NewScanner (dialect .MYSQL , "select 3" )
424+ if s3 .buf != "select 3" {
425+ t .Fatalf ("unexpected scanner buf after Get" )
426+ }
427+ PutScanner (s3 )
428+ }
429+
430+ func TestPutScannerSmallKeepsBuffers (t * testing.T ) {
431+ // Small SQL should keep buf and builder content when returned to pool
432+ sql := "select 1"
433+ s := NewScanner (dialect .MYSQL , sql )
434+ s .strBuilder .WriteString ("xyz" )
435+ PutScanner (s )
436+
437+ if s .buf == "" {
438+ t .Fatalf ("small scanner buf should not be cleared on PutScanner" )
439+ }
440+ if s .strBuilder .Len () == 0 {
441+ t .Fatalf ("small scanner strBuilder should retain content on PutScanner" )
442+ }
443+
444+ // When taking from pool next time, setSql will Reset the builder length
445+ s2 := NewScanner (dialect .MYSQL , "select 2" )
446+ if s2 .strBuilder .Len () != 0 {
447+ t .Fatalf ("builder length must be reset on setSql" )
448+ }
449+ PutScanner (s2 )
450+ }
451+
452+ func TestPutScannerOversizedClearsBuffers (t * testing.T ) {
453+ // Big SQL should be cleared and dropped
454+ big := make ([]byte , (1 << 20 )+ 123 )
455+ for i := range big {
456+ big [i ] = 'b'
457+ }
458+ s := NewScanner (dialect .MYSQL , string (big ))
459+ s .strBuilder .Grow (1 << 20 )
460+ s .strBuilder .WriteString ("payload" )
461+ PutScanner (s )
462+
463+ if s .buf != "" {
464+ t .Fatalf ("oversized scanner buf should be cleared on PutScanner" )
465+ }
466+ if s .strBuilder .Len () != 0 {
467+ t .Fatalf ("oversized scanner strBuilder should be zeroed on PutScanner" )
468+ }
469+ }
0 commit comments