feat: support impala (#184)

* feat(impala): add impala sqlLexer

* feat(impala): add impala grammar

* feat(impala): add alter table sql

* feat(impala): update alter table sql

* feat(impala): add alter db sql

* feat(impala): add alter view sql

* feat(impala): add compute stats/comment statement and update partition_desc for alter table

* feat(impala): add drop statement sql

* feat(impala): add revoke and grant sql

* feat(impala): add create db/function/role/view sql

* feat(impala): add describe/explain/invalidata_metadata/load_data sql

* feat(impala): add refresh/set/shutdown sql

* feat(impala): add truncate_table/use/values sql

* fix(impala): update shutdown and invaliddate_metadata

* feat(impala): add show/update/upsert sql

* feat(impala): add create/insert sql

* feat(impala): add select and delete sql

* feat(impala): add impala tokens and fix todo

* feat(impala): update impalaparser and some test unit

* feat(impala): add syntax suggestion

* feat(impala): add syntax suggestion

* feat(impala): update test unit

* feat(impala): remove reference

* fix(impala): add statement for sqlname and collect tableName

* fix(impala): fix syntax suggestion unit test

* fix(impala): update syntax suggestion and collect column

* feat(impala): add collect column create
This commit is contained in:
霜序
2023-11-28 21:11:07 +08:00
committed by GitHub
parent db05cb3e4f
commit e203f1a48a
68 changed files with 38979 additions and 4 deletions

139
src/parser/impala.ts Normal file
View File

@ -0,0 +1,139 @@
import { Token } from 'antlr4ts';
import { CandidatesCollection } from 'antlr4-c3';
import { ImpalaSqlLexer } from '../lib/impala/ImpalaSqlLexer';
import { ImpalaSqlParser, ProgramContext, StatementContext } from '../lib/impala/ImpalaSqlParser';
import BasicParser from './common/basicParser';
import { ImpalaSqlParserListener } from '../lib/impala/ImpalaSqlParserListener';
import { SyntaxContextType, Suggestions, SyntaxSuggestion } from './common/basic-parser-types';
export default class ImpalaSQL extends BasicParser<
ImpalaSqlLexer,
ProgramContext,
ImpalaSqlParser
> {
protected createLexerFormCharStream(charStreams) {
const lexer = new ImpalaSqlLexer(charStreams);
return lexer;
}
protected createParserFromTokenStream(tokenStream) {
return new ImpalaSqlParser(tokenStream);
}
protected preferredRules: Set<number> = new Set([
ImpalaSqlParser.RULE_functionNameCreate,
ImpalaSqlParser.RULE_tableNameCreate,
ImpalaSqlParser.RULE_viewNameCreate,
ImpalaSqlParser.RULE_databaseNameCreate,
ImpalaSqlParser.RULE_columnNamePathCreate,
ImpalaSqlParser.RULE_tableNamePath,
ImpalaSqlParser.RULE_functionNamePath,
ImpalaSqlParser.RULE_viewNamePath,
ImpalaSqlParser.RULE_databaseNamePath,
ImpalaSqlParser.RULE_columnNamePath,
]);
protected get splitListener() {
return new ImpalaSqlSplitListener();
}
protected processCandidates(
candidates: CandidatesCollection,
allTokens: Token[],
caretTokenIndex: number,
tokenIndexOffset: number
): Suggestions<Token> {
const originalSyntaxSuggestions: SyntaxSuggestion<Token>[] = [];
const keywords: string[] = [];
for (let candidate of candidates.rules) {
const [ruleType, candidateRule] = candidate;
const startTokenIndex = candidateRule.startTokenIndex + tokenIndexOffset;
const tokenRanges = allTokens.slice(
startTokenIndex,
caretTokenIndex + tokenIndexOffset + 1
);
let syntaxContextType: SyntaxContextType;
switch (ruleType) {
case ImpalaSqlParser.RULE_functionNameCreate: {
syntaxContextType = SyntaxContextType.FUNCTION_CREATE;
break;
}
case ImpalaSqlParser.RULE_tableNameCreate: {
syntaxContextType = SyntaxContextType.TABLE_CREATE;
break;
}
case ImpalaSqlParser.RULE_databaseNameCreate: {
syntaxContextType = SyntaxContextType.DATABASE_CREATE;
break;
}
case ImpalaSqlParser.RULE_viewNameCreate: {
syntaxContextType = SyntaxContextType.VIEW_CREATE;
break;
}
case ImpalaSqlParser.RULE_columnNamePathCreate: {
syntaxContextType = SyntaxContextType.COLUMN_CREATE;
break;
}
case ImpalaSqlParser.RULE_databaseNamePath: {
syntaxContextType = SyntaxContextType.DATABASE;
break;
}
case ImpalaSqlParser.RULE_tableNamePath: {
syntaxContextType = SyntaxContextType.TABLE;
break;
}
case ImpalaSqlParser.RULE_viewNamePath: {
syntaxContextType = SyntaxContextType.VIEW;
break;
}
case ImpalaSqlParser.RULE_functionNamePath: {
syntaxContextType = SyntaxContextType.FUNCTION;
break;
}
case ImpalaSqlParser.RULE_columnNamePath: {
syntaxContextType = SyntaxContextType.COLUMN;
}
default:
break;
}
if (syntaxContextType) {
originalSyntaxSuggestions.push({
syntaxContextType,
wordRanges: tokenRanges,
});
}
}
for (let candidate of candidates.tokens) {
const symbolicName = this._parser.vocabulary.getSymbolicName(candidate[0]);
const displayName = this._parser.vocabulary.getDisplayName(candidate[0]);
if (symbolicName && symbolicName.startsWith('KW_')) {
const keyword =
displayName.startsWith("'") && displayName.endsWith("'")
? displayName.slice(1, -1)
: displayName;
keywords.push(keyword);
}
}
return {
syntax: originalSyntaxSuggestions,
keywords,
};
}
}
export class ImpalaSqlSplitListener implements ImpalaSqlParserListener {
private _statementContext: StatementContext[] = [];
exitStatement = (ctx: StatementContext) => {
this._statementContext.push(ctx);
};
enterStatement = (ctx: StatementContext) => {};
get statementsContext() {
return this._statementContext;
}
}

View File

@ -5,3 +5,4 @@ export { default as FlinkSQL } from './flinksql';
export { default as SparkSQL } from './spark';
export { default as PostgresSQL } from './pgsql';
export { default as TrinoSQL } from './trinosql';
export { default as ImpalaSQL } from './impala';