Skip to content

Add NVARCHAR (SQL_C_WCHAR) Output Support to .NET Core C# Language Extension#69

Open
SicongLiu2000 wants to merge 1 commit intomainfrom
dev/sicongliu/nvarchar
Open

Add NVARCHAR (SQL_C_WCHAR) Output Support to .NET Core C# Language Extension#69
SicongLiu2000 wants to merge 1 commit intomainfrom
dev/sicongliu/nvarchar

Conversation

@SicongLiu2000
Copy link
Contributor

Motivation

SQL Server distinguishes between VARCHAR (byte-oriented, typically UTF-8) and NVARCHAR (UTF-16 Unicode). The existing C# extension always mapped .NET string columns to VARCHAR, with no way to produce NVARCHAR output. This is limiting for workloads that require native Unicode output or need to match an NVARCHAR schema on the SQL Server side.

Changes

API Surface

  • AbstractSqlServerExtensionExecutor.OutputColumnDataTypes — new Dictionary<string, SqlDataType> property on the SDK base class. Extension authors populate this dictionary in their Execute() method to override the default output type for specific string columns.
// Example: output "text" column as NVARCHAR instead of VARCHAR
OutputColumnDataTypes["text"] = SqlDataType.DotNetWChar;

Core Logic (CSharpOutputDataSet.cs)

  • ExtractColumns() now accepts an optional outputColumnDataTypes parameter.
  • For each string column, the method checks if the user specified an override:
    • Only DotNetChar (VARCHAR) and DotNetWChar (NVARCHAR) are valid overrides for string columns; any other type throws an ArgumentException.
  • WCHAR column size is now reported as byte length (not character count), matching the extension host's expectations for UTF-16 data.

Session Wiring (CSharpSession.cs)

  • Execute() passes the executor's OutputColumnDataTypes dictionary through to ExtractColumns().

Documentation (README.md)

  • Added an Output Schema Support section with:
    • Usage examples for single-column and mixed VARCHAR/NVARCHAR output
    • Supported string type table (DotNetChar → VARCHAR, DotNetWChar → NVARCHAR)
    • Default behavior explanation

Sample Update (RegexSample.cs)

  • Added a commented-out example showing how to use OutputColumnDataTypes to produce NVARCHAR output, without changing the sample's default behavior.

Test Coverage

Three new test executors and four new native Google Test cases were added:

Test Description
GetNVarcharOutputResultColumnsTest Verifies that OutputColumnDataTypes["text"] = DotNetWChar produces SQL_C_WCHAR output with correct byte-length column size
GetPreserveNVarcharTypeResultColumnsTest Verifies that NVARCHAR input still defaults to VARCHAR output when no OutputColumnDataTypes config is provided
GetMixedStringOutputResultColumnsTest Verifies mixed output: one column stays VARCHAR (default), another becomes NVARCHAR via explicit configuration
GetWStringResultColumnsTest (existing, updated) Updated variable names and comments for clarity; fixed stale API references

All 62 tests pass (release build, Windows).

Files Changed

File Change
src/managed/sdk/AbstractSqlServerExtensionExecutor.cs Added OutputColumnDataTypes property
src/managed/CSharpOutputDataSet.cs Added type override logic, validation, WCHAR byte-length fix
src/managed/CSharpSession.cs Wired OutputColumnDataTypes to ExtractColumns()
sample/regex/pkg/RegexSample.cs Added commented-out NVARCHAR usage example
test/src/managed/CSharpTestExecutor.cs Added 3 new test executors
test/src/native/CSharpGetResultColumnTests.cpp Added 3 new tests, improved existing test
README.md Added Output Schema Support documentation

Breaking Changes

None. The default behavior is unchanged — all string columns output as VARCHAR (UTF-8) unless explicitly overridden via OutputColumnDataTypes.

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

Adds opt-in NVARCHAR (SQL_C_WCHAR) output support for .NET Core C# language extensions by allowing executors to override the default string output type per column.

Changes:

  • Introduces AbstractSqlServerExtensionExecutor.OutputColumnDataTypes to override output SQL types by column name.
  • Wires the override dictionary through session execution into output schema extraction, including validation and WCHAR byte-length sizing.
  • Adds/updates native + managed tests, plus README and sample guidance for mixed VARCHAR/NVARCHAR outputs.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
language-extensions/dotnet-core-CSharp/src/managed/sdk/AbstractSqlServerExtensionExecutor.cs Adds new OutputColumnDataTypes API for executors to configure string output types.
language-extensions/dotnet-core-CSharp/src/managed/CSharpOutputDataSet.cs Applies per-column string type overrides with validation; reports DotNetWChar size as UTF-16 byte length.
language-extensions/dotnet-core-CSharp/src/managed/CSharpSession.cs Passes executor OutputColumnDataTypes into ExtractColumns().
language-extensions/dotnet-core-CSharp/test/src/managed/CSharpTestExecutor.cs Adds managed test executors exercising default vs NVARCHAR vs mixed output behavior.
language-extensions/dotnet-core-CSharp/test/src/native/CSharpGetResultColumnTests.cpp Adds native gtests validating result column metadata for NVARCHAR and mixed output.
language-extensions/dotnet-core-CSharp/sample/regex/pkg/RegexSample.cs Documents (commented) example of configuring NVARCHAR output.
language-extensions/dotnet-core-CSharp/README.md Documents Output Schema Support and how to use OutputColumnDataTypes.

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

Comment on lines +74 to +75
// Process and return data
return resultDataFrame;
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

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

The code sample returns resultDataFrame, but that variable isn’t defined in the example, so the snippet won’t compile if copied as-is. Consider returning input (as in other examples) or declare/build resultDataFrame in the snippet to keep the documentation self-contained.

Suggested change
// Process and return data
return resultDataFrame;
// Process data if needed and return the DataFrame
return input;

Copilot uses AI. Check for mistakes.
Comment on lines +82 to +86
| SqlDataType | SQL Type | Encoding | Description |
|-------------|----------|----------|-------------|
| `SqlDataType.DotNetChar` | VARCHAR | UTF-8 | Default for string columns |
| `SqlDataType.DotNetWChar` | NVARCHAR | UTF-16 | Use for Unicode data |

Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

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

The “Supported String Types” table rows start with ||, which creates an extra empty column in Markdown and renders incorrectly on GitHub. Use a single leading | for the header/separator/data rows so the table has the intended 4 columns.

Copilot uses AI. Check for mistakes.
Comment on lines +68 to +81
if (column.DataType == typeof(string) && outputColumnDataTypes != null)
{
if (outputColumnDataTypes.TryGetValue(column.Name, out var userType))
{
if (userType != SqlDataType.DotNetChar && userType != SqlDataType.DotNetWChar)
{
throw new ArgumentException(
$"Invalid type override '{userType}' for string column '{column.Name}'. " +
$"Only DotNetChar and DotNetWChar are supported for string columns.");
}

dataType = userType;
Logging.Trace($"ExtractColumns: Column '{column.Name}' using user-specified type: {dataType}");
}
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

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

These 'if' statements can be combined.

Suggested change
if (column.DataType == typeof(string) && outputColumnDataTypes != null)
{
if (outputColumnDataTypes.TryGetValue(column.Name, out var userType))
{
if (userType != SqlDataType.DotNetChar && userType != SqlDataType.DotNetWChar)
{
throw new ArgumentException(
$"Invalid type override '{userType}' for string column '{column.Name}'. " +
$"Only DotNetChar and DotNetWChar are supported for string columns.");
}
dataType = userType;
Logging.Trace($"ExtractColumns: Column '{column.Name}' using user-specified type: {dataType}");
}
if (column.DataType == typeof(string)
&& outputColumnDataTypes != null
&& outputColumnDataTypes.TryGetValue(column.Name, out var userType))
{
if (userType != SqlDataType.DotNetChar && userType != SqlDataType.DotNetWChar)
{
throw new ArgumentException(
$"Invalid type override '{userType}' for string column '{column.Name}'. " +
$"Only DotNetChar and DotNetWChar are supported for string columns.");
}
dataType = userType;
Logging.Trace($"ExtractColumns: Column '{column.Name}' using user-specified type: {dataType}");

Copilot uses AI. Check for mistakes.
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.

1 participant

Comments