Skip to content

Commit 528b91f

Browse files
Show warning when SQL notebook result set is incomplete (#21506)
* Show error messages with partial results * Generated loc changes * Add unit tests
1 parent def8b2a commit 528b91f

5 files changed

Lines changed: 119 additions & 0 deletions

File tree

extensions/mssql/l10n/bundle.l10n.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2002,6 +2002,13 @@
20022002
},
20032003
"(Command completed successfully)": "(Command completed successfully)",
20042004
"(0 rows)": "(0 rows)",
2005+
"Warning: Result set is incomplete. Showing {0} of {1} rows. The full result set could not be loaded./{0} is the number of rows actually returned{1} is the total number of rows expected": {
2006+
"message": "Warning: Result set is incomplete. Showing {0} of {1} rows. The full result set could not be loaded.",
2007+
"comment": [
2008+
"{0} is the number of rows actually returned",
2009+
"{1} is the total number of rows expected"
2010+
]
2011+
},
20052012
"({0} row)/{0} is the number of rows (singular)": {
20062013
"message": "({0} row)",
20072014
"comment": ["{0} is the number of rows (singular)"]

extensions/mssql/src/constants/locConstants.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,17 @@ export class Notebooks {
659659
}
660660
public static commandCompletedSuccessfully = l10n.t("(Command completed successfully)");
661661
public static zeroRows = l10n.t("(0 rows)");
662+
public static resultSetTruncated(actual: number, expected: number) {
663+
return l10n.t({
664+
message:
665+
"Warning: Result set is incomplete. Showing {0} of {1} rows. The full result set could not be loaded.",
666+
args: [actual, expected],
667+
comment: [
668+
"{0} is the number of rows actually returned",
669+
"{1} is the total number of rows expected",
670+
],
671+
});
672+
}
662673
public static rowCountPlain(count: number) {
663674
if (count === 1) {
664675
return l10n.t({

extensions/mssql/src/notebooks/sqlNotebookController.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,20 @@ export class SqlNotebookController implements vscode.Disposable {
519519
continue;
520520
}
521521

522+
if (rs.rows.length < rs.rowCount) {
523+
outputs.push(
524+
new vscode.NotebookCellOutput([
525+
vscode.NotebookCellOutputItem.text(
526+
LocalizedConstants.Notebooks.resultSetTruncated(
527+
rs.rows.length,
528+
rs.rowCount,
529+
),
530+
MIME_TEXT_PLAIN,
531+
),
532+
]),
533+
);
534+
}
535+
522536
const plain = formatter.toPlain(rs.columnInfo, rs.rows);
523537
outputs.push(
524538
new vscode.NotebookCellOutput([

extensions/mssql/test/unit/notebooks/sqlNotebookController.test.ts

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,88 @@ suite("SqlNotebookController", () => {
369369

370370
expect(mockExecution.end).to.have.been.calledWith(false, sinon.match.number);
371371
});
372+
373+
test("shows truncation warning when result set is incomplete", async () => {
374+
mockNotebookConnMgr.executeQueryString.resolves(
375+
makeQueryResult({
376+
batches: [
377+
{
378+
batchSummary: makeBatchSummary(),
379+
messages: [],
380+
resultSets: [
381+
{
382+
columnInfo: [makeColumn("id", "int")],
383+
rows: [
384+
[{ displayValue: "1", isNull: false }],
385+
[{ displayValue: "2", isNull: false }],
386+
],
387+
rowCount: 1000, // More rows exist than were returned
388+
},
389+
],
390+
hasError: false,
391+
},
392+
],
393+
}),
394+
);
395+
396+
const notebook = makeNotebook([{ text: "SELECT * FROM LargeTable" }]);
397+
const cells = notebook.getCells();
398+
399+
await mockController.executeHandler(cells, notebook, mockController);
400+
401+
expect(mockExecution.replaceOutput).to.have.been.calledOnce;
402+
const outputs = mockExecution.replaceOutput.firstCall.args[0];
403+
expect(outputs).to.have.lengthOf(2);
404+
405+
// First output should be the truncation warning
406+
const warningOutput = outputs[0];
407+
expect(warningOutput.items[0].mime).to.equal("text/plain");
408+
const warningText = new TextDecoder().decode(warningOutput.items[0].data);
409+
expect(warningText).to.include("Warning: Result set is incomplete");
410+
expect(warningText).to.include("2"); // Actual rows returned
411+
expect(warningText).to.include("1000"); // Total rows available
412+
413+
expect(mockExecution.end).to.have.been.calledWith(true, sinon.match.number);
414+
});
415+
416+
test("does not show truncation warning when result set is complete", async () => {
417+
mockNotebookConnMgr.executeQueryString.resolves(
418+
makeQueryResult({
419+
batches: [
420+
{
421+
batchSummary: makeBatchSummary(),
422+
messages: [],
423+
resultSets: [
424+
{
425+
columnInfo: [makeColumn("id", "int")],
426+
rows: [
427+
[{ displayValue: "1", isNull: false }],
428+
[{ displayValue: "2", isNull: false }],
429+
],
430+
rowCount: 2, // Counts match - no truncation
431+
},
432+
],
433+
hasError: false,
434+
},
435+
],
436+
}),
437+
);
438+
439+
const notebook = makeNotebook([{ text: "SELECT * FROM SmallTable" }]);
440+
const cells = notebook.getCells();
441+
442+
await mockController.executeHandler(cells, notebook, mockController);
443+
444+
expect(mockExecution.replaceOutput).to.have.been.calledOnce;
445+
const outputs = mockExecution.replaceOutput.firstCall.args[0];
446+
expect(outputs).to.have.lengthOf(1); // Only the result set output, no warning
447+
448+
// The output should be the result set, not a warning
449+
const resultOutput = outputs[0];
450+
expect(resultOutput.items[0].mime).to.equal("application/vnd.mssql.query-result");
451+
452+
expect(mockExecution.end).to.have.been.calledWith(true, sinon.match.number);
453+
});
372454
});
373455

374456
suite("executeCell — magic commands", () => {

localization/xliff/vscode-mssql.xlf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6393,6 +6393,11 @@
63936393
<trans-unit id="++CODE++e981ddae45d8f4ca53f1ccbe613ad254a041dacf65a06026099a6302d332113b">
63946394
<source xml:lang="en">Warning</source>
63956395
</trans-unit>
6396+
<trans-unit id="++CODE++4dd8d9584066dcf1db567b8f698595cd5da2385469531e7c7684fa0792be1fcc">
6397+
<source xml:lang="en">Warning: Result set is incomplete. Showing {0} of {1} rows. The full result set could not be loaded.</source>
6398+
<note>{0} is the number of rows actually returned
6399+
{1} is the total number of rows expected</note>
6400+
</trans-unit>
63966401
<trans-unit id="++CODE++4d7371c8931fdd0178f7cbdabd1fd8260039a824a5c0912e880840b4d841f41e">
63976402
<source xml:lang="en">Warnings detected. Please review the changes.</source>
63986403
</trans-unit>

0 commit comments

Comments
 (0)