Skip to content

Commit db57765

Browse files
fix: GO n prints cumulative stats instead of n separate blocks
1 parent d81f3fb commit db57765

3 files changed

Lines changed: 30 additions & 22 deletions

File tree

pkg/sqlcmd/commands.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,9 @@ func exitCommand(s *Sqlcmd, args []string, line uint) error {
249249

250250
if len(query1) > 0 || len(query2) > 0 {
251251
query := query1 + SqlcmdEol + query2
252-
s.Exitcode, _ = s.runQuery(query)
252+
var elapsedMs int64
253+
s.Exitcode, elapsedMs, _ = s.runQuery(query)
254+
s.printStatistics(elapsedMs, 1, s.GetOutput())
253255
}
254256
return ErrExitRequested
255257
}
@@ -290,12 +292,16 @@ func goCommand(s *Sqlcmd, args []string, line uint) error {
290292
return nil
291293
}
292294
query = s.getRunnableQuery(query)
295+
var totalElapsedMs int64
293296
for i := 0; i < n; i++ {
294-
if retcode, err := s.runQuery(query); err != nil {
297+
retcode, elapsedMs, err := s.runQuery(query)
298+
totalElapsedMs += elapsedMs
299+
if err != nil {
295300
s.Exitcode = retcode
296301
return err
297302
}
298303
}
304+
s.printStatistics(totalElapsedMs, n, s.GetOutput())
299305
s.batch.Reset(nil)
300306
return nil
301307
}

pkg/sqlcmd/sqlcmd.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -416,13 +416,14 @@ func (s *Sqlcmd) getRunnableQuery(q string) string {
416416
return b.String()
417417
}
418418

419-
// runQuery runs the query and prints the results
420-
// The return value is based on the first cell of the last column of the last result set.
419+
// runQuery runs the query and prints the results.
420+
// Returns (exitcode, elapsedMs, error).
421+
// The exitcode is based on the first cell of the last column of the last result set.
421422
// If it's numeric, it will be converted to int
422423
// -100 : Error encountered prior to selecting return value
423424
// -101: No rows found
424425
// -102: Conversion error occurred when selecting return value
425-
func (s *Sqlcmd) runQuery(query string) (int, error) {
426+
func (s *Sqlcmd) runQuery(query string) (int, int64, error) {
426427
retcode := -101
427428
startTime := time.Now()
428429
s.Format.BeginBatch(query, s.vars, s.GetOutput(), s.GetError())
@@ -513,8 +514,7 @@ func (s *Sqlcmd) runQuery(query string) (int, error) {
513514
}
514515
s.Format.EndBatch()
515516
elapsedMs := time.Since(startTime).Milliseconds()
516-
s.printStatistics(elapsedMs, 1, s.GetOutput())
517-
return retcode, qe
517+
return retcode, elapsedMs, qe
518518
}
519519

520520
// returns ErrExitRequested if the error is a SQL error and satisfies the connection's error handling configuration

pkg/sqlcmd/sqlcmd_test.go

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -289,27 +289,27 @@ func TestExitInitialQuery(t *testing.T) {
289289
func TestExitCodeSetOnError(t *testing.T) {
290290
s, _ := setupSqlCmdWithMemoryOutput(t)
291291
s.Connect.ErrorSeverityLevel = 12
292-
retcode, err := s.runQuery("RAISERROR (N'Testing!' , 11, 1)")
292+
retcode, _, err := s.runQuery("RAISERROR (N'Testing!' , 11, 1)")
293293
assert.NoError(t, err, "!ExitOnError 11")
294294
assert.Equal(t, -101, retcode, "Raiserror below ErrorSeverityLevel")
295-
retcode, err = s.runQuery("RAISERROR (N'Testing!' , 14, 1)")
295+
retcode, _, err = s.runQuery("RAISERROR (N'Testing!' , 14, 1)")
296296
assert.NoError(t, err, "!ExitOnError 14")
297297
assert.Equal(t, 14, retcode, "Raiserror above ErrorSeverityLevel")
298298
s.Connect.ExitOnError = true
299-
retcode, err = s.runQuery("RAISERROR (N'Testing!' , 11, 1)")
299+
retcode, _, err = s.runQuery("RAISERROR (N'Testing!' , 11, 1)")
300300
assert.NoError(t, err, "ExitOnError and Raiserror below ErrorSeverityLevel")
301301
assert.Equal(t, -101, retcode, "Raiserror below ErrorSeverityLevel")
302-
retcode, err = s.runQuery("RAISERROR (N'Testing!' , 14, 1)")
302+
retcode, _, err = s.runQuery("RAISERROR (N'Testing!' , 14, 1)")
303303
assert.ErrorIs(t, err, ErrExitRequested, "ExitOnError and Raiserror above ErrorSeverityLevel")
304304
assert.Equal(t, 14, retcode, "ExitOnError and Raiserror above ErrorSeverityLevel")
305305
s.Connect.ErrorSeverityLevel = 0
306-
retcode, err = s.runQuery("RAISERROR (N'Testing!' , 11, 1)")
306+
retcode, _, err = s.runQuery("RAISERROR (N'Testing!' , 11, 1)")
307307
assert.ErrorIs(t, err, ErrExitRequested, "ExitOnError and ErrorSeverityLevel = 0, Raiserror above 10")
308308
assert.Equal(t, 1, retcode, "ExitOnError and ErrorSeverityLevel = 0, Raiserror above 10")
309-
retcode, err = s.runQuery("RAISERROR (N'Testing!' , 5, 1)")
309+
retcode, _, err = s.runQuery("RAISERROR (N'Testing!' , 5, 1)")
310310
assert.NoError(t, err, "ExitOnError and ErrorSeverityLevel = 0, Raiserror below 10")
311311
assert.Equal(t, -101, retcode, "ExitOnError and ErrorSeverityLevel = 0, Raiserror below 10")
312-
retcode, err = s.runQuery("RAISERROR (15002, 10, 127, 'param')")
312+
retcode, _, err = s.runQuery("RAISERROR (15002, 10, 127, 'param')")
313313
assert.ErrorIs(t, err, ErrExitRequested, "RAISERROR with state 127")
314314
assert.Equal(t, 15002, retcode, "RAISERROR (15002, 10, 127, 'param')")
315315
}
@@ -441,7 +441,7 @@ func TestVerticalLayoutNoColumns(t *testing.T) {
441441
s, buf := setupSqlCmdWithMemoryOutput(t)
442442
defer buf.Close()
443443
s.vars.Set(SQLCMDFORMAT, "vert")
444-
_, err := s.runQuery("SELECT 100 as 'column1', 2000 as 'col2', 300")
444+
_, _, err := s.runQuery("SELECT 100 as 'column1', 2000 as 'col2', 300")
445445
assert.NoError(t, err, "runQuery failed")
446446
assert.Equal(t,
447447
"100"+SqlcmdEol+"2000"+SqlcmdEol+"300"+SqlcmdEol+SqlcmdEol+SqlcmdEol+oneRowAffected+SqlcmdEol,
@@ -451,15 +451,15 @@ func TestVerticalLayoutNoColumns(t *testing.T) {
451451
func TestSelectGuidColumn(t *testing.T) {
452452
s, buf := setupSqlCmdWithMemoryOutput(t)
453453
defer buf.Close()
454-
_, err := s.runQuery("select convert(uniqueidentifier, N'3ddba21e-ff0f-4d24-90b4-f355864d7865')")
454+
_, _, err := s.runQuery("select convert(uniqueidentifier, N'3ddba21e-ff0f-4d24-90b4-f355864d7865')")
455455
assert.NoError(t, err, "runQuery failed")
456456
assert.Equal(t, "3ddba21e-ff0f-4d24-90b4-f355864d7865"+SqlcmdEol+SqlcmdEol+oneRowAffected+SqlcmdEol, buf.buf.String(), "select a uniqueidentifier should work")
457457
}
458458

459459
func TestSelectNullGuidColumn(t *testing.T) {
460460
s, buf := setupSqlCmdWithMemoryOutput(t)
461461
defer buf.Close()
462-
_, err := s.runQuery("select convert(uniqueidentifier,null)")
462+
_, _, err := s.runQuery("select convert(uniqueidentifier,null)")
463463
assert.NoError(t, err, "runQuery failed")
464464
assert.Equal(t, "NULL"+SqlcmdEol+SqlcmdEol+oneRowAffected+SqlcmdEol, buf.buf.String(), "select a null uniqueidentifier should work")
465465
}
@@ -469,7 +469,7 @@ func TestVerticalLayoutWithColumns(t *testing.T) {
469469
defer buf.Close()
470470
s.vars.Set(SQLCMDFORMAT, "vert")
471471
s.vars.Set(SQLCMDMAXVARTYPEWIDTH, "256")
472-
_, err := s.runQuery("SELECT 100 as 'column1', 2000 as 'col2', 300")
472+
_, _, err := s.runQuery("SELECT 100 as 'column1', 2000 as 'col2', 300")
473473
assert.NoError(t, err, "runQuery failed")
474474
assert.Equal(t,
475475
"column1 100"+SqlcmdEol+"col2 2000"+SqlcmdEol+" 300"+SqlcmdEol+SqlcmdEol+SqlcmdEol+oneRowAffected+SqlcmdEol,
@@ -591,7 +591,7 @@ func TestQueryTimeout(t *testing.T) {
591591
s, buf := setupSqlCmdWithMemoryOutput(t)
592592
defer buf.Close()
593593
s.vars.Set(SQLCMDSTATTIMEOUT, "1")
594-
i, err := s.runQuery("waitfor delay '00:00:10'")
594+
i, _, err := s.runQuery("waitfor delay '00:00:10'")
595595
if assert.NoError(t, err, "runQuery returned an error") {
596596
assert.Equal(t, -100, i, "return from runQuery")
597597
assert.Equal(t, "Timeout expired"+SqlcmdEol, buf.buf.String(), "Query should have timed out")
@@ -712,8 +712,9 @@ func TestPrintStatisticsStandardFormat(t *testing.T) {
712712
standardFormat := 0
713713
s.PrintStatistics = &standardFormat
714714
s.Connect.PacketSize = 4096
715-
_, err := s.runQuery("SELECT 1")
715+
_, elapsedMs, err := s.runQuery("SELECT 1")
716716
assert.NoError(t, err, "runQuery failed")
717+
s.printStatistics(elapsedMs, 1, s.GetOutput())
717718
output := buf.buf.String()
718719
// Standard format should contain specific phrases
719720
assert.Contains(t, output, "Network packet size (bytes): 4096", "Should contain packet size")
@@ -728,8 +729,9 @@ func TestPrintStatisticsColonFormat(t *testing.T) {
728729
colonFormat := 1
729730
s.PrintStatistics = &colonFormat
730731
s.Connect.PacketSize = 8192
731-
_, err := s.runQuery("SELECT 1")
732+
_, elapsedMs, err := s.runQuery("SELECT 1")
732733
assert.NoError(t, err, "runQuery failed")
734+
s.printStatistics(elapsedMs, 1, s.GetOutput())
733735
output := buf.buf.String()
734736
// Colon format: packetSize:numBatches:totalTime:avgTime:batchesPerSec
735737
// Should start with 8192:1:
@@ -740,7 +742,7 @@ func TestPrintStatisticsDisabled(t *testing.T) {
740742
s, buf := setupSqlCmdWithMemoryOutput(t)
741743
defer func() { _ = buf.Close() }()
742744
// PrintStatistics is nil by default (disabled)
743-
_, err := s.runQuery("SELECT 1")
745+
_, _, err := s.runQuery("SELECT 1")
744746
assert.NoError(t, err, "runQuery failed")
745747
output := buf.buf.String()
746748
// Should not contain statistics output

0 commit comments

Comments
 (0)