Skip to content

Commit 616dc11

Browse files
authored
fix(common): #424 allTokens slice when caretTokenIndex use tokenIndexOffset (#426)
* test: #424 syntax after comments * fix(common): #424 allTokens slice when caretTokenIndex use tokenIndexOffset
1 parent db8a707 commit 616dc11

15 files changed

+450
-1
lines changed

src/parser/common/basicSQL.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ export abstract class BasicSQL<
414414

415415
// A boundary consisting of the index of the input.
416416
const startIndex = startStatement?.start?.start ?? 0;
417-
const stopIndex = stopStatement?.stop?.stop ?? inputSlice.length - 1;
417+
const stopIndex = stopStatement?.stop?.stop ?? inputSlice.length;
418418

419419
/**
420420
* Save offset of the tokenIndex in the range of input
@@ -518,6 +518,7 @@ export abstract class BasicSQL<
518518
} else {
519519
if (statementCount > 1) {
520520
caretTokenIndex = caretTokenIndex - tokenIndexOffset;
521+
allTokens = allTokens.slice(tokenIndexOffset);
521522
}
522523
}
523524

test/parser/flink/suggestion/completeAfterSyntaxError.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ describe('FlinkSQL Complete After Syntax Error', () => {
77
const sql1 = `SELECT FROM tb2;\nINSERT INTO `;
88
const sql2 = `SELECT FROM tb3;\nCREATE TABLE `;
99
const sql3 = `SELECT FROM t1;\nSL`;
10+
const sql4 = `SELECT FROM t1;\n-- the comment 1\n-- the comment 2\nSELECT * FROM db.`;
1011

1112
test('Syntax error but end with semi, should suggest tableName', () => {
1213
const pos: CaretPosition = {
@@ -62,4 +63,19 @@ describe('FlinkSQL Complete After Syntax Error', () => {
6263
);
6364
expect(filterKeywords).toMatchUnorderedArray(['SELECT']);
6465
});
66+
67+
test('Syntax suggestion after error and comments', () => {
68+
const pos: CaretPosition = {
69+
lineNumber: 4,
70+
column: 18,
71+
};
72+
const syntaxes = flink.getSuggestionAtCaretPosition(sql4, pos)?.syntax;
73+
const suggestion = syntaxes?.find(
74+
(syn) => syn.syntaxContextType === EntityContextType.TABLE
75+
);
76+
77+
// syntax
78+
expect(suggestion).not.toBeUndefined();
79+
expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']);
80+
});
6581
});

test/parser/flink/suggestion/syntaxSuggestion.test.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,4 +497,52 @@ describe('Flink SQL Syntax Suggestion', () => {
497497
expect(suggestion[0].syntaxContextType).toBe(scenario.entityContextType);
498498
});
499499
});
500+
501+
test('Syntax suggestion after a comment', () => {
502+
const sql = `-- the comment\nSELECT * FROM db.`;
503+
const pos: CaretPosition = {
504+
lineNumber: 2,
505+
column: 18,
506+
};
507+
508+
const syntaxes = flink.getSuggestionAtCaretPosition(sql, pos)?.syntax;
509+
const suggestion = syntaxes?.find(
510+
(syn) => syn.syntaxContextType === EntityContextType.TABLE
511+
);
512+
513+
expect(suggestion).not.toBeUndefined();
514+
expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']);
515+
});
516+
517+
test('Syntax suggestion after comments', () => {
518+
const sql = `-- the comment 1\n-- the comment 2\nSELECT * FROM db.`;
519+
const pos: CaretPosition = {
520+
lineNumber: 3,
521+
column: 18,
522+
};
523+
524+
const syntaxes = flink.getSuggestionAtCaretPosition(sql, pos)?.syntax;
525+
const suggestion = syntaxes?.find(
526+
(syn) => syn.syntaxContextType === EntityContextType.TABLE
527+
);
528+
529+
expect(suggestion).not.toBeUndefined();
530+
expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']);
531+
});
532+
533+
test('Syntax suggestion after comments', () => {
534+
const sql = `-- SELECT FROM t1;\n-- the comment 1\n-- the comment 2\nSELECT * FROM db.`;
535+
const pos: CaretPosition = {
536+
lineNumber: 4,
537+
column: 18,
538+
};
539+
540+
const syntaxes = flink.getSuggestionAtCaretPosition(sql, pos)?.syntax;
541+
const suggestion = syntaxes?.find(
542+
(syn) => syn.syntaxContextType === EntityContextType.TABLE
543+
);
544+
545+
expect(suggestion).not.toBeUndefined();
546+
expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']);
547+
});
500548
});

test/parser/hive/suggestion/completeAfterSyntaxError.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ describe('HiveSQL Complete After Syntax Error', () => {
77
const sql1 = `SELECT FROM tb2;\nINSERT INTO `;
88
const sql2 = `SELECT FROM tb3;\nCREATE TABLE `;
99
const sql3 = `SELECT FROM t1;\nSL`;
10+
const sql4 = `SELECT FROM t1;\n-- the comment 1\n-- the comment 2\nSELECT * FROM db.`;
1011

1112
test('Syntax error but end with semi, should suggest tableName', () => {
1213
const pos: CaretPosition = {
@@ -63,4 +64,19 @@ describe('HiveSQL Complete After Syntax Error', () => {
6364
);
6465
expect(filterKeywords).toMatchUnorderedArray(['SELECT']);
6566
});
67+
68+
test('Syntax suggestion after error and comments', () => {
69+
const pos: CaretPosition = {
70+
lineNumber: 4,
71+
column: 18,
72+
};
73+
const syntaxes = hive.getSuggestionAtCaretPosition(sql4, pos)?.syntax;
74+
const suggestion = syntaxes?.find(
75+
(syn) => syn.syntaxContextType === EntityContextType.TABLE
76+
);
77+
78+
// syntax
79+
expect(suggestion).not.toBeUndefined();
80+
expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']);
81+
});
6682
});

test/parser/hive/suggestion/syntaxSuggestion.test.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,4 +591,52 @@ describe('Hive SQL Syntax Suggestion', () => {
591591
expect(suggestion).not.toBeUndefined();
592592
expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['month']);
593593
});
594+
595+
test('Syntax suggestion after a comment', () => {
596+
const sql = `-- the comment\nSELECT * FROM db.`;
597+
const pos: CaretPosition = {
598+
lineNumber: 2,
599+
column: 18,
600+
};
601+
602+
const syntaxes = hive.getSuggestionAtCaretPosition(sql, pos)?.syntax;
603+
const suggestion = syntaxes?.find(
604+
(syn) => syn.syntaxContextType === EntityContextType.TABLE
605+
);
606+
607+
expect(suggestion).not.toBeUndefined();
608+
expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']);
609+
});
610+
611+
test('Syntax suggestion after comments', () => {
612+
const sql = `-- the comment 1\n-- the comment 2\nSELECT * FROM db.`;
613+
const pos: CaretPosition = {
614+
lineNumber: 3,
615+
column: 18,
616+
};
617+
618+
const syntaxes = hive.getSuggestionAtCaretPosition(sql, pos)?.syntax;
619+
const suggestion = syntaxes?.find(
620+
(syn) => syn.syntaxContextType === EntityContextType.TABLE
621+
);
622+
623+
expect(suggestion).not.toBeUndefined();
624+
expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']);
625+
});
626+
627+
test('Syntax suggestion after comments', () => {
628+
const sql = `-- SELECT FROM t1;\n-- the comment 1\n-- the comment 2\nSELECT * FROM db.`;
629+
const pos: CaretPosition = {
630+
lineNumber: 4,
631+
column: 18,
632+
};
633+
634+
const syntaxes = hive.getSuggestionAtCaretPosition(sql, pos)?.syntax;
635+
const suggestion = syntaxes?.find(
636+
(syn) => syn.syntaxContextType === EntityContextType.TABLE
637+
);
638+
639+
expect(suggestion).not.toBeUndefined();
640+
expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']);
641+
});
594642
});

test/parser/impala/suggestion/completeAfterSyntaxError.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ describe('ImpalaSQL Complete After Syntax Error', () => {
77
const sql1 = `SELECT FROM tb2;\nINSERT INTO `;
88
const sql2 = `SELECT FROM tb3;\nCREATE TABLE `;
99
const sql3 = `SELECT FROM t1;\nSL`;
10+
const sql4 = `SELECT FROM t1;\n-- the comment 1\n-- the comment 2\nSELECT * FROM db.`;
1011

1112
test('Syntax error but end with semi, should suggest tableName', () => {
1213
const pos: CaretPosition = {
@@ -63,4 +64,19 @@ describe('ImpalaSQL Complete After Syntax Error', () => {
6364
);
6465
expect(filterKeywords).toMatchUnorderedArray(['SELECT']);
6566
});
67+
68+
test('Syntax suggestion after error and comments', () => {
69+
const pos: CaretPosition = {
70+
lineNumber: 4,
71+
column: 18,
72+
};
73+
const syntaxes = impala.getSuggestionAtCaretPosition(sql4, pos)?.syntax;
74+
const suggestion = syntaxes?.find(
75+
(syn) => syn.syntaxContextType === EntityContextType.TABLE
76+
);
77+
78+
// syntax
79+
expect(suggestion).not.toBeUndefined();
80+
expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']);
81+
});
6682
});

test/parser/impala/suggestion/syntaxSuggestion.test.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,4 +462,52 @@ describe('Impala SQL Syntax Suggestion', () => {
462462
expect(suggestion).not.toBeUndefined();
463463
expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['YEAR']);
464464
});
465+
466+
test('Syntax suggestion after a comment', () => {
467+
const sql = `-- the comment\nSELECT * FROM db.`;
468+
const pos: CaretPosition = {
469+
lineNumber: 2,
470+
column: 18,
471+
};
472+
473+
const syntaxes = impala.getSuggestionAtCaretPosition(sql, pos)?.syntax;
474+
const suggestion = syntaxes?.find(
475+
(syn) => syn.syntaxContextType === EntityContextType.TABLE
476+
);
477+
478+
expect(suggestion).not.toBeUndefined();
479+
expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']);
480+
});
481+
482+
test('Syntax suggestion after comments', () => {
483+
const sql = `-- the comment 1\n-- the comment 2\nSELECT * FROM db.`;
484+
const pos: CaretPosition = {
485+
lineNumber: 3,
486+
column: 18,
487+
};
488+
489+
const syntaxes = impala.getSuggestionAtCaretPosition(sql, pos)?.syntax;
490+
const suggestion = syntaxes?.find(
491+
(syn) => syn.syntaxContextType === EntityContextType.TABLE
492+
);
493+
494+
expect(suggestion).not.toBeUndefined();
495+
expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']);
496+
});
497+
498+
test('Syntax suggestion after comments', () => {
499+
const sql = `-- SELECT FROM t1;\n-- the comment 1\n-- the comment 2\nSELECT * FROM db.`;
500+
const pos: CaretPosition = {
501+
lineNumber: 4,
502+
column: 18,
503+
};
504+
505+
const syntaxes = impala.getSuggestionAtCaretPosition(sql, pos)?.syntax;
506+
const suggestion = syntaxes?.find(
507+
(syn) => syn.syntaxContextType === EntityContextType.TABLE
508+
);
509+
510+
expect(suggestion).not.toBeUndefined();
511+
expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']);
512+
});
465513
});

test/parser/mysql/suggestion/completeAfterSyntaxError.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ describe('MySQL Complete After Syntax Error', () => {
77
const sql1 = `SELECT FROM tb2;\nINSERT INTO `;
88
const sql2 = `SELECT FROM tb3;\nCREATE TABLE `;
99
const sql3 = `SELECT FROM t1;\nSL`;
10+
const sql4 = `SELECT FROM t1;\n-- the comment 1\n-- the comment 2\nSELECT * FROM db.`;
1011

1112
test('Syntax error but end with semi, should suggest tableName', () => {
1213
const pos: CaretPosition = {
@@ -62,4 +63,19 @@ describe('MySQL Complete After Syntax Error', () => {
6263
);
6364
expect(filterKeywords).toMatchUnorderedArray(['SELECT', 'SIGNAL']);
6465
});
66+
67+
test('Syntax suggestion after error and comments', () => {
68+
const pos: CaretPosition = {
69+
lineNumber: 4,
70+
column: 18,
71+
};
72+
const syntaxes = mysql.getSuggestionAtCaretPosition(sql4, pos)?.syntax;
73+
const suggestion = syntaxes?.find(
74+
(syn) => syn.syntaxContextType === EntityContextType.TABLE
75+
);
76+
77+
// syntax
78+
expect(suggestion).not.toBeUndefined();
79+
expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']);
80+
});
6581
});

test/parser/mysql/suggestion/syntaxSuggestion.test.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,4 +640,52 @@ describe('MySQL Syntax Suggestion', () => {
640640
expect(suggestion).not.toBeUndefined();
641641
expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['score']);
642642
});
643+
644+
test('Syntax suggestion after a comment', () => {
645+
const sql = `-- the comment\nSELECT * FROM db.`;
646+
const pos: CaretPosition = {
647+
lineNumber: 2,
648+
column: 18,
649+
};
650+
651+
const syntaxes = mysql.getSuggestionAtCaretPosition(sql, pos)?.syntax;
652+
const suggestion = syntaxes?.find(
653+
(syn) => syn.syntaxContextType === EntityContextType.TABLE
654+
);
655+
656+
expect(suggestion).not.toBeUndefined();
657+
expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']);
658+
});
659+
660+
test('Syntax suggestion after comments', () => {
661+
const sql = `-- the comment 1\n-- the comment 2\nSELECT * FROM db.`;
662+
const pos: CaretPosition = {
663+
lineNumber: 3,
664+
column: 18,
665+
};
666+
667+
const syntaxes = mysql.getSuggestionAtCaretPosition(sql, pos)?.syntax;
668+
const suggestion = syntaxes?.find(
669+
(syn) => syn.syntaxContextType === EntityContextType.TABLE
670+
);
671+
672+
expect(suggestion).not.toBeUndefined();
673+
expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']);
674+
});
675+
676+
test('Syntax suggestion after comments', () => {
677+
const sql = `-- SELECT FROM t1;\n-- the comment 1\n-- the comment 2\nSELECT * FROM db.`;
678+
const pos: CaretPosition = {
679+
lineNumber: 4,
680+
column: 18,
681+
};
682+
683+
const syntaxes = mysql.getSuggestionAtCaretPosition(sql, pos)?.syntax;
684+
const suggestion = syntaxes?.find(
685+
(syn) => syn.syntaxContextType === EntityContextType.TABLE
686+
);
687+
688+
expect(suggestion).not.toBeUndefined();
689+
expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']);
690+
});
643691
});

test/parser/postgresql/suggestion/completeAfterSyntaxError.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ describe('PostgreSQL Complete After Syntax Error', () => {
77
const sql1 = `SELECT FROM tb2;\nINSERT INTO `;
88
const sql2 = `SELECT FROM tb3;\nCREATE TABLE `;
99
const sql3 = `SELECT FROM t1;\nSL`;
10+
const sql4 = `SELECT FROM t1;\n-- the comment 1\n-- the comment 2\nSELECT * FROM db.`;
1011

1112
test('Syntax error but end with semi, should suggest tableName', () => {
1213
const pos: CaretPosition = {
@@ -62,4 +63,19 @@ describe('PostgreSQL Complete After Syntax Error', () => {
6263
);
6364
expect(filterKeywords).toMatchUnorderedArray(['SELECT']);
6465
});
66+
67+
test('Syntax suggestion after error and comments', () => {
68+
const pos: CaretPosition = {
69+
lineNumber: 4,
70+
column: 18,
71+
};
72+
const syntaxes = postgresql.getSuggestionAtCaretPosition(sql4, pos)?.syntax;
73+
const suggestion = syntaxes?.find(
74+
(syn) => syn.syntaxContextType === EntityContextType.TABLE
75+
);
76+
77+
// syntax
78+
expect(suggestion).not.toBeUndefined();
79+
expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']);
80+
});
6581
});

0 commit comments

Comments
 (0)