Skip to content

Add support for XEvent logging and bump API version to v3#90

Open
miljann995 wants to merge 22 commits into
mainfrom
dev/mveljovic/host-callback-api
Open

Add support for XEvent logging and bump API version to v3#90
miljann995 wants to merge 22 commits into
mainfrom
dev/mveljovic/host-callback-api

Conversation

@miljann995
Copy link
Copy Markdown

@miljann995 miljann995 commented May 27, 2026

This pull request introduces a new optional host callback API (version 3) for SQL language extensions, enabling extensions to log XEvents back to the host infrastructure. The update defines new callback types and structures in the native interface, implements the callback registration and invocation in both native and managed (.NET) layers, and provides the necessary glue to allow the managed extension to log messages through the host's event system.

The most important changes are:

API and Interface Additions:

  • Bumped the EXTERNAL_LANGUAGE_EXTENSION_API version from 2 to 3 in sqlexternallanguage.h to indicate the new optional host callback API.
  • Added the PFunc_ExtensionLogXEvent callback type, the SQLEXTENSION_HOST_CALLBACKS structure, and the SetHostCallbacks API to sqlexternallanguage.h, allowing the host to provide callback functions to extensions.

Native Extension Integration:

  • Added the SetHostCallbacks function and the g_hostCallbacks pointer to nativecsharpextension.h and implemented their logic in nativecsharpextension.cpp, storing the host callbacks and forwarding them to the managed layer. [1] [2]

Managed Extension Support:

  • Defined managed representations for the callback delegate and structure in CSharpExtension.cs, and implemented the SetHostCallbacks method to receive and store the callback, enabling managed code to log XEvents through the host.
  • Updated the Logging utility in Logging.cs to store the host-provided callback and added the LogXEvent method, allowing managed code to log messages through the host's XEvent infrastructure. [1] [2]

Here's the compatibility matrix for general Extension API in terms of host callbacks.

Host v2 Host v3
Extension v2 SetHostCallbacks is not defined in Extension and host does not expect it and does not call it. SetHostCallbacks is not defined in Extension, but host does check it and skips calling it since it's not defined on Extension side.
Extension v3 SetHostCallbacks is defined in Extension but host does not expect it and does not call it. SetHostCallbacks is defined on both sides and host calls it.

Here's the compatibility matrix for Host Callbacks API. Here, v2 can be interpreted as vNext. v1 is the current version present in this pull request.

Host v1 Host v2
Extension v1 Host callbacks struct passed from host contains only LogXEvent callback and Extension expects only that one, and saves its address. Host callbacks struct passed from host contains additional functions apart from LogXEvent, but Extension reads only LogXEvent, ignoring other callbacks.
Extension v2 Host callbacks struct passed from host contains only LogXEvent callback, and Extension expects additional functions apart from LogXEvent, but since they are nullptr in a struct, they will be skipped. Host callbacks struct passed from host contains additional functions apart from LogXEvent, and Extension expects additional functions apart from LogXEvent, saves their addresses and calls them.

@miljann995 miljann995 changed the title feat: add v3 of extension api with host callbacks Add support for XEvent logging and bump API version to v3 May 27, 2026
@miljann995 miljann995 marked this pull request as ready for review May 27, 2026 18:28
Copilot AI review requested due to automatic review settings May 27, 2026 18:28
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 PR introduces a v3 extension interface update to support optional host callbacks, enabling extensions (specifically the .NET C# extension) to log XEvents back through the host infrastructure.

Changes:

  • Bumped EXTERNAL_LANGUAGE_EXTENSION_API from 2 to 3 and added a new optional SetHostCallbacks API + callback struct/type in the shared native interface header.
  • Implemented native SetHostCallbacks in the .NET C# extension and forwarded the callback struct to the managed layer.
  • Added managed callback delegates/structs plus a Logging.LogXEvent(...) helper that invokes the host-provided callback.

Reviewed changes

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

Show a summary per file
File Description
extension-host/include/sqlexternallanguage.h Bumps API version to v3; adds host callback typedef/struct and SetHostCallbacks API declaration.
language-extensions/dotnet-core-CSharp/include/nativecsharpextension.h Declares SetHostCallbacks export and stores a host-callbacks pointer.
language-extensions/dotnet-core-CSharp/src/native/nativecsharpextension.cpp Implements native SetHostCallbacks; resets host callbacks on cleanup.
language-extensions/dotnet-core-CSharp/src/managed/CSharpExtension.cs Adds managed callback delegate/struct and implements managed SetHostCallbacks.
language-extensions/dotnet-core-CSharp/src/managed/utils/Logging.cs Stores callback delegate and adds LogXEvent helper for managed code.

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

Comment thread extension-host/include/sqlexternallanguage.h
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 5 out of 5 changed files in this pull request and generated 2 comments.

SicongLiu2000

This comment was marked as off-topic.

SicongLiu2000

This comment was marked as off-topic.

Copy link
Copy Markdown
Contributor

@SicongLiu2000 SicongLiu2000 left a comment

Choose a reason for hiding this comment

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

Review Summary — XEvent Logging Callback API (v3)

Nice feature — clean API surface and good test coverage. Three items I'd want addressed before merge, plus several medium-severity hardening suggestions:

Must-fix (High)

  1. TOCTOU on _logXEventCallback (Logging.cs) — snapshot to local before null-check and invocation to prevent NRE from concurrent SetLogXEventCallback(null).
  2. Use-after-free in Cleanup() (nativecsharpextension.cpp) — must clear the managed-side callback delegate before tearing down the .NET runtime, otherwise background threads can invoke a stale host function pointer.
  3. char* vs byte* delegate type mismatch (CSharpExtension.cs) — delegate declares char* (2-byte UTF-16) but actually receives byte* (1-byte UTF-8). Should be byte* to match the native SQLCHAR*.

Should-fix (Medium)

  1. Dangling pointerg_hostCallbacks stores borrowed pointer; copy the struct or remove the dead global.
  2. fixed on empty array — yields null pointer passed to native code; guard the empty-message case.
  3. static globals in header — pre-existing issue, but the new g_hostCallbacks follows the pattern; extern + single definition is correct.

Consider (Low)

  1. Version check could use a MAX_SUPPORTED constant for future extensibility.
  2. ulong vs nuint for SQLULEN if 32-bit is ever a target.

See inline comments for details and suggested fixes.

Comment thread extension-host/include/sqlexternallanguage.h Outdated
Comment thread language-extensions/dotnet-core-CSharp/src/native/nativecsharpextension.cpp Outdated
Comment thread language-extensions/dotnet-core-CSharp/src/managed/CSharpExtension.cs Outdated
Comment thread language-extensions/dotnet-core-CSharp/src/managed/utils/Logging.cs Outdated
Comment thread language-extensions/dotnet-core-CSharp/src/managed/utils/Logging.cs
@miljann995 miljann995 requested a review from SicongLiu2000 May 28, 2026 21:57
Copy link
Copy Markdown
Contributor

@SicongLiu2000 SicongLiu2000 left a comment

Choose a reason for hiding this comment

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

All 8 findings addressed — TOCTOU snapshot, use-after-free ordering, type mismatch, dangling pointer copy, fixed-null guard, extern globals, version constant, and typo. Good test coverage with the new GTest suite. LGTM 👍

//
#define SQLEXTENSION_HOST_CALLBACKS_VERSION_1 1

typedef struct _SQLEXTENSION_HOST_CALLBACKS
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

the struct mismatches with the latest one in the engine

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

typedef struct _SQLEXTENSION_HOST_CALLBACKS
{
    SQLUSMALLINT Version;               // 2 bytes
    SQLUSMALLINT Reserved0;             // 2 bytes (explicit padding)
    SQLUINTEGER SizeInBytes;            // 4 bytes
    PFunc_ExtensionLogXEvent LogXEvent; // 8 bytes (pointer)
    void *Reserved1;                    // 8 bytes
    void *Reserved2;                    // 8 bytes
} SQLEXTENSION_HOST_CALLBACKS;          // Total: 32 bytes

Comment thread extension-host/include/sqlexternallanguage.h
SQLEXTENSION_INTERFACE
SQLRETURN Cleanup();

// Trace levels for events logged from via LogXEvent function.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We need to use the latest commit in our internal repo (this is used as git submodule there), generate nugets there, consume it in your DsMainDev private branch, run PVS with it.

// Lowest numeric value is the most severe, matching the Windows ETW
// TRACE_LEVEL_* convention.
//
enum ExtensionTraceLevel
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

sqlexternallanguage.h to stay similar with what we have in the engine;
right now this enum is not in the same place in the engine code.
can we move ExtensionTraceLevel in there also to sqlexternallanguage.h?


// Host callbacks pointer provided by the host via SetHostCallbacks.
//
static SQLEXTENSION_HOST_CALLBACKS* g_hostCallbacks = nullptr; No newline at end of file
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

g_hostCallbacks is a raw pointer to host-owned memory (CExthostExtensionManager::m_hostCallbacks in DsMainDev). Its lifetime is valid from SetHostCallbacks until Cleanup. Please add a comment documenting this ownership contract so future contributors don't cache or use it after Cleanup.

Comment thread language-extensions/dotnet-core-CSharp/src/managed/utils/Logging.cs Outdated
Comment thread extension-host/include/sqlexternallanguage.h
Comment thread extension-host/include/sqlextensionhostcallbacks.h
Comment thread extension-host/include/sqlextensionhostcallbacks.h 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 7 out of 7 changed files in this pull request and generated 6 comments.

Comment thread language-extensions/dotnet-core-CSharp/src/managed/CSharpExtension.cs Outdated
Comment thread language-extensions/dotnet-core-CSharp/src/managed/CSharpExtension.cs Outdated
Comment thread language-extensions/dotnet-core-CSharp/src/managed/utils/Logging.cs Outdated
Comment thread language-extensions/dotnet-core-CSharp/src/managed/CSharpExtension.cs Outdated
Comment thread language-extensions/dotnet-core-CSharp/src/managed/CSharpExtension.cs Outdated
Comment thread language-extensions/dotnet-core-CSharp/src/managed/utils/Logging.cs Outdated
@miljann995 miljann995 force-pushed the dev/mveljovic/host-callback-api branch from c3c4392 to 875619b Compare May 29, 2026 13:02
@miljann995 miljann995 force-pushed the dev/mveljovic/host-callback-api branch from 875619b to 2f9a8c9 Compare May 29, 2026 13:06
@miljann995 miljann995 requested a review from monamaki May 29, 2026 15:43
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