Skip to content

feat: add -f codepage flag for input/output encoding#638

Open
dlevy-msft-sql wants to merge 1 commit intomicrosoft:mainfrom
dlevy-msft-sql:round-out-part2
Open

feat: add -f codepage flag for input/output encoding#638
dlevy-msft-sql wants to merge 1 commit intomicrosoft:mainfrom
dlevy-msft-sql:round-out-part2

Conversation

@dlevy-msft-sql
Copy link
Contributor

Summary

Implements the -f flag from ODBC sqlcmd for specifying input and output file code pages.

Changes

  • cmd/sqlcmd/sqlcmd.go: Added CodePage and ListCodePages fields, -f/--code-page flag, validation, and runtime application
  • pkg/sqlcmd/codepage.go: Comprehensive codepage support with parsing and encoding conversion
  • pkg/sqlcmd/codepage_test.go: Unit tests for codepage parsing and supported encodings
  • pkg/sqlcmd/commands.go: Updated :R command to respect codepage settings when reading files
  • pkg/sqlcmd/sqlcmd.go: Added CodePage field to Sqlcmd struct
  • cmd/sqlcmd/sqlcmd_test.go: Command line argument tests for valid and invalid codepage values
  • README.md: Documentation with format examples

Usage

# Single codepage for both input and output
sqlcmd -S server -f 65001 -i script.sql -o results.txt

# Different codepages for input and output
sqlcmd -S server -f i:1252,o:65001 -i windows_script.sql -o utf8_results.txt

# List all supported codepages
sqlcmd --list-codepages

Supported Codepages

  • Unicode: 65001 (UTF-8), 1200 (UTF-16LE), 1201 (UTF-16BE)
  • Windows: 874, 1250-1258
  • OEM/DOS: 437, 850, etc.
  • ISO-8859: 28591-28606
  • CJK: 932 (Shift-JIS), 936 (GB2312), 949 (Korean), 950 (Big5)
  • EBCDIC: 37, 1047, 1140

Testing

  • All existing tests pass
  • Added command line argument parsing tests
  • Added unit tests for codepage parsing and validation

Improves ODBC sqlcmd compatibility.

@dlevy-msft-sql
Copy link
Contributor Author

Supersedes #627

@dlevy-msft-sql dlevy-msft-sql self-assigned this Jan 26, 2026
@dlevy-msft-sql dlevy-msft-sql added sqlcmd switch switch in existing sqlcmd Size: S Small issue (less than one week effort) labels Jan 26, 2026
Copy link

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 PR adds configurable input/output code page handling to the legacy sqlcmd CLI, improving compatibility with ODBC sqlcmd and enabling legacy-encoding workflows.

Changes:

  • Introduces a central code page registry and parsing logic (-f / --code-page) with support for many Windows, OEM, ISO-8859, CJK, and EBCDIC encodings and a --list-codepages listing mode.
  • Wires code page settings through the legacy CLI into the core Sqlcmd engine so :R, :OUT, and :ERROR commands correctly decode input files and encode output/error files according to the configured code pages.
  • Adds comprehensive unit tests for code page parsing/lookup and CLI argument validation, plus README documentation and examples for the new functionality.

Reviewed changes

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

Show a summary per file
File Description
pkg/sqlcmd/sqlcmd_test.go Adds tests to verify IncludeFile decodes input files correctly under various input code pages (Windows-1252, UTF-16LE/BE with and without BOM).
pkg/sqlcmd/sqlcmd.go Extends Sqlcmd with a CodePage field and updates IncludeFile to select an appropriate io.Reader based on configured input code page or BOM auto-detection.
pkg/sqlcmd/commands_test.go Adds tests confirming :OUT and :ERROR commands honor the configured output code page when writing to files.
pkg/sqlcmd/commands.go Introduces a transformWriteCloser helper and updates :OUT/:ERROR commands to encode output using the selected code page while ensuring underlying files are closed correctly.
pkg/sqlcmd/codepage_windows.go Implements Windows-specific encoding.Encoding support backed by MultiByteToWideChar/WideCharToMultiByte for system-installed code pages not in the built-in registry.
pkg/sqlcmd/codepage_test.go Adds tests for ParseCodePage, GetEncoding, SupportedCodePages, and Windows-specific fallback behavior, including round-trip checks for a Windows-only EBCDIC code page.
pkg/sqlcmd/codepage_other.go Provides a non-Windows implementation of getSystemCodePageEncoding that surfaces a clear error for unsupported system code pages.
pkg/sqlcmd/codepage.go Defines the cross-platform code page registry, CodePageSettings, parsing/validation logic for -f, and a SupportedCodePages API used by the CLI.
cmd/sqlcmd/sqlcmd_test.go Extends CLI argument tests to cover -f / --code-page, --list-codepages, and various invalid code page argument combinations.
cmd/sqlcmd/sqlcmd.go Adds CodePage and ListCodePages arguments, validates and stores parsed CodePageSettings, applies them to the Sqlcmd instance, and implements --list-codepages output formatting.
README.md Documents the new -f flag, describes supported code pages, provides usage examples, and explains --list-codepages and default BOM auto-detection behavior.

Copy link

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 11 out of 11 changed files in this pull request and generated 4 comments.

Copy link

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 11 out of 11 changed files in this pull request and generated no new comments.

err = localizer.Errorf("The -J parameter requires encryption to be enabled (-N true, -N mandatory, or -N strict).")
case a.CodePage != "":
if codePageSettings, parseErr := sqlcmd.ParseCodePage(a.CodePage); parseErr != nil {
err = localizer.Errorf(`'-f %s': %v`, a.CodePage, parseErr)
Copy link
Collaborator

Choose a reason for hiding this comment

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

lizer.Errorf

there's no localizable content in the format string so don't need to use localizer

if args.ListCodePages {
fmt.Println(localizer.Sprintf("Supported Code Pages:"))
fmt.Println()
fmt.Printf("%-8s %-20s %s\n", "Code", "Name", "Description")
Copy link
Collaborator

Choose a reason for hiding this comment

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

", "Code", "Name", "Description")

does this string need to be localizable?

os.Exit(0)
}
if len(argss) > 0 {
fmt.Printf("%s'%s': Unknown command. Enter '--help' for command help.", sqlcmdErrorPrefix, argss[0])
Copy link
Collaborator

Choose a reason for hiding this comment

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

%s'%s': Unknown command. Enter '--help' for command help

does this string need to be localizable?

@shueybubbles
Copy link
Collaborator

  		err = localizer.Errorf("The -L parameter can not be used in combination with other parameters.")

should list code pages get the same exclusivity treatment as list servers?


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

Copy link
Collaborator

@shueybubbles shueybubbles left a comment

Choose a reason for hiding this comment

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

:shipit:

@dlevy-msft-sql dlevy-msft-sql force-pushed the round-out-part2 branch 2 times, most recently from 17fc3b5 to 623f029 Compare February 5, 2026 20:00
@dlevy-msft-sql dlevy-msft-sql changed the title Add -f codepage flag for input/output encoding feat: add -f codepage flag for input/output encoding Feb 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Size: S Small issue (less than one week effort) sqlcmd switch switch in existing sqlcmd

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants