Skip to content

Format MSSQL query logs as executable multi-line SQL with DECLARE parameter headers (including TVP support)#170

Open
Copilot wants to merge 10 commits into
mainfrom
copilot/format-sql-query-logs
Open

Format MSSQL query logs as executable multi-line SQL with DECLARE parameter headers (including TVP support)#170
Copilot wants to merge 10 commits into
mainfrom
copilot/format-sql-query-logs

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 20, 2026

SQL query logs were difficult to read because query text and parameters were emitted as JSON fields with escaped control characters. This updates MSSQL logging to emit readable multi-line SQL and prepend parameter DECLARE statements with inferred SQL types and correctly formatted values.

  • Added SQL log formatter for { query, parameters }

    • Introduced formatSqlQueryForLog in lib/sql.js
    • Converts request parameters into DECLARE lines:
      • maps MSSQL constructors to SQL type names (INT, VARCHAR(n), DATETIME2, BIT, etc.)
      • supports length / precision / scale where present
      • formats values for SQL readability ('escaped strings', NULL, 1/0 for bit, datetime literals, hex for buffers)
    • Appends the original query verbatim, preserving real newlines/tabs
  • Added TVP (mssql.Table) formatting support

    • Detects TVP parameters via instanceof mssql.Table
    • Emits executable TVP setup before scalar DECLAREs:
      • DECLARE @Param [schema].[Type] (from table.path)
      • INSERT INTO @Param ([col1], [col2], ...) VALUES (...)
    • Uses TVP column names from table.columns
    • Uses existing SQL value formatting for row values
    • Batches row inserts up to 100 rows per INSERT using multi-row VALUES
  • Applied formatter at all MSSQL query log sites

    • Slow-query warning path (logSlowQuery)
    • Query threshold logger (createQueryLogger)
    • Query error logger (runQuery catch path)
  • Added focused coverage for log output shape

    • New tests in tests/sql-log-format.test.js
    • Verifies:
      • scalar DECLARE generation + type/value formatting
      • TVP formatting includes type path and readable row values (not JSON dump)
      • TVP batching at 100 rows per INSERT
      • preserved multi-line query text
      • formatter usage in all three logging paths
DECLARE @ListParam [dbo].[StringList]
INSERT INTO @ListParam ([Value]) VALUES
('Alpha'),
('Bob''s Item');

DECLARE @Id INT = 7

SELECT *
FROM dbo.Users	WHERE UserId = @Id

Agent-Logs-Url: https://github.com/durlabhjain/dframework-node/sessions/d09a10ce-2641-4551-b0a7-b3f28054ec3b

Co-authored-by: tushar-singh-spraxa <231176744+tushar-singh-spraxa@users.noreply.github.com>
Copilot AI changed the title [WIP] Format SQL query logs with DECLARE statements and multi-line output Format MSSQL query logs as executable multi-line SQL with DECLARE parameter headers May 20, 2026
Copilot AI requested a review from tushar-singh-spraxa May 20, 2026 06:42
@tushar-singh-spraxa
Copy link
Copy Markdown
Collaborator

@copilot formatSqlQueryForLog in lib/sql.js doesn't handle mssql.Table (TVP) parameters — it dumps them as JSON. Add detection via instanceof mssql.Table, then for TVPs generate executable T-SQL: DECLARE @name [schema].[type] using table.path, followed by INSERT INTO @name (col1, col2) VALUES (val1, val2) using table.columns for names and the existing stringifySqlValue for values — batch up to 100 rows per INSERT with multi-row VALUES. Mix TVP DECLARE+INSERT before scalar DECLARE lines. Add a test in tests/sql-log-format.test.js that creates an mssql.Table, passes it as a parameter, and asserts the output contains the type path and readable row values (not JSON).

Agent-Logs-Url: https://github.com/durlabhjain/dframework-node/sessions/fb06d526-c59d-401a-bcc5-1c8281924f0e

Co-authored-by: tushar-singh-spraxa <231176744+tushar-singh-spraxa@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 21, 2026

@copilot formatSqlQueryForLog in lib/sql.js doesn't handle mssql.Table (TVP) parameters — it dumps them as JSON. Add detection via instanceof mssql.Table, then for TVPs generate executable T-SQL: DE...

Implemented in commit 2c2023e.

formatSqlQueryForLog now detects TVPs via descriptor.value instanceof mssql.Table and emits executable TVP SQL before scalar DECLAREs:

  • DECLARE @Param [schema].[Type] (from table.path)
  • INSERT INTO @Param ([col...]) VALUES (...) with multi-row batching at 100 rows per INSERT

I also added tests in tests/sql-log-format.test.js that create real mssql.Table params and verify type path + readable row values are present (and not JSON blobs).

Copilot AI changed the title Format MSSQL query logs as executable multi-line SQL with DECLARE parameter headers Format MSSQL query logs as executable multi-line SQL with DECLARE parameter headers (including TVP support) May 21, 2026
@durlabhjain durlabhjain requested a review from Copilot May 22, 2026 16:22
Copy link
Copy Markdown
Contributor

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 improves MSSQL query logging by formatting logged queries as readable, executable multi-line SQL, including generated DECLARE statements for scalar parameters and expanded TVP (mssql.Table) parameters as DECLARE + batched INSERT statements. It updates the slow-query, threshold logger, and error logger paths to use the new formatter and adds targeted tests to validate the emitted log shape.

Changes:

  • Added formatSqlQueryForLog to generate executable SQL log output (scalar params + TVP support with 100-row batching).
  • Updated MSSQL slow-query, threshold logging (createQueryLogger), and error logging (runQuery catch) to emit formatted SQL.
  • Added tests/sql-log-format.test.js to verify formatting behavior and usage across logging call sites.

Reviewed changes

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

File Description
lib/sql.js Adds SQL log formatting helpers and applies them to query duration, slow-query, and error logging paths.
tests/sql-log-format.test.js Introduces coverage to validate the formatted SQL output (including TVPs and batching) and that all intended log sites use it.

Comment thread lib/sql.js
Comment on lines +61 to +65
if (Buffer.isBuffer(value)) {
return `0x${value.toString('hex')}`;
}
return `'${JSON.stringify(value).replace(/'/g, "''")}'`;
};
Comment thread lib/sql.js
Comment on lines +58 to +60
if (value instanceof Date) {
return `'${dayjs(value).format('YYYY-MM-DD HH:mm:ss.SSS')}'`;
}
Comment thread lib/sql.js Outdated
Comment on lines +151 to +156
const createQueryLogger = function ({ queryLogThreshold, timeoutLogLevel, logger }) {
return async function ({ query, start, end = Date.now(), parameters }) {
const queryDurationInMs = (end - start);
if (queryDurationInMs > queryLogThreshold) {
logger[timeoutLogLevel]({
query: query,
duration: `${queryDurationInMs}ms`,
parameters: parameters
});
const formattedQuery = formatSqlQueryForLog({ query, parameters });
logger[timeoutLogLevel](`SQL query duration ${queryDurationInMs}ms\n${formattedQuery}`);
Comment thread lib/sql.js Outdated
Comment on lines +269 to +270
const formattedQuery = formatSqlQueryForLog({ query, parameters: request.parameters || request.params });
loggerToUse.warn(`Query execution exceeded ${maxQueryTime} milliseconds (${executionTime}ms) [${type}]\n${formattedQuery}`);
@durlabhjain durlabhjain marked this pull request as ready for review May 22, 2026 16:33
Copy link
Copy Markdown
Contributor

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

Comment thread lib/sql.js
}
if (Number.isFinite(parameter?.length)) {
return `${sqlType}(${parameter.length})`;
}
Comment thread lib/sql.js
Comment on lines +165 to +173
const createQueryLogger = function ({ queryLogThreshold, timeoutLogLevel, logger, dialect = 'mssql' }) {
return async function ({ query, start, end = Date.now(), parameters }) {
const queryDurationInMs = (end - start);
if (queryDurationInMs > queryLogThreshold) {
logger[timeoutLogLevel]({
query: query,
duration: `${queryDurationInMs}ms`,
parameters: parameters
});
const formattedQuery = dialect === 'mssql' ? formatSqlQueryForLog({ query, parameters }) : (query || '');
logger[timeoutLogLevel](
{ query, duration: queryDurationInMs, parameters, formattedQuery, dialect },
`SQL query duration ${queryDurationInMs}ms\n${formattedQuery}`
);
Comment thread lib/sql.js
Comment on lines +276 to 278
const formattedQuery = formatSqlQueryForLog({ query, parameters: request.parameters });
loggerToUse.error({ err, type }, `SQL query failed\n${formattedQuery}`);
return { success: false, err, data: {} };
Comment thread lib/sql.js
Comment on lines 282 to +291
logSlowQuery({ startTime, query, type, request }) {
const executionTime = Date.now() - startTime;
if (executionTime > maxQueryTime) { // 500 milliseconds
const loggerToUse = request._logger || this.logger;
loggerToUse.warn({
message: `Query execution exceeded ${maxQueryTime} milliseconds`,
query,
executionTime: `${executionTime}ms`,
type,
parameters: request.parameters || request.params
});
const parameters = request.parameters || request.params;
const formattedQuery = formatSqlQueryForLog({ query, parameters });
loggerToUse.warn(
{ query, type, executionTime, parameters, formattedQuery },
`Query execution exceeded ${maxQueryTime} milliseconds (${executionTime}ms) [${type}]\n${formattedQuery}`
);
Comment thread lib/sql.js Outdated
parameters: request.parameters || request.params
});
const parameters = request.parameters || request.params;
const formattedQuery = formatSqlQueryForLog({ query, parameters });
Agent-Logs-Url: https://github.com/durlabhjain/dframework-node/sessions/6ce515d1-55d5-4f7a-9226-4aa9431a66b3

Co-authored-by: durlabhjain <18685657+durlabhjain@users.noreply.github.com>
Copilot AI and others added 3 commits May 22, 2026 17:04
Agent-Logs-Url: https://github.com/durlabhjain/dframework-node/sessions/6ce515d1-55d5-4f7a-9226-4aa9431a66b3

Co-authored-by: durlabhjain <18685657+durlabhjain@users.noreply.github.com>
Agent-Logs-Url: https://github.com/durlabhjain/dframework-node/sessions/6ce515d1-55d5-4f7a-9226-4aa9431a66b3

Co-authored-by: durlabhjain <18685657+durlabhjain@users.noreply.github.com>
Agent-Logs-Url: https://github.com/durlabhjain/dframework-node/sessions/6ce515d1-55d5-4f7a-9226-4aa9431a66b3

Co-authored-by: durlabhjain <18685657+durlabhjain@users.noreply.github.com>
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.

Format SQL query logs with DECLARE statements and readable multi-line output

3 participants