feat: implement :perftrace and :help commands - #632
feat: implement :perftrace and :help commands#632David Levy (dlevy-msft-sql) wants to merge 14 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR implements the :perftrace command to redirect performance statistics output to a file, stderr, or stdout, working in conjunction with the -p flag from PR #631.
Changes:
- Added stat writer infrastructure with GetStat/SetStat methods following the established pattern for output/error writers
- Implemented PERFTRACE command supporting file paths, "stdout", and "stderr" with variable substitution
- Added comprehensive test coverage for the command functionality
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| pkg/sqlcmd/sqlcmd.go | Added stat field and GetStat()/SetStat() methods for managing performance statistics output writer |
| pkg/sqlcmd/commands.go | Registered PERFTRACE command and implemented perftraceCommand() function with file/stdout/stderr support |
| pkg/sqlcmd/commands_test.go | Added TestPerftraceCommand() with comprehensive test scenarios and added PERFTRACE parsing tests |
| README.md | Documented the :perftrace command with usage example |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
e7abfe7 to
4d25bf2
Compare
652c011 to
1175a7e
Compare
:perftrace redirects timing/statistics output to a file, stderr, or stdout. :help displays the list of available sqlcmd commands with usage. Both commands validate arguments and return appropriate errors.
1175a7e to
ccd2a31
Compare
- helpCommand writes to os.Stdout instead of s.GetOutput() so :HELP output is not redirected when :OUT is active (matches ODBC sqlcmd) - Remove dead alias fallback loop (ED/R resolved by regex, not :HELP) - Fix TestHelpCommand: NOSUCHCMD now correctly asserts error - Add TestPerftraceCloseChain: verifies file1 closed when switching - Restore BOM context comment on outCommand - redirectWriter checks stdout before stderr (matches upstream order)
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
The implemented :help <command> behavior conflicts with the PR description and a new test intended to validate perftrace file-handle closure does not actually assert closure.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 5/5 changed files
- Comments generated: 3
- Review effort level: Lite
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
The :help feature is implemented but its own help/README documentation doesn’t mention the supported :help <command> form, making a covered capability undiscoverable.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 5/5 changed files
- Comments generated: 2
- Review effort level: Lite
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
:help <command> can’t show help for some commands using the spelling shown in the help output (e.g., :r, :ed, :!!), which is a functional usability bug in the new command.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 5/5 changed files
- Comments generated: 2
- Review effort level: Lite
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🔵 Needs a closer look
The -u (UnicodeOutputFile) :out path wraps files in a transform writer that does not close the underlying file, which can leak file descriptors when redirecting output.
Review details
Suppressed comments (3)
Previously missed (3) — in code that hasn't changed since the last review.
pkg/sqlcmd/commands.go:374
- When -u (UnicodeOutputFile) is enabled, :out wraps the destination file in transform.NewWriter and stores only the transform.Writer in Sqlcmd. Closing that wrapper does not close the underlying *os.File, so repeated :out redirections (or cleanup via SetOutput(nil)) can leak file descriptors.
pkg/sqlcmd/commands.go:73 - The :error help text uses the placeholder "", while :out and :perftrace document the exact accepted values ("|stderr|stdout"). Aligning this keeps :help output precise and consistent with the redirectWriter behavior.
pkg/sqlcmd/commands.go:78 - Grammar in :r help text: "Append" should be "Appends" to match the other present-tense descriptions in :help output.
- Files reviewed: 5/5 changed files
- Comments generated: 0 new
- Review effort level: Lite
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🔵 Needs a closer look
redirectWriter() doesn’t trim whitespace, so inputs like :out stdout can be misinterpreted as a filename and redirect incorrectly.
Review details
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
pkg/sqlcmd/commands.go:343
- redirectWriter() treats arguments like "stdout " (with trailing whitespace) as a filename rather than the stdout/stderr sentinel, because it never trims spaces before comparing. Since the command regex captures the rest of the line verbatim, users can easily end up creating a file named "stdout " instead of redirecting to stdout/stderr.
- Files reviewed: 5/5 changed files
- Comments generated: 0 new
- Review effort level: Lite
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🔵 Needs a closer look
The new TestHelpCommand helper mutates global os.Stdout without defers for guaranteed restoration/FD cleanup, which can leak handles and destabilize subsequent tests if a failure/panic occurs.
Review details
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
pkg/sqlcmd/commands_test.go:494
- captureHelp mutates the global os.Stdout but doesn’t use defers to guarantee restoration/FD cleanup if fn panics or a require/FailNow happens later. This can leak pipe handles and make subsequent tests fail in hard-to-diagnose ways.
- Files reviewed: 5/5 changed files
- Comments generated: 0 new
- Review effort level: Lite
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟢 Approval recommended
The implementation matches the PR description, centralizes redirection safely (including proper file closing), and includes targeted unit tests for the new behaviors.
Review details
- Files reviewed: 5/5 changed files
- Comments generated: 0 new
- Review effort level: Lite
Summary
Adds two new interactive commands:
:helpand:perftrace.:helpdisplays a reference of all available sqlcmd commands with short descriptions. It can also show help for a single command::help connect.:perftraceredirects performance statistics output (from the-pflag, PR #631) to a file, stderr, or stdout -- the same way:outand:errorredirect query and error output.New commands
:help:help <command>:perftrace <file>Usage
Implementation
helpfield to theCommandstruct. Every registered command carries its own help text, so:helpoutput is always in sync with the command registry. ATestAllCommandsHaveHelptest guards against drift.:help <command>does a case-insensitive lookup into the command map. Unknown names fall through to the full listing.redirectWriter()to share file/stderr/stdout resolution logic across:out,:error, and:perftrace(was duplicated betweenoutCommandanderrorCommand).stat(io.WriteCloser) field toSqlcmdwithGetStat()/SetStat()accessors.GetStat()falls back toGetOutput()when no:perftraceredirection is active, so existing-poutput is unaffected.SetStat(nil)called during cleanup incmd/sqlcmd/sqlcmd.goto close any open perf trace file.Testing
TestHelpCommand: full listing, per-command filtering, case-insensitive lookup, unknown command fallbackTestAllCommandsHaveHelp: drift guard ensuring every command has help textTestPerftraceCommand: empty arg error, stdout, stderr, file redirect, variable resolutionTestCommandParsing: parsing for:help,:help CONNECT,:perftrace stderr, etc.Merge notes
-pflag). After both merge, update theprintStatistics()call site to useGetStat()instead ofGetOutput().:serverlist) also registers aHELPcommand. Merge this PR first, then rebase feat: implement :serverlist command #630.Fixes #622.