Skip to content

Commit 2690cec

Browse files
committed
test: #436 add structure guard test for statement isolation
1 parent 81ec301 commit 2690cec

2 files changed

Lines changed: 20 additions & 0 deletions

File tree

src/parser/common/basicSQL.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,8 @@ export abstract class BasicSQL<
559559

560560
/**
561561
* Get the minimum statement tree for collecting completion candidates
562+
* Each supported grammar exposes one top-level statement per direct program child
563+
* Keep the lookup shallow to avoid selecting nested statements or subqueries
562564
*/
563565
private getSuggestionParseTree(
564566
parseTree: ParserRuleContext,
@@ -605,6 +607,7 @@ export abstract class BasicSQL<
605607

606608
if (suggestionParseTree === parseTree) return candidates;
607609

610+
// Keep the program candidates for outer rule paths and use statement candidates for isolation
608611
const statementCore = new CodeCompletionCore(parser);
609612
statementCore.preferredRules = this.preferredRules;
610613
const statementCandidates = statementCore.collectCandidates(

test/common/suggestion.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { ParserRuleContext } from 'antlr4ng';
2+
13
import {
24
FlinkSQL,
35
GenericSQL,
@@ -20,6 +22,21 @@ const dialects = [
2022
['GenericSQL', () => new GenericSQL()],
2123
] as const;
2224

25+
test.each(dialects)(
26+
'%s exposes each top-level statement as a direct program child',
27+
(_, createParser) => {
28+
const parseTree = createParser().parse('SELECT * FROM t; SELECT * FROM u');
29+
const topLevelStatements =
30+
parseTree.children?.filter((child) => child instanceof ParserRuleContext) ?? [];
31+
32+
expect(topLevelStatements).toHaveLength(2);
33+
expect(topLevelStatements.map((statement) => statement.getText())).toEqual([
34+
'SELECT*FROMt;',
35+
'SELECT*FROMu',
36+
]);
37+
}
38+
);
39+
2340
describe.each(dialects)('%s suggestion at caret position', (_, createParser) => {
2441
const parser = createParser();
2542

0 commit comments

Comments
 (0)