From ebd4b2f17bd85026b05f9876176e5900f4b5a0df Mon Sep 17 00:00:00 2001 From: David Levy Date: Sat, 24 Jan 2026 22:32:31 -0600 Subject: [PATCH 1/2] Implement :help command Add the :help command to display available sqlcmd commands. This improves compatibility with legacy ODBC sqlcmd. Changes: - Added HELP command to command registry - Added helpCommand function with full command list - Added tests for command parsing and functionality - Updated README.md --- README.md | 1 + pkg/sqlcmd/commands.go | 54 +++++++++++++++++++++++++++++++++++++ pkg/sqlcmd/commands_test.go | 23 ++++++++++++++++ 3 files changed, 78 insertions(+) diff --git a/README.md b/README.md index fe26e192..711ac9b6 100644 --- a/README.md +++ b/README.md @@ -154,6 +154,7 @@ switches are most important to you to have implemented next in the new sqlcmd. - `:Connect` now has an optional `-G` parameter to select one of the authentication methods for Azure SQL Database - `SqlAuthentication`, `ActiveDirectoryDefault`, `ActiveDirectoryIntegrated`, `ActiveDirectoryServicePrincipal`, `ActiveDirectoryManagedIdentity`, `ActiveDirectoryPassword`. If `-G` is not provided, either Integrated security or SQL Authentication will be used, dependent on the presence of a `-U` username parameter. - The new `--driver-logging-level` command line parameter allows you to see traces from the `go-mssqldb` client driver. Use `64` to see all traces. - Sqlcmd can now print results using a vertical format. Use the new `--vertical` command line option to set it. It's also controlled by the `SQLCMDFORMAT` scripting variable. +- `:help` displays a list of available sqlcmd commands. ``` 1> select session_id, client_interface_name, program_name from sys.dm_exec_sessions where session_id=@@spid diff --git a/pkg/sqlcmd/commands.go b/pkg/sqlcmd/commands.go index 66dd1dba..8528c4b5 100644 --- a/pkg/sqlcmd/commands.go +++ b/pkg/sqlcmd/commands.go @@ -113,6 +113,11 @@ func newCommands() Commands { action: xmlCommand, name: "XML", }, + "HELP": { + regex: regexp.MustCompile(`(?im)^[ \t]*:HELP(?:[ \t]+(.*$)|$)`), + action: helpCommand, + name: "HELP", + }, } } @@ -596,6 +601,55 @@ func xmlCommand(s *Sqlcmd, args []string, line uint) error { return nil } +// helpCommand displays the list of available sqlcmd commands +func helpCommand(s *Sqlcmd, args []string, line uint) error { + helpText := `:!! [] + - Executes a command in the operating system shell. +:connect server[\instance] [-l timeout] [-U user [-P password]] + - Connects to a SQL Server instance. +:ed + - Edits the current or last executed statement cache. +:error + - Redirects error output to a file, stderr, or stdout. +:exit + - Quits sqlcmd immediately. +:exit() + - Execute statement cache; quit with no return value. +:exit() + - Execute the specified query; returns numeric result. +go [] + - Executes the statement cache (n times). +:help + - Shows this list of commands. +:list + - Prints the content of the statement cache. +:listvar + - Lists the set sqlcmd scripting variables. +:on error [exit|ignore] + - Action for batch or sqlcmd command errors. +:out |stderr|stdout + - Redirects query output to a file, stderr, or stdout. +:perftrace |stderr|stdout + - Redirects timing output to a file, stderr, or stdout. +:quit + - Quits sqlcmd immediately. +:r + - Append file contents to the statement cache. +:reset + - Discards the statement cache. +:serverlist + - Lists local and SQL Servers on the network. +:setvar {variable} + - Removes a sqlcmd scripting variable. +:setvar + - Sets a sqlcmd scripting variable. +:xml [on|off] + - Sets XML output mode. +` + _, err := s.GetOutput().Write([]byte(helpText)) + return err +} + func resolveArgumentVariables(s *Sqlcmd, arg []rune, failOnUnresolved bool) (string, error) { var b *strings.Builder end := len(arg) diff --git a/pkg/sqlcmd/commands_test.go b/pkg/sqlcmd/commands_test.go index 6197aa3f..5d527b87 100644 --- a/pkg/sqlcmd/commands_test.go +++ b/pkg/sqlcmd/commands_test.go @@ -54,6 +54,8 @@ func TestCommandParsing(t *testing.T) { {`:XML ON `, "XML", []string{`ON `}}, {`:RESET`, "RESET", []string{""}}, {`RESET`, "RESET", []string{""}}, + {`:HELP`, "HELP", []string{""}}, + {`:help`, "HELP", []string{""}}, } for _, test := range commands { @@ -458,3 +460,24 @@ func TestExitCommandAppendsParameterToCurrentBatch(t *testing.T) { } } + +func TestHelpCommand(t *testing.T) { + s, buf := setupSqlCmdWithMemoryOutput(t) + defer buf.Close() + s.SetOutput(buf) + + err := helpCommand(s, []string{""}, 1) + assert.NoError(t, err, "helpCommand should not error") + + output := buf.buf.String() + // Verify key commands are listed + assert.Contains(t, output, ":connect", "help should list :connect") + assert.Contains(t, output, ":exit", "help should list :exit") + assert.Contains(t, output, ":help", "help should list :help") + assert.Contains(t, output, ":setvar", "help should list :setvar") + assert.Contains(t, output, ":listvar", "help should list :listvar") + assert.Contains(t, output, ":out", "help should list :out") + assert.Contains(t, output, ":error", "help should list :error") + assert.Contains(t, output, ":r", "help should list :r") + assert.Contains(t, output, "go", "help should list go") +} From 4bea3f26108ee5406b27b154be308be7f8ecc52a Mon Sep 17 00:00:00 2001 From: David Levy Date: Sun, 25 Jan 2026 11:47:13 -0600 Subject: [PATCH 2/2] Fix review comments for PR #634 - Remove :serverlist and :perftrace from help text - These commands are in separate PRs and not yet merged - Help text should only list commands that exist in this branch --- pkg/sqlcmd/commands.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pkg/sqlcmd/commands.go b/pkg/sqlcmd/commands.go index 8528c4b5..d67d6c17 100644 --- a/pkg/sqlcmd/commands.go +++ b/pkg/sqlcmd/commands.go @@ -629,16 +629,12 @@ go [] - Action for batch or sqlcmd command errors. :out |stderr|stdout - Redirects query output to a file, stderr, or stdout. -:perftrace |stderr|stdout - - Redirects timing output to a file, stderr, or stdout. :quit - Quits sqlcmd immediately. :r - Append file contents to the statement cache. :reset - Discards the statement cache. -:serverlist - - Lists local and SQL Servers on the network. :setvar {variable} - Removes a sqlcmd scripting variable. :setvar