From d470e7278937297372d0b94656ee0fc19a0b9f8d Mon Sep 17 00:00:00 2001 From: liuxy0551 Date: Thu, 29 May 2025 20:02:04 +0800 Subject: [PATCH 1/2] test: #424 syntax after comments --- .../completeAfterSyntaxError.test.ts | 16 +++++++ .../flink/suggestion/syntaxSuggestion.test.ts | 48 +++++++++++++++++++ .../completeAfterSyntaxError.test.ts | 16 +++++++ .../hive/suggestion/syntaxSuggestion.test.ts | 48 +++++++++++++++++++ .../completeAfterSyntaxError.test.ts | 16 +++++++ .../suggestion/syntaxSuggestion.test.ts | 48 +++++++++++++++++++ .../completeAfterSyntaxError.test.ts | 16 +++++++ .../mysql/suggestion/syntaxSuggestion.test.ts | 48 +++++++++++++++++++ .../completeAfterSyntaxError.test.ts | 16 +++++++ .../suggestion/syntaxSuggestion.test.ts | 48 +++++++++++++++++++ .../completeAfterSyntaxError.test.ts | 16 +++++++ .../spark/suggestion/syntaxSuggestion.test.ts | 48 +++++++++++++++++++ .../completeAfterSyntaxError.test.ts | 16 +++++++ .../trino/suggestion/syntaxSuggestion.test.ts | 48 +++++++++++++++++++ 14 files changed, 448 insertions(+) diff --git a/test/parser/flink/suggestion/completeAfterSyntaxError.test.ts b/test/parser/flink/suggestion/completeAfterSyntaxError.test.ts index a6def22a4..1b593a97b 100644 --- a/test/parser/flink/suggestion/completeAfterSyntaxError.test.ts +++ b/test/parser/flink/suggestion/completeAfterSyntaxError.test.ts @@ -7,6 +7,7 @@ describe('FlinkSQL Complete After Syntax Error', () => { const sql1 = `SELECT FROM tb2;\nINSERT INTO `; const sql2 = `SELECT FROM tb3;\nCREATE TABLE `; const sql3 = `SELECT FROM t1;\nSL`; + const sql4 = `SELECT FROM t1;\n-- the comment 1\n-- the comment 2\nSELECT * FROM db.`; test('Syntax error but end with semi, should suggest tableName', () => { const pos: CaretPosition = { @@ -62,4 +63,19 @@ describe('FlinkSQL Complete After Syntax Error', () => { ); expect(filterKeywords).toMatchUnorderedArray(['SELECT']); }); + + test('Syntax suggestion after error and comments', () => { + const pos: CaretPosition = { + lineNumber: 4, + column: 18, + }; + const syntaxes = flink.getSuggestionAtCaretPosition(sql4, pos)?.syntax; + const suggestion = syntaxes?.find( + (syn) => syn.syntaxContextType === EntityContextType.TABLE + ); + + // syntax + expect(suggestion).not.toBeUndefined(); + expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']); + }); }); diff --git a/test/parser/flink/suggestion/syntaxSuggestion.test.ts b/test/parser/flink/suggestion/syntaxSuggestion.test.ts index 7a6dd0046..bd3d9b79b 100644 --- a/test/parser/flink/suggestion/syntaxSuggestion.test.ts +++ b/test/parser/flink/suggestion/syntaxSuggestion.test.ts @@ -497,4 +497,52 @@ describe('Flink SQL Syntax Suggestion', () => { expect(suggestion[0].syntaxContextType).toBe(scenario.entityContextType); }); }); + + test('Syntax suggestion after a comment', () => { + const sql = `-- the comment\nSELECT * FROM db.`; + const pos: CaretPosition = { + lineNumber: 2, + column: 18, + }; + + const syntaxes = flink.getSuggestionAtCaretPosition(sql, pos)?.syntax; + const suggestion = syntaxes?.find( + (syn) => syn.syntaxContextType === EntityContextType.TABLE + ); + + expect(suggestion).not.toBeUndefined(); + expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']); + }); + + test('Syntax suggestion after comments', () => { + const sql = `-- the comment 1\n-- the comment 2\nSELECT * FROM db.`; + const pos: CaretPosition = { + lineNumber: 3, + column: 18, + }; + + const syntaxes = flink.getSuggestionAtCaretPosition(sql, pos)?.syntax; + const suggestion = syntaxes?.find( + (syn) => syn.syntaxContextType === EntityContextType.TABLE + ); + + expect(suggestion).not.toBeUndefined(); + expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']); + }); + + test('Syntax suggestion after comments', () => { + const sql = `-- SELECT FROM t1;\n-- the comment 1\n-- the comment 2\nSELECT * FROM db.`; + const pos: CaretPosition = { + lineNumber: 4, + column: 18, + }; + + const syntaxes = flink.getSuggestionAtCaretPosition(sql, pos)?.syntax; + const suggestion = syntaxes?.find( + (syn) => syn.syntaxContextType === EntityContextType.TABLE + ); + + expect(suggestion).not.toBeUndefined(); + expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']); + }); }); diff --git a/test/parser/hive/suggestion/completeAfterSyntaxError.test.ts b/test/parser/hive/suggestion/completeAfterSyntaxError.test.ts index 93e7f9af0..a30c4ac2b 100644 --- a/test/parser/hive/suggestion/completeAfterSyntaxError.test.ts +++ b/test/parser/hive/suggestion/completeAfterSyntaxError.test.ts @@ -7,6 +7,7 @@ describe('HiveSQL Complete After Syntax Error', () => { const sql1 = `SELECT FROM tb2;\nINSERT INTO `; const sql2 = `SELECT FROM tb3;\nCREATE TABLE `; const sql3 = `SELECT FROM t1;\nSL`; + const sql4 = `SELECT FROM t1;\n-- the comment 1\n-- the comment 2\nSELECT * FROM db.`; test('Syntax error but end with semi, should suggest tableName', () => { const pos: CaretPosition = { @@ -63,4 +64,19 @@ describe('HiveSQL Complete After Syntax Error', () => { ); expect(filterKeywords).toMatchUnorderedArray(['SELECT']); }); + + test('Syntax suggestion after error and comments', () => { + const pos: CaretPosition = { + lineNumber: 4, + column: 18, + }; + const syntaxes = hive.getSuggestionAtCaretPosition(sql4, pos)?.syntax; + const suggestion = syntaxes?.find( + (syn) => syn.syntaxContextType === EntityContextType.TABLE + ); + + // syntax + expect(suggestion).not.toBeUndefined(); + expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']); + }); }); diff --git a/test/parser/hive/suggestion/syntaxSuggestion.test.ts b/test/parser/hive/suggestion/syntaxSuggestion.test.ts index 2013d5788..764c90eba 100644 --- a/test/parser/hive/suggestion/syntaxSuggestion.test.ts +++ b/test/parser/hive/suggestion/syntaxSuggestion.test.ts @@ -591,4 +591,52 @@ describe('Hive SQL Syntax Suggestion', () => { expect(suggestion).not.toBeUndefined(); expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['month']); }); + + test('Syntax suggestion after a comment', () => { + const sql = `-- the comment\nSELECT * FROM db.`; + const pos: CaretPosition = { + lineNumber: 2, + column: 18, + }; + + const syntaxes = hive.getSuggestionAtCaretPosition(sql, pos)?.syntax; + const suggestion = syntaxes?.find( + (syn) => syn.syntaxContextType === EntityContextType.TABLE + ); + + expect(suggestion).not.toBeUndefined(); + expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']); + }); + + test('Syntax suggestion after comments', () => { + const sql = `-- the comment 1\n-- the comment 2\nSELECT * FROM db.`; + const pos: CaretPosition = { + lineNumber: 3, + column: 18, + }; + + const syntaxes = hive.getSuggestionAtCaretPosition(sql, pos)?.syntax; + const suggestion = syntaxes?.find( + (syn) => syn.syntaxContextType === EntityContextType.TABLE + ); + + expect(suggestion).not.toBeUndefined(); + expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']); + }); + + test('Syntax suggestion after comments', () => { + const sql = `-- SELECT FROM t1;\n-- the comment 1\n-- the comment 2\nSELECT * FROM db.`; + const pos: CaretPosition = { + lineNumber: 4, + column: 18, + }; + + const syntaxes = hive.getSuggestionAtCaretPosition(sql, pos)?.syntax; + const suggestion = syntaxes?.find( + (syn) => syn.syntaxContextType === EntityContextType.TABLE + ); + + expect(suggestion).not.toBeUndefined(); + expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']); + }); }); diff --git a/test/parser/impala/suggestion/completeAfterSyntaxError.test.ts b/test/parser/impala/suggestion/completeAfterSyntaxError.test.ts index 792e87c68..7ea9ce5cd 100644 --- a/test/parser/impala/suggestion/completeAfterSyntaxError.test.ts +++ b/test/parser/impala/suggestion/completeAfterSyntaxError.test.ts @@ -7,6 +7,7 @@ describe('ImpalaSQL Complete After Syntax Error', () => { const sql1 = `SELECT FROM tb2;\nINSERT INTO `; const sql2 = `SELECT FROM tb3;\nCREATE TABLE `; const sql3 = `SELECT FROM t1;\nSL`; + const sql4 = `SELECT FROM t1;\n-- the comment 1\n-- the comment 2\nSELECT * FROM db.`; test('Syntax error but end with semi, should suggest tableName', () => { const pos: CaretPosition = { @@ -63,4 +64,19 @@ describe('ImpalaSQL Complete After Syntax Error', () => { ); expect(filterKeywords).toMatchUnorderedArray(['SELECT']); }); + + test('Syntax suggestion after error and comments', () => { + const pos: CaretPosition = { + lineNumber: 4, + column: 18, + }; + const syntaxes = impala.getSuggestionAtCaretPosition(sql4, pos)?.syntax; + const suggestion = syntaxes?.find( + (syn) => syn.syntaxContextType === EntityContextType.TABLE + ); + + // syntax + expect(suggestion).not.toBeUndefined(); + expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']); + }); }); diff --git a/test/parser/impala/suggestion/syntaxSuggestion.test.ts b/test/parser/impala/suggestion/syntaxSuggestion.test.ts index 02cf8d4de..d2cb2a620 100644 --- a/test/parser/impala/suggestion/syntaxSuggestion.test.ts +++ b/test/parser/impala/suggestion/syntaxSuggestion.test.ts @@ -462,4 +462,52 @@ describe('Impala SQL Syntax Suggestion', () => { expect(suggestion).not.toBeUndefined(); expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['YEAR']); }); + + test('Syntax suggestion after a comment', () => { + const sql = `-- the comment\nSELECT * FROM db.`; + const pos: CaretPosition = { + lineNumber: 2, + column: 18, + }; + + const syntaxes = impala.getSuggestionAtCaretPosition(sql, pos)?.syntax; + const suggestion = syntaxes?.find( + (syn) => syn.syntaxContextType === EntityContextType.TABLE + ); + + expect(suggestion).not.toBeUndefined(); + expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']); + }); + + test('Syntax suggestion after comments', () => { + const sql = `-- the comment 1\n-- the comment 2\nSELECT * FROM db.`; + const pos: CaretPosition = { + lineNumber: 3, + column: 18, + }; + + const syntaxes = impala.getSuggestionAtCaretPosition(sql, pos)?.syntax; + const suggestion = syntaxes?.find( + (syn) => syn.syntaxContextType === EntityContextType.TABLE + ); + + expect(suggestion).not.toBeUndefined(); + expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']); + }); + + test('Syntax suggestion after comments', () => { + const sql = `-- SELECT FROM t1;\n-- the comment 1\n-- the comment 2\nSELECT * FROM db.`; + const pos: CaretPosition = { + lineNumber: 4, + column: 18, + }; + + const syntaxes = impala.getSuggestionAtCaretPosition(sql, pos)?.syntax; + const suggestion = syntaxes?.find( + (syn) => syn.syntaxContextType === EntityContextType.TABLE + ); + + expect(suggestion).not.toBeUndefined(); + expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']); + }); }); diff --git a/test/parser/mysql/suggestion/completeAfterSyntaxError.test.ts b/test/parser/mysql/suggestion/completeAfterSyntaxError.test.ts index 7f5acc4a4..38fc56bf0 100644 --- a/test/parser/mysql/suggestion/completeAfterSyntaxError.test.ts +++ b/test/parser/mysql/suggestion/completeAfterSyntaxError.test.ts @@ -7,6 +7,7 @@ describe('MySQL Complete After Syntax Error', () => { const sql1 = `SELECT FROM tb2;\nINSERT INTO `; const sql2 = `SELECT FROM tb3;\nCREATE TABLE `; const sql3 = `SELECT FROM t1;\nSL`; + const sql4 = `SELECT FROM t1;\n-- the comment 1\n-- the comment 2\nSELECT * FROM db.`; test('Syntax error but end with semi, should suggest tableName', () => { const pos: CaretPosition = { @@ -62,4 +63,19 @@ describe('MySQL Complete After Syntax Error', () => { ); expect(filterKeywords).toMatchUnorderedArray(['SELECT', 'SIGNAL']); }); + + test('Syntax suggestion after error and comments', () => { + const pos: CaretPosition = { + lineNumber: 4, + column: 18, + }; + const syntaxes = mysql.getSuggestionAtCaretPosition(sql4, pos)?.syntax; + const suggestion = syntaxes?.find( + (syn) => syn.syntaxContextType === EntityContextType.TABLE + ); + + // syntax + expect(suggestion).not.toBeUndefined(); + expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']); + }); }); diff --git a/test/parser/mysql/suggestion/syntaxSuggestion.test.ts b/test/parser/mysql/suggestion/syntaxSuggestion.test.ts index 98bb48521..ea0f6d663 100644 --- a/test/parser/mysql/suggestion/syntaxSuggestion.test.ts +++ b/test/parser/mysql/suggestion/syntaxSuggestion.test.ts @@ -640,4 +640,52 @@ describe('MySQL Syntax Suggestion', () => { expect(suggestion).not.toBeUndefined(); expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['score']); }); + + test('Syntax suggestion after a comment', () => { + const sql = `-- the comment\nSELECT * FROM db.`; + const pos: CaretPosition = { + lineNumber: 2, + column: 18, + }; + + const syntaxes = mysql.getSuggestionAtCaretPosition(sql, pos)?.syntax; + const suggestion = syntaxes?.find( + (syn) => syn.syntaxContextType === EntityContextType.TABLE + ); + + expect(suggestion).not.toBeUndefined(); + expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']); + }); + + test('Syntax suggestion after comments', () => { + const sql = `-- the comment 1\n-- the comment 2\nSELECT * FROM db.`; + const pos: CaretPosition = { + lineNumber: 3, + column: 18, + }; + + const syntaxes = mysql.getSuggestionAtCaretPosition(sql, pos)?.syntax; + const suggestion = syntaxes?.find( + (syn) => syn.syntaxContextType === EntityContextType.TABLE + ); + + expect(suggestion).not.toBeUndefined(); + expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']); + }); + + test('Syntax suggestion after comments', () => { + const sql = `-- SELECT FROM t1;\n-- the comment 1\n-- the comment 2\nSELECT * FROM db.`; + const pos: CaretPosition = { + lineNumber: 4, + column: 18, + }; + + const syntaxes = mysql.getSuggestionAtCaretPosition(sql, pos)?.syntax; + const suggestion = syntaxes?.find( + (syn) => syn.syntaxContextType === EntityContextType.TABLE + ); + + expect(suggestion).not.toBeUndefined(); + expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']); + }); }); diff --git a/test/parser/postgresql/suggestion/completeAfterSyntaxError.test.ts b/test/parser/postgresql/suggestion/completeAfterSyntaxError.test.ts index 07f5ddac8..09b2ffeb6 100644 --- a/test/parser/postgresql/suggestion/completeAfterSyntaxError.test.ts +++ b/test/parser/postgresql/suggestion/completeAfterSyntaxError.test.ts @@ -7,6 +7,7 @@ describe('PostgreSQL Complete After Syntax Error', () => { const sql1 = `SELECT FROM tb2;\nINSERT INTO `; const sql2 = `SELECT FROM tb3;\nCREATE TABLE `; const sql3 = `SELECT FROM t1;\nSL`; + const sql4 = `SELECT FROM t1;\n-- the comment 1\n-- the comment 2\nSELECT * FROM db.`; test('Syntax error but end with semi, should suggest tableName', () => { const pos: CaretPosition = { @@ -62,4 +63,19 @@ describe('PostgreSQL Complete After Syntax Error', () => { ); expect(filterKeywords).toMatchUnorderedArray(['SELECT']); }); + + test('Syntax suggestion after error and comments', () => { + const pos: CaretPosition = { + lineNumber: 4, + column: 18, + }; + const syntaxes = postgresql.getSuggestionAtCaretPosition(sql4, pos)?.syntax; + const suggestion = syntaxes?.find( + (syn) => syn.syntaxContextType === EntityContextType.TABLE + ); + + // syntax + expect(suggestion).not.toBeUndefined(); + expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']); + }); }); diff --git a/test/parser/postgresql/suggestion/syntaxSuggestion.test.ts b/test/parser/postgresql/suggestion/syntaxSuggestion.test.ts index abc906ba1..4e80d5991 100644 --- a/test/parser/postgresql/suggestion/syntaxSuggestion.test.ts +++ b/test/parser/postgresql/suggestion/syntaxSuggestion.test.ts @@ -1142,4 +1142,52 @@ describe('Postgre SQL Syntax Suggestion', () => { expect(suggestion).not.toBeUndefined(); expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['depname']); }); + + test('Syntax suggestion after a comment', () => { + const sql = `-- the comment\nSELECT * FROM db.`; + const pos: CaretPosition = { + lineNumber: 2, + column: 18, + }; + + const syntaxes = postgresql.getSuggestionAtCaretPosition(sql, pos)?.syntax; + const suggestion = syntaxes?.find( + (syn) => syn.syntaxContextType === EntityContextType.TABLE + ); + + expect(suggestion).not.toBeUndefined(); + expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']); + }); + + test('Syntax suggestion after comments', () => { + const sql = `-- the comment 1\n-- the comment 2\nSELECT * FROM db.`; + const pos: CaretPosition = { + lineNumber: 3, + column: 18, + }; + + const syntaxes = postgresql.getSuggestionAtCaretPosition(sql, pos)?.syntax; + const suggestion = syntaxes?.find( + (syn) => syn.syntaxContextType === EntityContextType.TABLE + ); + + expect(suggestion).not.toBeUndefined(); + expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']); + }); + + test('Syntax suggestion after comments', () => { + const sql = `-- SELECT FROM t1;\n-- the comment 1\n-- the comment 2\nSELECT * FROM db.`; + const pos: CaretPosition = { + lineNumber: 4, + column: 18, + }; + + const syntaxes = postgresql.getSuggestionAtCaretPosition(sql, pos)?.syntax; + const suggestion = syntaxes?.find( + (syn) => syn.syntaxContextType === EntityContextType.TABLE + ); + + expect(suggestion).not.toBeUndefined(); + expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']); + }); }); diff --git a/test/parser/spark/suggestion/completeAfterSyntaxError.test.ts b/test/parser/spark/suggestion/completeAfterSyntaxError.test.ts index fde5b27d3..96c1ba165 100644 --- a/test/parser/spark/suggestion/completeAfterSyntaxError.test.ts +++ b/test/parser/spark/suggestion/completeAfterSyntaxError.test.ts @@ -7,6 +7,7 @@ describe('SparkSQL Complete After Syntax Error', () => { const sql1 = `SELECT FROM tb2;\nINSERT INTO `; const sql2 = `SELECT FROM tb3;\nCREATE TABLE `; const sql3 = `SELECT FROM t1;\nSL`; + const sql4 = `SELECT FROM t1;\n-- the comment 1\n-- the comment 2\nSELECT * FROM db.`; test('Syntax error but end with semi, should suggest tableName', () => { const pos: CaretPosition = { @@ -63,4 +64,19 @@ describe('SparkSQL Complete After Syntax Error', () => { ); expect(filterKeywords).toMatchUnorderedArray(['SELECT']); }); + + test('Syntax suggestion after error and comments', () => { + const pos: CaretPosition = { + lineNumber: 4, + column: 18, + }; + const syntaxes = spark.getSuggestionAtCaretPosition(sql4, pos)?.syntax; + const suggestion = syntaxes?.find( + (syn) => syn.syntaxContextType === EntityContextType.TABLE + ); + + // syntax + expect(suggestion).not.toBeUndefined(); + expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']); + }); }); diff --git a/test/parser/spark/suggestion/syntaxSuggestion.test.ts b/test/parser/spark/suggestion/syntaxSuggestion.test.ts index 4bb8245f0..207cb550a 100644 --- a/test/parser/spark/suggestion/syntaxSuggestion.test.ts +++ b/test/parser/spark/suggestion/syntaxSuggestion.test.ts @@ -761,4 +761,52 @@ describe('Spark SQL Syntax Suggestion', () => { expect(suggestion).not.toBeUndefined(); expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['quantity']); }); + + test('Syntax suggestion after a comment', () => { + const sql = `-- the comment\nSELECT * FROM db.`; + const pos: CaretPosition = { + lineNumber: 2, + column: 18, + }; + + const syntaxes = spark.getSuggestionAtCaretPosition(sql, pos)?.syntax; + const suggestion = syntaxes?.find( + (syn) => syn.syntaxContextType === EntityContextType.TABLE + ); + + expect(suggestion).not.toBeUndefined(); + expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']); + }); + + test('Syntax suggestion after comments', () => { + const sql = `-- the comment 1\n-- the comment 2\nSELECT * FROM db.`; + const pos: CaretPosition = { + lineNumber: 3, + column: 18, + }; + + const syntaxes = spark.getSuggestionAtCaretPosition(sql, pos)?.syntax; + const suggestion = syntaxes?.find( + (syn) => syn.syntaxContextType === EntityContextType.TABLE + ); + + expect(suggestion).not.toBeUndefined(); + expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']); + }); + + test('Syntax suggestion after comments', () => { + const sql = `-- SELECT FROM t1;\n-- the comment 1\n-- the comment 2\nSELECT * FROM db.`; + const pos: CaretPosition = { + lineNumber: 4, + column: 18, + }; + + const syntaxes = spark.getSuggestionAtCaretPosition(sql, pos)?.syntax; + const suggestion = syntaxes?.find( + (syn) => syn.syntaxContextType === EntityContextType.TABLE + ); + + expect(suggestion).not.toBeUndefined(); + expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']); + }); }); diff --git a/test/parser/trino/suggestion/completeAfterSyntaxError.test.ts b/test/parser/trino/suggestion/completeAfterSyntaxError.test.ts index 59f33213d..4a38a64a8 100644 --- a/test/parser/trino/suggestion/completeAfterSyntaxError.test.ts +++ b/test/parser/trino/suggestion/completeAfterSyntaxError.test.ts @@ -7,6 +7,7 @@ describe('TrinoSQL Complete After Syntax Error', () => { const sql1 = `SELECT FROM tb2;\nINSERT INTO `; const sql2 = `SELECT FROM tb3;\nCREATE TABLE `; const sql3 = `SELECT FROM t1;\nSL`; + const sql4 = `SELECT FROM t1;\n-- the comment 1\n-- the comment 2\nSELECT * FROM db.`; test('Syntax error but end with semi, should suggest tableName', () => { const pos: CaretPosition = { @@ -62,4 +63,19 @@ describe('TrinoSQL Complete After Syntax Error', () => { ); expect(filterKeywords).toMatchUnorderedArray(['SELECT']); }); + + test('Syntax suggestion after error and comments', () => { + const pos: CaretPosition = { + lineNumber: 4, + column: 18, + }; + const syntaxes = trino.getSuggestionAtCaretPosition(sql4, pos)?.syntax; + const suggestion = syntaxes?.find( + (syn) => syn.syntaxContextType === EntityContextType.TABLE + ); + + // syntax + expect(suggestion).not.toBeUndefined(); + expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']); + }); }); diff --git a/test/parser/trino/suggestion/syntaxSuggestion.test.ts b/test/parser/trino/suggestion/syntaxSuggestion.test.ts index 864ba7518..947e27da1 100644 --- a/test/parser/trino/suggestion/syntaxSuggestion.test.ts +++ b/test/parser/trino/suggestion/syntaxSuggestion.test.ts @@ -564,4 +564,52 @@ describe('Trino SQL Syntax Suggestion', () => { expect(suggestion).not.toBeUndefined(); expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['friends']); }); + + test('Syntax suggestion after a comment', () => { + const sql = `-- the comment\nSELECT * FROM db.`; + const pos: CaretPosition = { + lineNumber: 2, + column: 18, + }; + + const syntaxes = trino.getSuggestionAtCaretPosition(sql, pos)?.syntax; + const suggestion = syntaxes?.find( + (syn) => syn.syntaxContextType === EntityContextType.TABLE + ); + + expect(suggestion).not.toBeUndefined(); + expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']); + }); + + test('Syntax suggestion after comments', () => { + const sql = `-- the comment 1\n-- the comment 2\nSELECT * FROM db.`; + const pos: CaretPosition = { + lineNumber: 3, + column: 18, + }; + + const syntaxes = trino.getSuggestionAtCaretPosition(sql, pos)?.syntax; + const suggestion = syntaxes?.find( + (syn) => syn.syntaxContextType === EntityContextType.TABLE + ); + + expect(suggestion).not.toBeUndefined(); + expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']); + }); + + test('Syntax suggestion after comments', () => { + const sql = `-- SELECT FROM t1;\n-- the comment 1\n-- the comment 2\nSELECT * FROM db.`; + const pos: CaretPosition = { + lineNumber: 4, + column: 18, + }; + + const syntaxes = trino.getSuggestionAtCaretPosition(sql, pos)?.syntax; + const suggestion = syntaxes?.find( + (syn) => syn.syntaxContextType === EntityContextType.TABLE + ); + + expect(suggestion).not.toBeUndefined(); + expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']); + }); }); From 84562b11f1f5c77324d0b44e048834231adb2129 Mon Sep 17 00:00:00 2001 From: liuxy0551 Date: Thu, 29 May 2025 20:03:25 +0800 Subject: [PATCH 2/2] fix(common): #424 allTokens slice when caretTokenIndex use tokenIndexOffset --- src/parser/common/basicSQL.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/parser/common/basicSQL.ts b/src/parser/common/basicSQL.ts index db0e4f88d..385ab2dcc 100644 --- a/src/parser/common/basicSQL.ts +++ b/src/parser/common/basicSQL.ts @@ -414,7 +414,7 @@ export abstract class BasicSQL< // A boundary consisting of the index of the input. const startIndex = startStatement?.start?.start ?? 0; - const stopIndex = stopStatement?.stop?.stop ?? inputSlice.length - 1; + const stopIndex = stopStatement?.stop?.stop ?? inputSlice.length; /** * Save offset of the tokenIndex in the range of input @@ -518,6 +518,7 @@ export abstract class BasicSQL< } else { if (statementCount > 1) { caretTokenIndex = caretTokenIndex - tokenIndexOffset; + allTokens = allTokens.slice(tokenIndexOffset); } }