feat: mysql auto complete (#219)
* refactor: mysql auto complete * test: mysql auto complete --------- Co-authored-by: liuyi <liuyi@dtstack.com>
This commit is contained in:
		
							
								
								
									
										49
									
								
								test/parser/mysql/suggestion/fixtures/syntaxSuggestion.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								test/parser/mysql/suggestion/fixtures/syntaxSuggestion.sql
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,49 @@
 | 
			
		||||
INSERT INTO db.tb ;
 | 
			
		||||
 | 
			
		||||
SELECT * FROM db.;
 | 
			
		||||
 | 
			
		||||
CREATE TABLE db. VALUES;
 | 
			
		||||
 | 
			
		||||
DROP TABLE IF EXISTS db.a;
 | 
			
		||||
 | 
			
		||||
CREATE OR REPLACE VIEW db.v;
 | 
			
		||||
 | 
			
		||||
DROP VIEW db.v;
 | 
			
		||||
 | 
			
		||||
CREATE FUNCTION fn1;
 | 
			
		||||
 | 
			
		||||
SELECT name, calculate_age(birthday) AS age FROM students;
 | 
			
		||||
 | 
			
		||||
CREATE DATABASE db;
 | 
			
		||||
 | 
			
		||||
DROP SCHEMA IF EXISTS sch;
 | 
			
		||||
 | 
			
		||||
ANALYZE TABLE t UPDATE HISTOGRAM ON c1, c2, c3 WITH 10 BUCKETS;
 | 
			
		||||
 | 
			
		||||
SELECT name, age FROM students;
 | 
			
		||||
 | 
			
		||||
ALTER TABLE StudentInfo RENAME COLUMN ;
 | 
			
		||||
 | 
			
		||||
ALTER TABLE StudentInfo RENAME COLUMN name TO t;
 | 
			
		||||
 | 
			
		||||
ALTER TABLE t1 ADD c2 INT GENERATED ALWAYS AS (c1 + 1) STORED;
 | 
			
		||||
 | 
			
		||||
ALTER TABLE StudentInfo CHANGE FirstName;
 | 
			
		||||
 | 
			
		||||
INSERT INTO students (  );
 | 
			
		||||
 | 
			
		||||
INSERT INTO students ( id, n );
 | 
			
		||||
 | 
			
		||||
SELECT ;
 | 
			
		||||
 | 
			
		||||
SELECT id, n;
 | 
			
		||||
 | 
			
		||||
SELECT  FROM tbl;
 | 
			
		||||
 | 
			
		||||
SELECT id, n FROM tbl;
 | 
			
		||||
 | 
			
		||||
SELECT id, n FROM tbl GROUP BY  ;
 | 
			
		||||
 | 
			
		||||
SELECT id, n FROM tbl ORDER BY name, i ;
 | 
			
		||||
 | 
			
		||||
SELECT id FROM tb1 GROUP BY ROLLUP(  );
 | 
			
		||||
							
								
								
									
										16
									
								
								test/parser/mysql/suggestion/fixtures/tokenSuggestion.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								test/parser/mysql/suggestion/fixtures/tokenSuggestion.sql
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
			
		||||
ALTER 
 | 
			
		||||
;
 | 
			
		||||
CREATE 
 | 
			
		||||
;
 | 
			
		||||
DELETE 
 | 
			
		||||
;
 | 
			
		||||
DESCRIBE 
 | 
			
		||||
;
 | 
			
		||||
DROP 
 | 
			
		||||
;
 | 
			
		||||
INSERT 
 | 
			
		||||
;
 | 
			
		||||
LOAD 
 | 
			
		||||
;
 | 
			
		||||
SHOW 
 | 
			
		||||
;
 | 
			
		||||
							
								
								
									
										443
									
								
								test/parser/mysql/suggestion/syntaxSuggestion.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										443
									
								
								test/parser/mysql/suggestion/syntaxSuggestion.test.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,443 @@
 | 
			
		||||
import fs from 'fs';
 | 
			
		||||
import path from 'path';
 | 
			
		||||
import { CaretPosition, SyntaxContextType } from '../../../../src/parser/common/basic-parser-types';
 | 
			
		||||
import MySQL from '../../../../src/parser/mysql';
 | 
			
		||||
import { commentOtherLine } from '../../../helper';
 | 
			
		||||
 | 
			
		||||
const syntaxSql = fs.readFileSync(
 | 
			
		||||
    path.join(__dirname, 'fixtures', 'syntaxSuggestion.sql'),
 | 
			
		||||
    'utf-8'
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
describe('MySQL Syntax Suggestion', () => {
 | 
			
		||||
    const parser = new MySQL();
 | 
			
		||||
 | 
			
		||||
    test('Validate Syntax SQL', () => {
 | 
			
		||||
        expect(parser.validate(syntaxSql).length).not.toBe(0);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('Insert table ', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 1,
 | 
			
		||||
            column: 18,
 | 
			
		||||
        };
 | 
			
		||||
        const syntaxes = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(syntaxSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.syntax;
 | 
			
		||||
        const suggestion = syntaxes?.find(
 | 
			
		||||
            (syn) => syn.syntaxContextType === SyntaxContextType.TABLE
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).not.toBeUndefined();
 | 
			
		||||
        expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.', 'tb']);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('Select table ', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 3,
 | 
			
		||||
            column: 18,
 | 
			
		||||
        };
 | 
			
		||||
        const syntaxes = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(syntaxSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.syntax;
 | 
			
		||||
        const suggestion = syntaxes?.find(
 | 
			
		||||
            (syn) => syn.syntaxContextType === SyntaxContextType.TABLE
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).not.toBeUndefined();
 | 
			
		||||
        expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('Create table ', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 5,
 | 
			
		||||
            column: 17,
 | 
			
		||||
        };
 | 
			
		||||
        const syntaxes = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(syntaxSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.syntax;
 | 
			
		||||
        const suggestion = syntaxes?.find(
 | 
			
		||||
            (syn) => syn.syntaxContextType === SyntaxContextType.TABLE_CREATE
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).not.toBeUndefined();
 | 
			
		||||
        expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.']);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('DROP table ', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 7,
 | 
			
		||||
            column: 26,
 | 
			
		||||
        };
 | 
			
		||||
        const syntaxes = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(syntaxSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.syntax;
 | 
			
		||||
        const suggestion = syntaxes?.find(
 | 
			
		||||
            (syn) => syn.syntaxContextType === SyntaxContextType.TABLE
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).not.toBeUndefined();
 | 
			
		||||
        expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.', 'a']);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('Create view ', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 9,
 | 
			
		||||
            column: 28,
 | 
			
		||||
        };
 | 
			
		||||
        const syntaxes = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(syntaxSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.syntax;
 | 
			
		||||
        const suggestion = syntaxes?.find(
 | 
			
		||||
            (syn) => syn.syntaxContextType === SyntaxContextType.VIEW_CREATE
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).not.toBeUndefined();
 | 
			
		||||
        expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.', 'v']);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('Drop view ', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 11,
 | 
			
		||||
            column: 15,
 | 
			
		||||
        };
 | 
			
		||||
        const syntaxes = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(syntaxSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.syntax;
 | 
			
		||||
        const suggestion = syntaxes?.find(
 | 
			
		||||
            (syn) => syn.syntaxContextType === SyntaxContextType.VIEW
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).not.toBeUndefined();
 | 
			
		||||
        expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db', '.', 'v']);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('Create function ', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 13,
 | 
			
		||||
            column: 20,
 | 
			
		||||
        };
 | 
			
		||||
        const syntaxes = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(syntaxSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.syntax;
 | 
			
		||||
        const suggestion = syntaxes?.find(
 | 
			
		||||
            (syn) => syn.syntaxContextType === SyntaxContextType.FUNCTION_CREATE
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).not.toBeUndefined();
 | 
			
		||||
        expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['fn1']);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('Use function', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 15,
 | 
			
		||||
            column: 27,
 | 
			
		||||
        };
 | 
			
		||||
        const syntaxes = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(syntaxSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.syntax;
 | 
			
		||||
        const suggestion = syntaxes?.find(
 | 
			
		||||
            (syn) => syn.syntaxContextType === SyntaxContextType.FUNCTION
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).not.toBeUndefined();
 | 
			
		||||
        expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['calculate_age']);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('Create database', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 17,
 | 
			
		||||
            column: 19,
 | 
			
		||||
        };
 | 
			
		||||
        const syntaxes = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(syntaxSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.syntax;
 | 
			
		||||
        const suggestion = syntaxes?.find(
 | 
			
		||||
            (syn) => syn.syntaxContextType === SyntaxContextType.DATABASE_CREATE
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).not.toBeUndefined();
 | 
			
		||||
        expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['db']);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('Drop database', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 19,
 | 
			
		||||
            column: 26,
 | 
			
		||||
        };
 | 
			
		||||
        const syntaxes = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(syntaxSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.syntax;
 | 
			
		||||
        const suggestion = syntaxes?.find(
 | 
			
		||||
            (syn) => syn.syntaxContextType === SyntaxContextType.DATABASE
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).not.toBeUndefined();
 | 
			
		||||
        expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['sch']);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('Analyze table on column', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 21,
 | 
			
		||||
            column: 39,
 | 
			
		||||
        };
 | 
			
		||||
        const syntaxes = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(syntaxSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.syntax;
 | 
			
		||||
        const suggestion = syntaxes?.find(
 | 
			
		||||
            (syn) => syn.syntaxContextType === SyntaxContextType.COLUMN
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).not.toBeUndefined();
 | 
			
		||||
        expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['c1']);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('Select columnName', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 23,
 | 
			
		||||
            column: 17,
 | 
			
		||||
        };
 | 
			
		||||
        const syntaxes = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(syntaxSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.syntax;
 | 
			
		||||
        const suggestion = syntaxes?.find(
 | 
			
		||||
            (syn) => syn.syntaxContextType === SyntaxContextType.COLUMN
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).not.toBeUndefined();
 | 
			
		||||
        expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['age']);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('Alter table rename columns', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 25,
 | 
			
		||||
            column: 39,
 | 
			
		||||
        };
 | 
			
		||||
        const syntaxes = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(syntaxSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.syntax;
 | 
			
		||||
        const suggestion = syntaxes?.find(
 | 
			
		||||
            (syn) => syn.syntaxContextType === SyntaxContextType.COLUMN
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).not.toBeUndefined();
 | 
			
		||||
        expect(suggestion?.wordRanges.map((token) => token.text)).toEqual([]);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('Alter table rename columns to', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 27,
 | 
			
		||||
            column: 48,
 | 
			
		||||
        };
 | 
			
		||||
        const syntaxes = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(syntaxSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.syntax;
 | 
			
		||||
        const suggestion = syntaxes?.find(
 | 
			
		||||
            (syn) => syn.syntaxContextType === SyntaxContextType.COLUMN_CREATE
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).not.toBeUndefined();
 | 
			
		||||
        expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['t']);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('Alter table add column', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 29,
 | 
			
		||||
            column: 22,
 | 
			
		||||
        };
 | 
			
		||||
        const syntaxes = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(syntaxSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.syntax;
 | 
			
		||||
        const suggestion = syntaxes?.find(
 | 
			
		||||
            (syn) => syn.syntaxContextType === SyntaxContextType.COLUMN
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).not.toBeUndefined();
 | 
			
		||||
        expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['c2']);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('Alter table change columns', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 31,
 | 
			
		||||
            column: 41,
 | 
			
		||||
        };
 | 
			
		||||
        const syntaxes = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(syntaxSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.syntax;
 | 
			
		||||
        const suggestion = syntaxes?.find(
 | 
			
		||||
            (syn) => syn.syntaxContextType === SyntaxContextType.COLUMN
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).not.toBeUndefined();
 | 
			
		||||
        expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['FirstName']);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('Insert into table spec columns', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 33,
 | 
			
		||||
            column: 24,
 | 
			
		||||
        };
 | 
			
		||||
        const syntaxes = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(syntaxSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.syntax;
 | 
			
		||||
        const suggestion = syntaxes?.find(
 | 
			
		||||
            (syn) => syn.syntaxContextType === SyntaxContextType.COLUMN
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).not.toBeUndefined();
 | 
			
		||||
        expect(suggestion?.wordRanges.map((token) => token.text)).toEqual([]);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('Insert into table spec columns2', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 35,
 | 
			
		||||
            column: 29,
 | 
			
		||||
        };
 | 
			
		||||
        const syntaxes = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(syntaxSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.syntax;
 | 
			
		||||
        const suggestion = syntaxes?.find(
 | 
			
		||||
            (syn) => syn.syntaxContextType === SyntaxContextType.COLUMN
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).not.toBeUndefined();
 | 
			
		||||
        expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['n']);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('Select columns case empty', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 37,
 | 
			
		||||
            column: 8,
 | 
			
		||||
        };
 | 
			
		||||
        const syntaxes = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(syntaxSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.syntax;
 | 
			
		||||
        const suggestion = syntaxes?.find(
 | 
			
		||||
            (syn) => syn.syntaxContextType === SyntaxContextType.COLUMN
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).not.toBeUndefined();
 | 
			
		||||
        expect(suggestion?.wordRanges.map((token) => token.text)).toEqual([]);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('Select columns case seq', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 39,
 | 
			
		||||
            column: 13,
 | 
			
		||||
        };
 | 
			
		||||
        const syntaxes = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(syntaxSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.syntax;
 | 
			
		||||
        const suggestion = syntaxes?.find(
 | 
			
		||||
            (syn) => syn.syntaxContextType === SyntaxContextType.COLUMN
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).not.toBeUndefined();
 | 
			
		||||
        expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['n']);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('Select columns from table case empty', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 41,
 | 
			
		||||
            column: 8,
 | 
			
		||||
        };
 | 
			
		||||
        const syntaxes = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(syntaxSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.syntax;
 | 
			
		||||
        const suggestion = syntaxes?.find(
 | 
			
		||||
            (syn) => syn.syntaxContextType === SyntaxContextType.COLUMN
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).not.toBeUndefined();
 | 
			
		||||
        expect(suggestion?.wordRanges.map((token) => token.text)).toEqual([]);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('Select columns from table case seq', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 43,
 | 
			
		||||
            column: 13,
 | 
			
		||||
        };
 | 
			
		||||
        const syntaxes = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(syntaxSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.syntax;
 | 
			
		||||
        const suggestion = syntaxes?.find(
 | 
			
		||||
            (syn) => syn.syntaxContextType === SyntaxContextType.COLUMN
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).not.toBeUndefined();
 | 
			
		||||
        expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['n']);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('Select group by', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 45,
 | 
			
		||||
            column: 32,
 | 
			
		||||
        };
 | 
			
		||||
        const syntaxes = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(syntaxSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.syntax;
 | 
			
		||||
        const suggestion = syntaxes?.find(
 | 
			
		||||
            (syn) => syn.syntaxContextType === SyntaxContextType.COLUMN
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).not.toBeUndefined();
 | 
			
		||||
        expect(suggestion?.wordRanges.map((token) => token.text)).toEqual([]);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('Select group by', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 47,
 | 
			
		||||
            column: 39,
 | 
			
		||||
        };
 | 
			
		||||
        const syntaxes = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(syntaxSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.syntax;
 | 
			
		||||
        const suggestion = syntaxes?.find(
 | 
			
		||||
            (syn) => syn.syntaxContextType === SyntaxContextType.COLUMN
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).not.toBeUndefined();
 | 
			
		||||
        expect(suggestion?.wordRanges.map((token) => token.text)).toEqual(['i']);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('Select group by rollup', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 49,
 | 
			
		||||
            column: 37,
 | 
			
		||||
        };
 | 
			
		||||
        const syntaxes = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(syntaxSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.syntax;
 | 
			
		||||
        const suggestion = syntaxes?.find(
 | 
			
		||||
            (syn) => syn.syntaxContextType === SyntaxContextType.COLUMN
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).not.toBeUndefined();
 | 
			
		||||
        expect(suggestion?.wordRanges.map((token) => token.text)).toEqual([]);
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										238
									
								
								test/parser/mysql/suggestion/tokenSuggestion.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										238
									
								
								test/parser/mysql/suggestion/tokenSuggestion.test.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,238 @@
 | 
			
		||||
import fs from 'fs';
 | 
			
		||||
import path from 'path';
 | 
			
		||||
import { CaretPosition } from '../../../../src/parser/common/basic-parser-types';
 | 
			
		||||
import MySQL from '../../../../src/parser/mysql';
 | 
			
		||||
import { commentOtherLine } from '../../../helper';
 | 
			
		||||
 | 
			
		||||
const tokenSql = fs.readFileSync(path.join(__dirname, 'fixtures', 'tokenSuggestion.sql'), 'utf-8');
 | 
			
		||||
 | 
			
		||||
describe('MySQL Token Suggestion', () => {
 | 
			
		||||
    const parser = new MySQL();
 | 
			
		||||
 | 
			
		||||
    test('After ALTER', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 1,
 | 
			
		||||
            column: 7,
 | 
			
		||||
        };
 | 
			
		||||
        const suggestion = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(tokenSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.keywords;
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).toEqual([
 | 
			
		||||
            'RESOURCE',
 | 
			
		||||
            'USER',
 | 
			
		||||
            'VIEW',
 | 
			
		||||
            'SQL',
 | 
			
		||||
            'DEFINER',
 | 
			
		||||
            'ALGORITHM',
 | 
			
		||||
            'TABLESPACE',
 | 
			
		||||
            'UNDO',
 | 
			
		||||
            'TABLE',
 | 
			
		||||
            'SERVER',
 | 
			
		||||
            'PROCEDURE',
 | 
			
		||||
            'LOGFILE',
 | 
			
		||||
            'INSTANCE',
 | 
			
		||||
            'FUNCTION',
 | 
			
		||||
            'EVENT',
 | 
			
		||||
            'DATABASE',
 | 
			
		||||
            'SCHEMA',
 | 
			
		||||
        ]);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('After CREATE', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 3,
 | 
			
		||||
            column: 8,
 | 
			
		||||
        };
 | 
			
		||||
        const suggestion = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(tokenSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.keywords;
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).toEqual([
 | 
			
		||||
            'RESOURCE',
 | 
			
		||||
            'USER',
 | 
			
		||||
            'ROLE',
 | 
			
		||||
            'VIEW',
 | 
			
		||||
            'SQL',
 | 
			
		||||
            'DEFINER',
 | 
			
		||||
            'ALGORITHM',
 | 
			
		||||
            'OR',
 | 
			
		||||
            'TRIGGER',
 | 
			
		||||
            'TABLESPACE',
 | 
			
		||||
            'UNDO',
 | 
			
		||||
            'TABLE',
 | 
			
		||||
            'TEMPORARY',
 | 
			
		||||
            'SERVER',
 | 
			
		||||
            'FUNCTION',
 | 
			
		||||
            'AGGREGATE',
 | 
			
		||||
            'PROCEDURE',
 | 
			
		||||
            'LOGFILE',
 | 
			
		||||
            'INDEX',
 | 
			
		||||
            'FULLTEXT',
 | 
			
		||||
            'SPATIAL',
 | 
			
		||||
            'UNIQUE',
 | 
			
		||||
            'OFFLINE',
 | 
			
		||||
            'ONLINE',
 | 
			
		||||
            'EVENT',
 | 
			
		||||
            'DATABASE',
 | 
			
		||||
            'SCHEMA',
 | 
			
		||||
        ]);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('After DELETE', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 5,
 | 
			
		||||
            column: 8,
 | 
			
		||||
        };
 | 
			
		||||
        const suggestion = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(tokenSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.keywords;
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).toEqual(['FROM', 'IGNORE', 'QUICK', 'LOW_PRIORITY']);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('After DESCRIBE', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 7,
 | 
			
		||||
            column: 10,
 | 
			
		||||
        };
 | 
			
		||||
        const suggestion = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(tokenSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.keywords;
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).toEqual([
 | 
			
		||||
            'ANALYZE',
 | 
			
		||||
            'SELECT',
 | 
			
		||||
            'DELETE',
 | 
			
		||||
            'INSERT',
 | 
			
		||||
            'REPLACE',
 | 
			
		||||
            'UPDATE',
 | 
			
		||||
            'FOR',
 | 
			
		||||
            'FORMAT',
 | 
			
		||||
            'PARTITIONS',
 | 
			
		||||
            'EXTENDED',
 | 
			
		||||
        ]);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('After DROP', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 9,
 | 
			
		||||
            column: 6,
 | 
			
		||||
        };
 | 
			
		||||
        const suggestion = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(tokenSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.keywords;
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).toEqual([
 | 
			
		||||
            'RESOURCE',
 | 
			
		||||
            'USER',
 | 
			
		||||
            'PREPARE',
 | 
			
		||||
            'ROLE',
 | 
			
		||||
            'VIEW',
 | 
			
		||||
            'TRIGGER',
 | 
			
		||||
            'TABLESPACE',
 | 
			
		||||
            'UNDO',
 | 
			
		||||
            'TABLE',
 | 
			
		||||
            'TEMPORARY',
 | 
			
		||||
            'SPATIAL',
 | 
			
		||||
            'SERVER',
 | 
			
		||||
            'FUNCTION',
 | 
			
		||||
            'PROCEDURE',
 | 
			
		||||
            'LOGFILE',
 | 
			
		||||
            'INDEX',
 | 
			
		||||
            'EVENT',
 | 
			
		||||
            'DATABASE',
 | 
			
		||||
            'SCHEMA',
 | 
			
		||||
        ]);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('After INSERT', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 11,
 | 
			
		||||
            column: 8,
 | 
			
		||||
        };
 | 
			
		||||
        const suggestion = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(tokenSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.keywords;
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).toEqual(['INTO', 'IGNORE', 'DELAYED', 'HIGH_PRIORITY', 'LOW_PRIORITY']);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('After LOAD', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 13,
 | 
			
		||||
            column: 6,
 | 
			
		||||
        };
 | 
			
		||||
        const suggestion = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(tokenSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.keywords;
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).toEqual(['INDEX', 'XML', 'DATA']);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('After SHOW', () => {
 | 
			
		||||
        const pos: CaretPosition = {
 | 
			
		||||
            lineNumber: 15,
 | 
			
		||||
            column: 6,
 | 
			
		||||
        };
 | 
			
		||||
        const suggestion = parser.getSuggestionAtCaretPosition(
 | 
			
		||||
            commentOtherLine(tokenSql, pos.lineNumber),
 | 
			
		||||
            pos
 | 
			
		||||
        )?.keywords;
 | 
			
		||||
 | 
			
		||||
        expect(suggestion).toEqual([
 | 
			
		||||
            'REPLICAS',
 | 
			
		||||
            'REPLICA',
 | 
			
		||||
            'SLAVE',
 | 
			
		||||
            'PROFILE',
 | 
			
		||||
            'OPEN',
 | 
			
		||||
            'INDEX',
 | 
			
		||||
            'KEYS',
 | 
			
		||||
            'INDEXES',
 | 
			
		||||
            'EXTENDED',
 | 
			
		||||
            'GRANTS',
 | 
			
		||||
            'FUNCTION',
 | 
			
		||||
            'PROCEDURE',
 | 
			
		||||
            'EVENTS',
 | 
			
		||||
            'TABLE',
 | 
			
		||||
            'FULL',
 | 
			
		||||
            'TABLES',
 | 
			
		||||
            'TRIGGERS',
 | 
			
		||||
            'COUNT',
 | 
			
		||||
            'ERRORS',
 | 
			
		||||
            'WARNINGS',
 | 
			
		||||
            'STORAGE',
 | 
			
		||||
            'ENGINES',
 | 
			
		||||
            'MASTER',
 | 
			
		||||
            'PLUGINS',
 | 
			
		||||
            'PRIVILEGES',
 | 
			
		||||
            'PROCESSLIST',
 | 
			
		||||
            'PROFILES',
 | 
			
		||||
            'AUTHORS',
 | 
			
		||||
            'CONTRIBUTORS',
 | 
			
		||||
            'ENGINE',
 | 
			
		||||
            'CREATE',
 | 
			
		||||
            'COLUMNS',
 | 
			
		||||
            'FIELDS',
 | 
			
		||||
            'CHARACTER',
 | 
			
		||||
            'CHARSET',
 | 
			
		||||
            'COLLATION',
 | 
			
		||||
            'DATABASES',
 | 
			
		||||
            'SCHEMAS',
 | 
			
		||||
            'GLOBAL',
 | 
			
		||||
            'SESSION',
 | 
			
		||||
            'STATUS',
 | 
			
		||||
            'VARIABLES',
 | 
			
		||||
            'BINLOG',
 | 
			
		||||
            'RELAYLOG',
 | 
			
		||||
            'BINARY',
 | 
			
		||||
        ]);
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
		Reference in New Issue
	
	Block a user