Feat/auto complete (#175)
* feat: update hive grammar to adapt to c3 * feat: support viewName, dbName, fnName autoComplete to hive * test: add hive suggestion unit test * test: optimze flink suggestion unit tests
This commit is contained in:
19
test/parser/hive/suggestion/fixtures/syntaxSuggestion.sql
Normal file
19
test/parser/hive/suggestion/fixtures/syntaxSuggestion.sql
Normal file
@ -0,0 +1,19 @@
|
||||
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(birthdate) AS age FROM students;
|
||||
|
||||
CREATE DATABASE db;
|
||||
|
||||
DROP SCHEMA IF EXISTS sch;
|
20
test/parser/hive/suggestion/fixtures/tokenSuggestion.sql
Normal file
20
test/parser/hive/suggestion/fixtures/tokenSuggestion.sql
Normal file
@ -0,0 +1,20 @@
|
||||
ALTER
|
||||
;
|
||||
CREATE
|
||||
;
|
||||
DELETE
|
||||
;
|
||||
DESCRIBE
|
||||
;
|
||||
DROP
|
||||
;
|
||||
EXPORT
|
||||
;
|
||||
IMPORT
|
||||
;
|
||||
INSERT
|
||||
;
|
||||
LOAD
|
||||
;
|
||||
SHOW
|
||||
;
|
147
test/parser/hive/suggestion/syntaxSuggestion.test.ts
Normal file
147
test/parser/hive/suggestion/syntaxSuggestion.test.ts
Normal file
@ -0,0 +1,147 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { CaretPosition, SyntaxContextType } from '../../../../src/parser/common/basic-parser-types';
|
||||
import HiveSQL from '../../../../src/parser/hive'
|
||||
|
||||
const syntaxSql = fs.readFileSync(path.join(__dirname, 'fixtures', 'syntaxSuggestion.sql'), 'utf-8');
|
||||
|
||||
describe('Hive SQL Syntax Suggestion', () => {
|
||||
const parser = new HiveSQL();
|
||||
|
||||
test('Validate Syntax SQL', () => {
|
||||
expect(parser.validate(syntaxSql).length).not.toBe(0);
|
||||
expect(parser.validate(syntaxSql).length).not.toBe(0);
|
||||
expect(parser.validate(syntaxSql).length).not.toBe(0);
|
||||
});
|
||||
|
||||
test('Insert table ', () => {
|
||||
const pos: CaretPosition = {
|
||||
lineNumber: 1,
|
||||
column: 18
|
||||
}
|
||||
const syntaxes = parser.getSuggestionAtCaretPosition(syntaxSql, 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(syntaxSql, 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(syntaxSql, 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(syntaxSql, 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(syntaxSql, 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(syntaxSql, 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(syntaxSql, 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(syntaxSql, 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(syntaxSql, 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(syntaxSql, pos)?.syntax;
|
||||
const suggestion = syntaxes?.find(syn => syn.syntaxContextType === SyntaxContextType.DATABASE);
|
||||
|
||||
expect(suggestion).not.toBeUndefined();
|
||||
expect(suggestion?.wordRanges.map(token => token.text))
|
||||
.toEqual([ 'sch' ])
|
||||
});
|
||||
|
||||
})
|
232
test/parser/hive/suggestion/tokenSuggestion.test.ts
Normal file
232
test/parser/hive/suggestion/tokenSuggestion.test.ts
Normal file
@ -0,0 +1,232 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { CaretPosition } from "../../../../src/parser/common/basic-parser-types";
|
||||
import HiveSQL from "../../../../src/parser/hive";
|
||||
|
||||
const tokenSql = fs.readFileSync(
|
||||
path.join(__dirname, "fixtures", "tokenSuggestion.sql"),
|
||||
"utf-8"
|
||||
);
|
||||
|
||||
describe("Hive SQL Syntax Suggestion", () => {
|
||||
const parser = new HiveSQL();
|
||||
|
||||
test("After ALTER", () => {
|
||||
const pos: CaretPosition = {
|
||||
lineNumber: 1,
|
||||
column: 7,
|
||||
};
|
||||
const suggestion = parser.getSuggestionAtCaretPosition(
|
||||
tokenSql,
|
||||
pos
|
||||
)?.keywords;
|
||||
expect(suggestion).toEqual([
|
||||
"APPLICATION",
|
||||
"GROUP",
|
||||
"USER",
|
||||
"POOL",
|
||||
"TRIGGER",
|
||||
"RESOURCE",
|
||||
"SCHEDULED",
|
||||
"INDEX",
|
||||
"CONNECTOR",
|
||||
"DATABASE",
|
||||
"SCHEMA",
|
||||
"MATERIALIZED",
|
||||
"VIEW",
|
||||
"TABLE",
|
||||
]);
|
||||
});
|
||||
|
||||
test("After CREATE", () => {
|
||||
const pos: CaretPosition = {
|
||||
lineNumber: 3,
|
||||
column: 8,
|
||||
};
|
||||
const suggestion = parser.getSuggestionAtCaretPosition(
|
||||
tokenSql,
|
||||
pos
|
||||
)?.keywords;
|
||||
expect(suggestion).toEqual([
|
||||
"CONNECTOR",
|
||||
"APPLICATION",
|
||||
"GROUP",
|
||||
"USER",
|
||||
"POOL",
|
||||
"TRIGGER",
|
||||
"RESOURCE",
|
||||
"ROLE",
|
||||
"INDEX",
|
||||
"TEMPORARY",
|
||||
"FUNCTION",
|
||||
"SCHEDULED",
|
||||
"MATERIALIZED",
|
||||
"VIEW",
|
||||
"OR",
|
||||
"MANAGED",
|
||||
"TABLE",
|
||||
"EXTERNAL",
|
||||
"TRANSACTIONAL",
|
||||
"REMOTE",
|
||||
"DATABASE",
|
||||
"SCHEMA",
|
||||
]);
|
||||
});
|
||||
|
||||
test("After DELETE", () => {
|
||||
const pos: CaretPosition = {
|
||||
lineNumber: 5,
|
||||
column: 8,
|
||||
};
|
||||
const suggestion = parser.getSuggestionAtCaretPosition(
|
||||
tokenSql,
|
||||
pos
|
||||
)?.keywords;
|
||||
expect(suggestion).toEqual(['FROM']);
|
||||
});
|
||||
|
||||
test("After DESCRIBE", () => {
|
||||
const pos: CaretPosition = {
|
||||
lineNumber: 7,
|
||||
column: 10,
|
||||
};
|
||||
const suggestion = parser.getSuggestionAtCaretPosition(
|
||||
tokenSql,
|
||||
pos
|
||||
)?.keywords;
|
||||
expect(suggestion).toEqual([
|
||||
"EXTENDED",
|
||||
"FORMATTED",
|
||||
"FUNCTION",
|
||||
"CONNECTOR",
|
||||
"DATABASE",
|
||||
"SCHEMA",
|
||||
]);
|
||||
});
|
||||
|
||||
test("After DROP", () => {
|
||||
const pos: CaretPosition = {
|
||||
lineNumber: 9,
|
||||
column: 6,
|
||||
};
|
||||
const suggestion = parser.getSuggestionAtCaretPosition(
|
||||
tokenSql,
|
||||
pos
|
||||
)?.keywords;
|
||||
expect(suggestion).toEqual([
|
||||
"CONNECTOR",
|
||||
"APPLICATION",
|
||||
"GROUP",
|
||||
"USER",
|
||||
"POOL",
|
||||
"TRIGGER",
|
||||
"RESOURCE",
|
||||
"ROLE",
|
||||
"INDEX",
|
||||
"TEMPORARY",
|
||||
"FUNCTION",
|
||||
"MATERIALIZED",
|
||||
"VIEW",
|
||||
"SCHEDULED",
|
||||
"TABLE",
|
||||
"DATABASE",
|
||||
"SCHEMA",
|
||||
]);
|
||||
});
|
||||
|
||||
test("After EXPORT", () => {
|
||||
const pos: CaretPosition = {
|
||||
lineNumber: 11,
|
||||
column: 8,
|
||||
};
|
||||
const suggestion = parser.getSuggestionAtCaretPosition(
|
||||
tokenSql,
|
||||
pos
|
||||
)?.keywords;
|
||||
expect(suggestion).toEqual(['TABLE']);
|
||||
});
|
||||
|
||||
test("After IMPORT", () => {
|
||||
const pos: CaretPosition = {
|
||||
lineNumber: 13,
|
||||
column: 8,
|
||||
};
|
||||
const suggestion = parser.getSuggestionAtCaretPosition(
|
||||
tokenSql,
|
||||
pos
|
||||
)?.keywords;
|
||||
expect(suggestion).toEqual([
|
||||
"FROM",
|
||||
"TABLE",
|
||||
"EXTERNAL",
|
||||
]);
|
||||
});
|
||||
|
||||
test("After INSERT", () => {
|
||||
const pos: CaretPosition = {
|
||||
lineNumber: 15,
|
||||
column: 8,
|
||||
};
|
||||
const suggestion = parser.getSuggestionAtCaretPosition(
|
||||
tokenSql,
|
||||
pos
|
||||
)?.keywords;
|
||||
expect(suggestion).toEqual([
|
||||
"INTO",
|
||||
"OVERWRITE",
|
||||
]);
|
||||
});
|
||||
|
||||
test("After LOAD", () => {
|
||||
const pos: CaretPosition = {
|
||||
lineNumber: 17,
|
||||
column: 6,
|
||||
};
|
||||
const suggestion = parser.getSuggestionAtCaretPosition(
|
||||
tokenSql,
|
||||
pos
|
||||
)?.keywords;
|
||||
expect(suggestion).toEqual(["DATA"
|
||||
]);
|
||||
});
|
||||
|
||||
test("After SHOW", () => {
|
||||
const pos: CaretPosition = {
|
||||
lineNumber: 19,
|
||||
column: 6,
|
||||
};
|
||||
const suggestion = parser.getSuggestionAtCaretPosition(
|
||||
tokenSql,
|
||||
pos
|
||||
)?.keywords;
|
||||
expect(suggestion).toEqual([
|
||||
"CURRENT",
|
||||
"ROLES",
|
||||
"PRINCIPALS",
|
||||
"ROLE",
|
||||
"GRANT",
|
||||
"INDEX",
|
||||
"INDEXES",
|
||||
"FORMATTED",
|
||||
"CONNECTORS",
|
||||
"RESOURCE",
|
||||
"CONF",
|
||||
"TRANSACTIONS",
|
||||
"COMPACTIONS",
|
||||
"LOCKS",
|
||||
"TBLPROPERTIES",
|
||||
"TABLE",
|
||||
"CREATE",
|
||||
"PARTITIONS",
|
||||
"FUNCTIONS",
|
||||
"COLUMNS",
|
||||
"SORTED",
|
||||
"MATERIALIZED",
|
||||
"VIEWS",
|
||||
"TABLES",
|
||||
"EXTENDED",
|
||||
"DATABASES",
|
||||
"SCHEMAS",
|
||||
]);
|
||||
});
|
||||
});
|
Reference in New Issue
Block a user