Skip to content

feat: add ASCII table query output format#609

Open
0x7FFFFFFFFFFFFFFF wants to merge 17 commits into
microsoft:mainfrom
0x7FFFFFFFFFFFFFFF:main
Open

feat: add ASCII table query output format#609
0x7FFFFFFFFFFFFFFF wants to merge 17 commits into
microsoft:mainfrom
0x7FFFFFFFFFFFFFFF:main

Conversation

@0x7FFFFFFFFFFFFFFF
Copy link
Copy Markdown

This pull request adds a new ASCII table output format to sqlcmd, making it easier to read query results. It introduces the --ascii command-line option and updates the relevant code paths to support this feature. README.md has also been updated to reflect this option.

If --ascii is not used, sqlcmd behaves exactly the same as before.

The new output format looks like this:

image

@shueybubbles shueybubbles requested a review from Copilot November 24, 2025 03:45
@shueybubbles
Copy link
Copy Markdown
Collaborator

thx for opening a PR!

Comment thread cmd/sqlcmd/sqlcmd.go Outdated
Comment thread pkg/sqlcmd/format.go Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds a new ASCII table output format to sqlcmd, providing a more visually structured alternative to the default horizontal format. The feature is activated via the --ascii command-line flag or by setting the SQLCMDFORMAT variable to "ascii".

  • Introduces ASCII table formatter with automatic column wrapping for wide result sets
  • Updates the formatter initialization pattern across the codebase to support format selection
  • Adds comprehensive test coverage for the new formatter

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
pkg/sqlcmd/variables.go Adds "ascii" case handling in Format() method and initializes SQLCMDFORMAT variable
pkg/sqlcmd/format.go Updates NewSQLCmdDefaultFormatter to accept Variables parameter and delegate to ASCII formatter when appropriate
pkg/sqlcmd/format_ascii.go Implements new asciiFormatter with table rendering, column wrapping, and numeric alignment
pkg/sqlcmd/format_ascii_test.go Provides test coverage for ASCII formatter including basic output and column wrapping scenarios
pkg/sqlcmd/sqlcmd_test.go Updates test helper functions to pass Variables to formatter constructor
pkg/sqlcmd/commands_test.go Updates TestListColorPrintsStyleSamples to pass Variables to formatter constructor
cmd/sqlcmd/sqlcmd.go Adds --ascii flag definition and implements format variable setting logic
internal/sql/mssql.go Updates formatter initialization to pass Variables parameter
build/buildfast.cmd Adds Windows build script for faster development builds
README.md Documents the new --ascii option and ASCII table format feature

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread build/buildfast.cmd Outdated
Comment thread pkg/sqlcmd/format_ascii.go
Comment thread pkg/sqlcmd/format_ascii.go Outdated
@shueybubbles
Copy link
Copy Markdown
Collaborator

func (a *SQLCmdArguments) Validate(c *cobra.Command) (err error) {

--vertical and --ascii should be marked as mutually exclusive


Refers to: cmd/sqlcmd/sqlcmd.go:132 in dcdaa09. [](commit_id = dcdaa09, deletion_comment = False)

Comment thread README.md Outdated
Comment thread pkg/sqlcmd/format_ascii.go Outdated
Comment thread pkg/sqlcmd/format_ascii.go Outdated
Comment thread pkg/sqlcmd/format_ascii.go Outdated
Comment thread pkg/sqlcmd/format_ascii.go Outdated
Comment thread README.md Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

pkg/sqlcmd/format.go:101

  • The vars field is not initialized in the sqlCmdFormatterType struct. This will cause a nil pointer dereference when methods like ScreenWidth() or ColumnSeparator() are called on f.vars in the horizontal/vertical formatter. Add vars: vars, to fix this issue.
	return &sqlCmdFormatterType{
		removeTrailingSpaces: removeTrailingSpaces,
		format:               "horizontal",
		colorizer:            color.New(false),
		ccb:                  ccb,
	}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread README.md Outdated
@shueybubbles
Copy link
Copy Markdown
Collaborator

please resolve the comments that have been addressed

@0x7FFFFFFFFFFFFFFF
Copy link
Copy Markdown
Author

please resolve the comments that have been addressed

All resolved.

@0x7FFFFFFFFFFFFFFF
Copy link
Copy Markdown
Author

0x7FFFFFFFFFFFFFFF commented Jan 31, 2026

@shueybubbles There's still an issue: if a cell's content exceeds the terminal width, the output doesn't display well.

image

I can submit a new commit to limit the maximum column width to the terminal width and truncate any excess content. Any ideas?

@dlevy-msft-sql dlevy-msft-sql changed the title Add ASCII table query output format feat: add ASCII table query output format May 11, 2026
@dlevy-msft-sql
Copy link
Copy Markdown
Contributor

@shueybubbles There's still an issue: if a cell's content exceeds the terminal width, the output doesn't display well.

image I can submit a new commit to limit the maximum column width to the terminal width and truncate any excess content. Any ideas?

That sounds good. Truncate 3 columns short of the limit and add ... to indicate truncation sounds like the best plan.

@0x7FFFFFFFFFFFFFFF
Copy link
Copy Markdown
Author

@shueybubbles There's still an issue: if a cell's content exceeds the terminal width, the output doesn't display well.
image
I can submit a new commit to limit the maximum column width to the terminal width and truncate any excess content. Any ideas?

That sounds good. Truncate 3 columns short of the limit and add ... to indicate truncation sounds like the best plan.

Implemented.

@dlevy-msft-sql
Copy link
Copy Markdown
Contributor

Re-reviewed at head 6bb154d7. Three concrete fixes still needed before merge; the rest are acknowledgements / merge-coordination notes.

1. Missing copyright header on new files

Both pkg/sqlcmd/format_ascii.go and pkg/sqlcmd/format_ascii_test.go start at package sqlcmd with no header. Per the repo convention, every Go file needs:

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

package sqlcmd

2. asciiFormatter.AddRow does not increment rowcount

The default formatter increments f.rowcount on each row so downstream consumers (e.g. row-count reporting) stay correct. The ASCII path skips it:

func (f *asciiFormatter) AddRow(row *sql.Rows) string {
    values, err := f.scanRow(row)
    if err != nil { ... }
    f.rows = append(f.rows, values)
    // ... colWidths update ...
    // missing: f.rowcount++
}

Please add f.rowcount++ after a successful scan to match sqlCmdFormatterType's default behavior.

3. Test helper weakened in pkg/sqlcmd/sqlcmd_test.go

setupSqlCmdWithMemoryOutput now logs but does not fail on connect errors:

err := s.ConnectDb(nil, true)
if err != nil {
    t.Logf("ConnectDb failed: %v", err)
}
return s, buf

This silently swallows connection failures. Every test using this helper will continue running against an unconnected Sqlcmd, producing misleading green results in a broken environment. Please restore assert.NoError(t, err) (or t.Fatalf) so a broken test environment fails loudly.


Acknowledged / non-blocking

  • NewSQLCmdDefaultFormatter signature change is a public API break; worth a changelog note at release time.
  • Signature conflict with feat: implement -R and -f flags for regional settings and codepage #628 (also touches NewSQLCmdDefaultFormatter); whoever merges second resolves the trivial conflict.
  • Unbounded row buffering is inherent to ASCII table layout (need all rows to compute column widths).
  • term.GetSize(os.Stdout.Fd()) falling back to maxWidth = 1000000 for redirected output is reasonable.

@0x7FFFFFFFFFFFFFFF
Copy link
Copy Markdown
Author

Code modified based on the feedback.

Copy link
Copy Markdown
Contributor

@dlevy-msft-sql dlevy-msft-sql left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified at head 9cc0e839. All three findings from my earlier comment are addressed:

  • format_ascii.go / format_ascii_test.go — Microsoft copyright headers added.
  • asciiFormatter.AddRowf.rowcount++ added after successful scan.
  • setupSqlCmdWithMemoryOutput — restored to assert.NoError(t, err, "s.ConnectDB").

Bonus: the Refactor buffer closure commit also asserts on buf.Close() in TestAsciiFormatterWrapping instead of swallowing the error. Nice.

Thanks for the fast turnaround. LGTM.

@shueybubbles
Copy link
Copy Markdown
Collaborator

Do you have any screenshots of colorized output? I bet for some color schemes it looks very nice compared to ODBC format.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants