feat: collect entity (#265)
* feat: add text and word utils * feat: add entity collector class * refactor: rename SyntaxContextType to EntityContextType * refactor: improve EntityCollector * feat: improve mysql parser grammar * feat: add mysql entity collector * test: mysql entity collector tests * feat: remove useless method * feat: improve spark grammar file * feat: add spark entity collector * test: spark entity collector unit tests * feat: remove useless code * feat: add queryStatement label * feat: add crateDatabaseStmt * feat: add trino entity collector * feat: rename trinosql to trino * test: trino collect entity unit tests * test: fix spark test * feat(impala): support impale entity collector (#256) * Feat/collect entity hive (#263) * feat(hive): support hive collect entity * feat(hive): update tableAllColumns * feat: replace antlr4ts with antlr4ng * feat(pgsql): pgsql collect entity (#268) * feat(pgsql): pgsql collect entity * feat(pgsql): optimize some name --------- Co-authored-by: zhaoge <> * feat: get word text by token.text * feat: supprt collect db/function and add splitListener (#270) * feat: supprt collect db/function and add splitListner * feat: remove SplitListener interface in baseParser to use SplitListener in root * fix(mysql): fix show create xxx not celloct as createXXXEntity type * test: fix pgsql unit tests * Feat/error recover predicate (#274) * feat: optimize pgsql grammar * feat: add sql parser base * feat: apply SQLParserBase * feat: add geAllEntities method * test: test collect table when missing column * feat: compose collect and suggestion (#276) * feat: mark stmt which contain caret * test: correct name of getAllEntities * test: remove misscolumn unit tests * test: add suggestionWithEntity tests * feat: flink collect entity (#277) * feat: improve flink sql parser * feat: support flink entity collector * test: flink entity collect unit test * feat: move combine entities to parent class --------- Co-authored-by: 霜序 <976060700@qq.com> Co-authored-by: XCynthia <942884029@qq.com>
This commit is contained in:
@ -1,3 +1,6 @@
|
||||
import { WordRange } from './textAndWord';
|
||||
import { StmtContextType } from './entityCollector';
|
||||
|
||||
/**
|
||||
* The insertion position of the candidate list.
|
||||
* Such as cursor position
|
||||
@ -12,7 +15,7 @@ export interface CaretPosition {
|
||||
/**
|
||||
* Syntax context type at caret position
|
||||
*/
|
||||
export enum SyntaxContextType {
|
||||
export enum EntityContextType {
|
||||
/** catalog name */
|
||||
CATALOG = 'catalog',
|
||||
/** catalog name that will be created */
|
||||
@ -43,26 +46,11 @@ export enum SyntaxContextType {
|
||||
COLUMN_CREATE = 'columnCreate',
|
||||
}
|
||||
|
||||
export interface WordRange {
|
||||
/** content of word */
|
||||
readonly text: string;
|
||||
/** start at 0 */
|
||||
readonly startIndex: number;
|
||||
/** end at ..n-1 */
|
||||
readonly endIndex: number;
|
||||
/** start at 1 */
|
||||
readonly line: number;
|
||||
/** start at 1 */
|
||||
readonly startColumn: number;
|
||||
/** end at ..n + 1 */
|
||||
readonly stopColumn: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Suggested information analyzed from the input
|
||||
*/
|
||||
export interface SyntaxSuggestion<T = WordRange> {
|
||||
readonly syntaxContextType: SyntaxContextType;
|
||||
readonly syntaxContextType: EntityContextType | StmtContextType;
|
||||
readonly wordRanges: T[];
|
||||
}
|
||||
|
||||
@ -79,19 +67,3 @@ export interface Suggestions<T = WordRange> {
|
||||
*/
|
||||
readonly keywords: string[];
|
||||
}
|
||||
|
||||
export interface TextSlice {
|
||||
/** start at 0 */
|
||||
readonly startIndex: number;
|
||||
/** end at ..n-1 */
|
||||
readonly endIndex: number;
|
||||
/** start at 1 */
|
||||
readonly startLine: number;
|
||||
/** end at ..n */
|
||||
readonly endLine: number;
|
||||
/** start at 1 */
|
||||
readonly startColumn: number;
|
||||
/** end at ..n + 1 */
|
||||
readonly endColumn: number;
|
||||
readonly text: string;
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import {
|
||||
Parser,
|
||||
Lexer,
|
||||
Token,
|
||||
CharStreams,
|
||||
@ -11,25 +10,15 @@ import {
|
||||
PredictionMode,
|
||||
} from 'antlr4ng';
|
||||
import { CandidatesCollection, CodeCompletionCore } from 'antlr4-c3';
|
||||
import { findCaretTokenIndex } from './utils/findCaretTokenIndex';
|
||||
import {
|
||||
CaretPosition,
|
||||
Suggestions,
|
||||
SyntaxSuggestion,
|
||||
WordRange,
|
||||
TextSlice,
|
||||
} from './basic-parser-types';
|
||||
import SQLParserBase from '../../lib/SQLParserBase';
|
||||
import { findCaretTokenIndex } from './findCaretTokenIndex';
|
||||
import { ctxToText, tokenToWord, WordRange, TextSlice } from './textAndWord';
|
||||
import { CaretPosition, Suggestions, SyntaxSuggestion } from './basic-parser-types';
|
||||
import ParseErrorListener, { ParseError, ErrorListener } from './parseErrorListener';
|
||||
import { ErrorStrategy } from './errorStrategy';
|
||||
|
||||
interface IParser<IParserRuleContext extends ParserRuleContext> extends Parser {
|
||||
// Customized in our parser
|
||||
program(): IParserRuleContext;
|
||||
}
|
||||
|
||||
interface SplitListener extends ParseTreeListener {
|
||||
statementsContext: ParserRuleContext[];
|
||||
}
|
||||
import type SplitListener from './splitListener';
|
||||
import type EntityCollector from './entityCollector';
|
||||
import { EntityContext } from './entityCollector';
|
||||
|
||||
/**
|
||||
* Custom Parser class, subclass needs extends it.
|
||||
@ -37,7 +26,7 @@ interface SplitListener extends ParseTreeListener {
|
||||
export default abstract class BasicParser<
|
||||
L extends Lexer = Lexer,
|
||||
PRC extends ParserRuleContext = ParserRuleContext,
|
||||
P extends IParser<PRC> = IParser<PRC>,
|
||||
P extends SQLParserBase<PRC> = SQLParserBase<PRC>,
|
||||
> {
|
||||
/** members for cache start */
|
||||
protected _charStreams: CharStream;
|
||||
@ -85,9 +74,17 @@ export default abstract class BasicParser<
|
||||
): Suggestions<Token>;
|
||||
|
||||
/**
|
||||
* Get splitListener instance.
|
||||
* Get a new splitListener instance.
|
||||
*/
|
||||
protected abstract get splitListener(): SplitListener;
|
||||
protected abstract get splitListener(): SplitListener<ParserRuleContext>;
|
||||
|
||||
/**
|
||||
* Get a new entityCollector instance.
|
||||
*/
|
||||
protected abstract createEntityCollector(
|
||||
input: string,
|
||||
caretTokenIndex?: number
|
||||
): EntityCollector;
|
||||
|
||||
/**
|
||||
* Create an antlr4 lexer from input.
|
||||
@ -218,7 +215,7 @@ export default abstract class BasicParser<
|
||||
*/
|
||||
public listen<PTL extends ParseTreeListener = ParseTreeListener>(
|
||||
listener: PTL,
|
||||
parseTree: PRC
|
||||
parseTree: ParserRuleContext
|
||||
) {
|
||||
ParseTreeWalker.DEFAULT.walk(listener, parseTree);
|
||||
}
|
||||
@ -234,22 +231,13 @@ export default abstract class BasicParser<
|
||||
return null;
|
||||
}
|
||||
const splitListener = this.splitListener;
|
||||
// TODO: add splitListener to all sqlParser implements add remove following if
|
||||
// TODO: add splitListener to all sqlParser implements and remove following if
|
||||
if (!splitListener) return null;
|
||||
|
||||
this.listen(splitListener, this._parseTree);
|
||||
|
||||
const res = splitListener.statementsContext.map((context) => {
|
||||
const { start, stop } = context;
|
||||
return {
|
||||
startIndex: start.start,
|
||||
endIndex: stop.stop,
|
||||
startLine: start.line,
|
||||
endLine: stop.line,
|
||||
startColumn: start.column + 1,
|
||||
endColumn: stop.column + 1 + stop.text.length,
|
||||
text: this._parsedInput.slice(start.start, stop.stop + 1),
|
||||
};
|
||||
return ctxToText(context, this._parsedInput);
|
||||
});
|
||||
|
||||
return res;
|
||||
@ -266,7 +254,7 @@ export default abstract class BasicParser<
|
||||
caretPosition: CaretPosition
|
||||
): Suggestions | null {
|
||||
const splitListener = this.splitListener;
|
||||
// TODO: add splitListener to all sqlParser implements add remove following if
|
||||
// TODO: add splitListener to all sqlParser implements and remove following if
|
||||
if (!splitListener) return null;
|
||||
|
||||
this.parseWithCache(input);
|
||||
@ -365,14 +353,7 @@ export default abstract class BasicParser<
|
||||
const syntaxSuggestions: SyntaxSuggestion<WordRange>[] = originalSuggestions.syntax.map(
|
||||
(syntaxCtx) => {
|
||||
const wordRanges: WordRange[] = syntaxCtx.wordRanges.map((token) => {
|
||||
return {
|
||||
text: this._parsedInput.slice(token.start, token.stop + 1),
|
||||
startIndex: token.start,
|
||||
endIndex: token.stop,
|
||||
line: token.line,
|
||||
startColumn: token.column + 1,
|
||||
stopColumn: token.column + 1 + token.text.length,
|
||||
};
|
||||
return tokenToWord(token, this._parsedInput);
|
||||
});
|
||||
return {
|
||||
syntaxContextType: syntaxCtx.syntaxContextType,
|
||||
@ -385,4 +366,34 @@ export default abstract class BasicParser<
|
||||
keywords: originalSuggestions.keywords,
|
||||
};
|
||||
}
|
||||
|
||||
public getAllEntities(input: string, caretPosition?: CaretPosition): EntityContext[] | null {
|
||||
const allTokens = this.getAllTokens(input);
|
||||
const caretTokenIndex = findCaretTokenIndex(caretPosition, allTokens);
|
||||
|
||||
const collectListener = this.createEntityCollector(input, caretTokenIndex);
|
||||
// TODO: add entityCollector to all sqlParser implements and remove following if
|
||||
if (!collectListener) {
|
||||
return null;
|
||||
}
|
||||
// const parser = this.createParserWithCache(input);
|
||||
|
||||
// parser.entityCollecting = true;
|
||||
// if(caretPosition) {
|
||||
// const allTokens = this.getAllTokens(input);
|
||||
// const tokenIndex = findCaretTokenIndex(caretPosition, allTokens);
|
||||
// parser.caretTokenIndex = tokenIndex;
|
||||
// }
|
||||
|
||||
// const parseTree = parser.program();
|
||||
|
||||
const parseTree = this.parseWithCache(input);
|
||||
|
||||
this.listen(collectListener, parseTree);
|
||||
|
||||
// parser.caretTokenIndex = -1;
|
||||
// parser.entityCollecting = false;
|
||||
|
||||
return collectListener.getEntities();
|
||||
}
|
||||
}
|
||||
|
279
src/parser/common/entityCollector.ts
Normal file
279
src/parser/common/entityCollector.ts
Normal file
@ -0,0 +1,279 @@
|
||||
import { ParserRuleContext } from 'antlr4ng';
|
||||
import { EntityContextType } from './basic-parser-types';
|
||||
import { WordPosition, TextPosition } from './textAndWord';
|
||||
import { ctxToText, ctxToWord } from './textAndWord';
|
||||
import SimpleStack from './simpleStack';
|
||||
|
||||
/**
|
||||
* TODO: more stmt type should be supported.
|
||||
*/
|
||||
export enum StmtContextType {
|
||||
/** A self-contained and complete statement */
|
||||
COMMON_STMT = 'commonStmt',
|
||||
CREATE_CATALOG_STMT = 'createCatalogStmt',
|
||||
CREATE_DATABASE_STMT = 'crateDatabaseStmt',
|
||||
CREATE_TABLE_STMT = 'createTableStmt',
|
||||
CREATE_VIEW_STMT = 'createViewStmt',
|
||||
SELECT_STMT = 'selectStmt',
|
||||
INSERT_STMT = 'insertStmt',
|
||||
CREATE_FUNCTION_STMT = 'createFunctionStmt',
|
||||
}
|
||||
|
||||
export interface StmtContext {
|
||||
readonly stmtContextType: StmtContextType;
|
||||
readonly position: TextPosition;
|
||||
readonly rootStmt: StmtContext | null;
|
||||
readonly parentStmt: StmtContext | null;
|
||||
readonly isContainCaret?: boolean;
|
||||
}
|
||||
|
||||
export function toStmtContext(
|
||||
ctx: ParserRuleContext,
|
||||
type: StmtContextType,
|
||||
input: string,
|
||||
rootStmt: StmtContext | null,
|
||||
parentStmt: StmtContext | null,
|
||||
isContainCaret?: boolean
|
||||
): StmtContext {
|
||||
const { text: _, ...position } = ctxToText(ctx, input);
|
||||
return {
|
||||
stmtContextType: type,
|
||||
position,
|
||||
rootStmt: rootStmt ?? null,
|
||||
parentStmt: parentStmt ?? null,
|
||||
isContainCaret,
|
||||
};
|
||||
}
|
||||
|
||||
export interface BaseAliasContext {
|
||||
readonly isAlias: boolean;
|
||||
alias?: string | EntityContext | null;
|
||||
origin?: string | EntityContext | StmtContext | null;
|
||||
}
|
||||
|
||||
const baseAlias: BaseAliasContext = {
|
||||
isAlias: false,
|
||||
origin: null,
|
||||
alias: null,
|
||||
};
|
||||
|
||||
export interface EntityContext extends BaseAliasContext {
|
||||
readonly entityContextType: EntityContextType;
|
||||
readonly text: string;
|
||||
readonly position: WordPosition;
|
||||
readonly belongStmt: StmtContext;
|
||||
relatedEntities: EntityContext[] | null;
|
||||
columns: EntityContext[] | null;
|
||||
}
|
||||
|
||||
export function toEntityContext(
|
||||
ctx: ParserRuleContext,
|
||||
type: EntityContextType,
|
||||
input: string,
|
||||
belongStmt: StmtContext,
|
||||
alias?: BaseAliasContext
|
||||
): EntityContext {
|
||||
const { text, ...position } = ctxToWord(ctx, input);
|
||||
const finalAlias = Object.assign({}, baseAlias, alias ?? {});
|
||||
return {
|
||||
entityContextType: type,
|
||||
text,
|
||||
position,
|
||||
belongStmt,
|
||||
relatedEntities: null,
|
||||
columns: null,
|
||||
...finalAlias,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo: Handle alias, includes column alias, table alias, query as alias and so on.
|
||||
* @todo: [may be need] Combine the entities in each clause.
|
||||
*/
|
||||
abstract class EntityCollector {
|
||||
constructor(input: string, caretTokenIndex?: number) {
|
||||
this._input = input;
|
||||
this._caretTokenIndex = caretTokenIndex ?? -1;
|
||||
this._entitiesSet = new Set();
|
||||
this._stmtStack = new SimpleStack();
|
||||
this._entityStack = new SimpleStack();
|
||||
this._rootStmt = null;
|
||||
}
|
||||
private readonly _input: string;
|
||||
private readonly _caretTokenIndex: number;
|
||||
private readonly _entitiesSet: Set<EntityContext>;
|
||||
/** Staging statements that have already entered. */
|
||||
private readonly _stmtStack: SimpleStack<StmtContext>;
|
||||
/** Staging entities inside a single statement or clause. */
|
||||
private readonly _entityStack: SimpleStack<EntityContext>;
|
||||
/**
|
||||
* Always point to the first non-commonStmt at the bottom of the _stmtStack,
|
||||
* unless there are only commonStmts in the _stmtStack.
|
||||
* */
|
||||
private _rootStmt: StmtContext;
|
||||
|
||||
visitTerminal() {}
|
||||
|
||||
visitErrorNode() {}
|
||||
|
||||
enterEveryRule() {}
|
||||
|
||||
exitEveryRule() {}
|
||||
|
||||
getEntities() {
|
||||
return Array.from(this._entitiesSet);
|
||||
}
|
||||
|
||||
enterProgram() {
|
||||
this._entitiesSet.clear();
|
||||
this._stmtStack.clear();
|
||||
this._entityStack.clear();
|
||||
this._rootStmt = null;
|
||||
}
|
||||
|
||||
protected pushStmt(ctx: ParserRuleContext, type: StmtContextType) {
|
||||
let isContainCaret;
|
||||
if (this._caretTokenIndex >= 0) {
|
||||
isContainCaret =
|
||||
ctx.start.tokenIndex <= this._caretTokenIndex &&
|
||||
ctx.stop?.tokenIndex >= this._caretTokenIndex;
|
||||
}
|
||||
const stmtContext = toStmtContext(
|
||||
ctx,
|
||||
type,
|
||||
this._input,
|
||||
this._rootStmt,
|
||||
this._stmtStack.peek(),
|
||||
isContainCaret
|
||||
);
|
||||
if (
|
||||
this._stmtStack.isEmpty() ||
|
||||
this._stmtStack.peek()?.stmtContextType === StmtContextType.COMMON_STMT
|
||||
) {
|
||||
this._rootStmt = stmtContext;
|
||||
}
|
||||
this._stmtStack.push(stmtContext);
|
||||
|
||||
return stmtContext;
|
||||
}
|
||||
|
||||
protected popStmt() {
|
||||
const stmtContext = this._stmtStack.pop();
|
||||
if (this._rootStmt === stmtContext) {
|
||||
this._rootStmt = this._stmtStack.peek();
|
||||
if (!this._entityStack.isEmpty()) {
|
||||
this.combineEntitiesAndAdd(stmtContext);
|
||||
}
|
||||
}
|
||||
return stmtContext;
|
||||
}
|
||||
|
||||
protected pushEntity(
|
||||
ctx: ParserRuleContext,
|
||||
type: EntityContextType,
|
||||
alias?: BaseAliasContext
|
||||
) {
|
||||
const entityContext = toEntityContext(
|
||||
ctx,
|
||||
type,
|
||||
this._input,
|
||||
this._stmtStack.peek(),
|
||||
alias
|
||||
);
|
||||
if (this._stmtStack.isEmpty()) {
|
||||
this._entitiesSet.add(entityContext);
|
||||
} else {
|
||||
// If is inside a statement
|
||||
this._entityStack.push(entityContext);
|
||||
}
|
||||
return entityContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine entities that inside a single statement.
|
||||
* e.g. combine tableName and column if they are inside a same createTableStatement.
|
||||
* Then add combined entities into result.
|
||||
*/
|
||||
private combineEntitiesAndAdd(stmtContext: StmtContext) {
|
||||
const entitiesInsideStmt: EntityContext[] = [];
|
||||
while (
|
||||
!this._entityStack.isEmpty() &&
|
||||
(this._entityStack.peek().belongStmt === stmtContext ||
|
||||
this._entityStack.peek().belongStmt.rootStmt === stmtContext)
|
||||
) {
|
||||
entitiesInsideStmt.unshift(this._entityStack.pop());
|
||||
}
|
||||
|
||||
let tmpResults = entitiesInsideStmt;
|
||||
|
||||
tmpResults = this.combineRootStmtEntities(stmtContext, entitiesInsideStmt);
|
||||
|
||||
while (tmpResults.length) {
|
||||
this._entitiesSet.add(tmpResults.shift());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Combined all entities under a rootStmt.
|
||||
*/
|
||||
protected combineRootStmtEntities(
|
||||
stmtContext: StmtContext,
|
||||
entitiesInsideStmt: EntityContext[]
|
||||
): EntityContext[] {
|
||||
if (
|
||||
stmtContext.stmtContextType === StmtContextType.CREATE_VIEW_STMT ||
|
||||
stmtContext.stmtContextType === StmtContextType.CREATE_TABLE_STMT
|
||||
) {
|
||||
return this.combineCreateTableOrViewStmtEntities(stmtContext, entitiesInsideStmt);
|
||||
}
|
||||
return entitiesInsideStmt;
|
||||
}
|
||||
|
||||
protected combineCreateTableOrViewStmtEntities(
|
||||
stmtContext: StmtContext,
|
||||
entitiesInsideStmt: EntityContext[]
|
||||
): EntityContext[] {
|
||||
const columns: EntityContext[] = [];
|
||||
const relatedEntities: EntityContext[] = [];
|
||||
let mainEntity: EntityContext = null;
|
||||
const finalEntities = entitiesInsideStmt.reduce((result, entity) => {
|
||||
if (entity.belongStmt !== stmtContext) {
|
||||
if (
|
||||
entity.entityContextType !== EntityContextType.COLUMN &&
|
||||
entity.entityContextType !== EntityContextType.COLUMN_CREATE
|
||||
) {
|
||||
relatedEntities.push(entity);
|
||||
result.push(entity);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if (entity.entityContextType === EntityContextType.COLUMN_CREATE) {
|
||||
columns.push(entity);
|
||||
} else if (
|
||||
entity.entityContextType === EntityContextType.TABLE_CREATE ||
|
||||
entity.entityContextType === EntityContextType.VIEW_CREATE
|
||||
) {
|
||||
mainEntity = entity;
|
||||
result.push(entity);
|
||||
return result;
|
||||
} else if (entity.entityContextType !== EntityContextType.COLUMN) {
|
||||
relatedEntities.push(entity);
|
||||
result.push(entity);
|
||||
}
|
||||
return result;
|
||||
}, []);
|
||||
|
||||
if (columns.length) {
|
||||
mainEntity.columns = columns;
|
||||
}
|
||||
|
||||
if (relatedEntities.length) {
|
||||
mainEntity.relatedEntities = relatedEntities;
|
||||
}
|
||||
|
||||
return finalEntities;
|
||||
}
|
||||
}
|
||||
|
||||
export default EntityCollector;
|
@ -1,5 +1,5 @@
|
||||
import { Token } from 'antlr4ng';
|
||||
import { CaretPosition } from '../basic-parser-types';
|
||||
import { CaretPosition } from './basic-parser-types';
|
||||
|
||||
/**
|
||||
* find token index via caret position (cursor position)
|
32
src/parser/common/simpleStack.ts
Normal file
32
src/parser/common/simpleStack.ts
Normal file
@ -0,0 +1,32 @@
|
||||
class SimpleStack<T> {
|
||||
constructor() {
|
||||
this.stack = [];
|
||||
}
|
||||
private stack: T[];
|
||||
|
||||
push(item: T) {
|
||||
this.stack.push(item);
|
||||
}
|
||||
|
||||
pop(): T {
|
||||
return this.stack.pop();
|
||||
}
|
||||
|
||||
peek(): T {
|
||||
return this.stack[this.stack.length - 1];
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.stack = [];
|
||||
}
|
||||
|
||||
size(): number {
|
||||
return this.stack.length;
|
||||
}
|
||||
|
||||
isEmpty(): boolean {
|
||||
return this.stack.length === 0;
|
||||
}
|
||||
}
|
||||
|
||||
export default SimpleStack;
|
17
src/parser/common/splitListener.ts
Normal file
17
src/parser/common/splitListener.ts
Normal file
@ -0,0 +1,17 @@
|
||||
abstract class SplitListener<T> {
|
||||
protected _statementsContext: T[] = [];
|
||||
|
||||
visitTerminal() {}
|
||||
|
||||
visitErrorNode() {}
|
||||
|
||||
enterEveryRule() {}
|
||||
|
||||
exitEveryRule() {}
|
||||
|
||||
get statementsContext() {
|
||||
return this._statementsContext;
|
||||
}
|
||||
}
|
||||
|
||||
export default SplitListener;
|
89
src/parser/common/textAndWord.ts
Normal file
89
src/parser/common/textAndWord.ts
Normal file
@ -0,0 +1,89 @@
|
||||
import type { ParserRuleContext, Token } from 'antlr4ng';
|
||||
|
||||
export interface WordPosition {
|
||||
/** start at 0 */
|
||||
readonly startIndex: number;
|
||||
/** end at ..n-1 */
|
||||
readonly endIndex: number;
|
||||
/** start at 1 */
|
||||
readonly line: number;
|
||||
/** start at 1 */
|
||||
readonly startColumn: number;
|
||||
/** end at ..n + 1 */
|
||||
readonly endColumn: number;
|
||||
}
|
||||
|
||||
export interface WordRange extends WordPosition {
|
||||
/** content of word */
|
||||
readonly text: string;
|
||||
}
|
||||
|
||||
export interface TextPosition {
|
||||
/** start at 0 */
|
||||
readonly startIndex: number;
|
||||
/** end at ..n-1 */
|
||||
readonly endIndex: number;
|
||||
/** start at 1 */
|
||||
readonly startLine: number;
|
||||
/** end at ..n */
|
||||
readonly endLine: number;
|
||||
/** start at 1 */
|
||||
readonly startColumn: number;
|
||||
/** end at ..n + 1 */
|
||||
readonly endColumn: number;
|
||||
}
|
||||
|
||||
export interface TextSlice extends TextPosition {
|
||||
readonly text: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert Token to Word
|
||||
*/
|
||||
export function tokenToWord(token: Token, input: string): WordPosition & { text: string } {
|
||||
const startIndex = token.start;
|
||||
const endIndex = token.stop;
|
||||
return {
|
||||
text: token.text,
|
||||
line: token.line,
|
||||
startIndex,
|
||||
endIndex,
|
||||
startColumn: token.column + 1,
|
||||
endColumn: token.column + 1 + token.text.length,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert ParserRuleContext to Word
|
||||
*/
|
||||
export function ctxToWord(ctx: ParserRuleContext, input: string): WordPosition & { text: string } {
|
||||
const startIndex = ctx.start.start;
|
||||
const endIndex = ctx.stop.stop;
|
||||
const text = input.slice(startIndex, endIndex + 1);
|
||||
return {
|
||||
text,
|
||||
line: ctx.start.line,
|
||||
startIndex,
|
||||
endIndex,
|
||||
startColumn: ctx.start.column + 1,
|
||||
endColumn: ctx.stop.column + 1 + ctx.stop.text.length,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert ParserRuleContext to Text
|
||||
*/
|
||||
export function ctxToText(ctx: ParserRuleContext, input: string): TextPosition & { text: string } {
|
||||
const startIndex = ctx.start.start;
|
||||
const endIndex = ctx.stop.stop;
|
||||
const text = input.slice(startIndex, endIndex + 1);
|
||||
return {
|
||||
text,
|
||||
startLine: ctx.start.line,
|
||||
endLine: ctx.stop.line,
|
||||
startIndex,
|
||||
endIndex,
|
||||
startColumn: ctx.start.column + 1,
|
||||
endColumn: ctx.stop.column + 1 + ctx.stop.text.length,
|
||||
};
|
||||
}
|
134
src/parser/flinksql/flinkEntityCollector.ts
Normal file
134
src/parser/flinksql/flinkEntityCollector.ts
Normal file
@ -0,0 +1,134 @@
|
||||
import { EntityContextType } from '../../parser/common/basic-parser-types';
|
||||
import {
|
||||
CatalogPathContext,
|
||||
CatalogPathCreateContext,
|
||||
ColumnNameCreateContext,
|
||||
CreateCatalogContext,
|
||||
CreateDatabaseContext,
|
||||
CreateFunctionContext,
|
||||
CreateTableContext,
|
||||
CreateViewContext,
|
||||
DatabasePathContext,
|
||||
DatabasePathCreateContext,
|
||||
FunctionNameCreateContext,
|
||||
InsertStatementContext,
|
||||
QueryStatementContext,
|
||||
SqlStatementContext,
|
||||
TablePathContext,
|
||||
TablePathCreateContext,
|
||||
ViewPathContext,
|
||||
ViewPathCreateContext,
|
||||
} from '../../lib/flinksql/FlinkSqlParser';
|
||||
import { FlinkSqlParserListener } from '../../lib/flinksql/FlinkSqlParserListener';
|
||||
import EntityCollector, { StmtContextType } from '../common/entityCollector';
|
||||
|
||||
export default class FlinkEntityCollector
|
||||
extends EntityCollector
|
||||
implements FlinkSqlParserListener
|
||||
{
|
||||
/** ====== Entity Begin */
|
||||
exitCatalogPathCreate(ctx: CatalogPathCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.CATALOG_CREATE);
|
||||
}
|
||||
|
||||
exitCatalogPath(ctx: CatalogPathContext) {
|
||||
this.pushEntity(ctx, EntityContextType.CATALOG);
|
||||
}
|
||||
|
||||
exitDatabasePathCreate(ctx: DatabasePathCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.DATABASE_CREATE);
|
||||
}
|
||||
|
||||
exitDatabasePath(ctx: DatabasePathContext) {
|
||||
this.pushEntity(ctx, EntityContextType.DATABASE);
|
||||
}
|
||||
|
||||
exitTablePath(ctx: TablePathContext) {
|
||||
this.pushEntity(ctx, EntityContextType.TABLE);
|
||||
}
|
||||
|
||||
exitTablePathCreate(ctx: TablePathCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.TABLE_CREATE);
|
||||
}
|
||||
|
||||
exitViewPath(ctx: ViewPathContext) {
|
||||
this.pushEntity(ctx, EntityContextType.VIEW);
|
||||
}
|
||||
|
||||
exitViewPathCreate(ctx: ViewPathCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.VIEW_CREATE);
|
||||
}
|
||||
|
||||
exitColumnNameCreate(ctx: ColumnNameCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.COLUMN_CREATE);
|
||||
}
|
||||
|
||||
exitFunctionNameCreate(ctx: FunctionNameCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.FUNCTION_CREATE);
|
||||
}
|
||||
|
||||
/** ===== Statement begin */
|
||||
enterSqlStatement(ctx: SqlStatementContext) {
|
||||
this.pushStmt(ctx, StmtContextType.COMMON_STMT);
|
||||
}
|
||||
|
||||
exitSqlStatement(ctx: SqlStatementContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateCatalog(ctx: CreateCatalogContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_CATALOG_STMT);
|
||||
}
|
||||
|
||||
exitCreateCatalog(ctx: CreateCatalogContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateDatabase(ctx: CreateDatabaseContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_DATABASE_STMT);
|
||||
}
|
||||
|
||||
exitCreateDatabase(ctx: CreateDatabaseContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateTable(ctx: CreateTableContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_TABLE_STMT);
|
||||
}
|
||||
|
||||
exitCreateTable(ctx: CreateTableContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateView(ctx: CreateViewContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_VIEW_STMT);
|
||||
}
|
||||
|
||||
exitCreateView(ctx: CreateViewContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterQueryStatement(ctx: QueryStatementContext) {
|
||||
this.pushStmt(ctx, StmtContextType.SELECT_STMT);
|
||||
}
|
||||
|
||||
exitQueryStatement(ctx: QueryStatementContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateFunction(ctx: CreateFunctionContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_FUNCTION_STMT);
|
||||
}
|
||||
|
||||
exitCreateFunction(ctx: CreateFunctionContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterInsertStatement(ctx: InsertStatementContext) {
|
||||
this.pushStmt(ctx, StmtContextType.INSERT_STMT);
|
||||
}
|
||||
|
||||
exitInsertStatement(ctx: InsertStatementContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
}
|
12
src/parser/flinksql/flinkSplitListener.ts
Normal file
12
src/parser/flinksql/flinkSplitListener.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { SingleStatementContext } from '../../lib/flinksql/FlinkSqlParser';
|
||||
import { FlinkSqlParserListener } from '../../lib/flinksql/FlinkSqlParserListener';
|
||||
import SplitListener from '../common/splitListener';
|
||||
|
||||
export class FlinkSqlSplitListener
|
||||
extends SplitListener<SingleStatementContext>
|
||||
implements FlinkSqlParserListener
|
||||
{
|
||||
exitSingleStatement = (ctx: SingleStatementContext) => {
|
||||
this._statementsContext.push(ctx);
|
||||
};
|
||||
}
|
@ -1,14 +1,14 @@
|
||||
import { Token } from 'antlr4ng';
|
||||
import { CandidatesCollection } from 'antlr4-c3';
|
||||
import { FlinkSqlLexer } from '../lib/flinksql/FlinkSqlLexer';
|
||||
import {
|
||||
FlinkSqlParser,
|
||||
ProgramContext,
|
||||
SingleStatementContext,
|
||||
} from '../lib/flinksql/FlinkSqlParser';
|
||||
import { FlinkSqlParserListener } from '../lib/flinksql/FlinkSqlParserListener';
|
||||
import { SyntaxContextType, Suggestions, SyntaxSuggestion } from './common/basic-parser-types';
|
||||
import BasicParser from './common/basicParser';
|
||||
import { FlinkSqlLexer } from '../../lib/flinksql/FlinkSqlLexer';
|
||||
import { FlinkSqlParser, ProgramContext } from '../../lib/flinksql/FlinkSqlParser';
|
||||
import { EntityContextType, Suggestions, SyntaxSuggestion } from '../common/basic-parser-types';
|
||||
import BasicParser from '../common/basicParser';
|
||||
import { StmtContextType } from '../common/entityCollector';
|
||||
import { FlinkSqlSplitListener } from './flinkSplitListener';
|
||||
import FlinkEntityCollector from './flinkEntityCollector';
|
||||
|
||||
export { FlinkSqlSplitListener, FlinkEntityCollector };
|
||||
|
||||
export default class FlinkSQL extends BasicParser<FlinkSqlLexer, ProgramContext, FlinkSqlParser> {
|
||||
protected createLexerFromCharStream(charStreams) {
|
||||
@ -39,6 +39,10 @@ export default class FlinkSQL extends BasicParser<FlinkSqlLexer, ProgramContext,
|
||||
return new FlinkSqlSplitListener();
|
||||
}
|
||||
|
||||
protected createEntityCollector(input: string, caretTokenIndex?: number) {
|
||||
return new FlinkEntityCollector(input, caretTokenIndex);
|
||||
}
|
||||
|
||||
protected processCandidates(
|
||||
candidates: CandidatesCollection,
|
||||
allTokens: Token[],
|
||||
@ -56,50 +60,50 @@ export default class FlinkSQL extends BasicParser<FlinkSqlLexer, ProgramContext,
|
||||
caretTokenIndex + tokenIndexOffset + 1
|
||||
);
|
||||
|
||||
let syntaxContextType: SyntaxContextType;
|
||||
let syntaxContextType: EntityContextType | StmtContextType;
|
||||
switch (ruleType) {
|
||||
case FlinkSqlParser.RULE_catalogPath: {
|
||||
syntaxContextType = SyntaxContextType.CATALOG;
|
||||
syntaxContextType = EntityContextType.CATALOG;
|
||||
break;
|
||||
}
|
||||
case FlinkSqlParser.RULE_databasePath: {
|
||||
syntaxContextType = SyntaxContextType.DATABASE;
|
||||
syntaxContextType = EntityContextType.DATABASE;
|
||||
break;
|
||||
}
|
||||
case FlinkSqlParser.RULE_databasePathCreate: {
|
||||
syntaxContextType = SyntaxContextType.DATABASE_CREATE;
|
||||
syntaxContextType = EntityContextType.DATABASE_CREATE;
|
||||
break;
|
||||
}
|
||||
case FlinkSqlParser.RULE_tablePath: {
|
||||
syntaxContextType = SyntaxContextType.TABLE;
|
||||
syntaxContextType = EntityContextType.TABLE;
|
||||
break;
|
||||
}
|
||||
case FlinkSqlParser.RULE_tablePathCreate: {
|
||||
syntaxContextType = SyntaxContextType.TABLE_CREATE;
|
||||
syntaxContextType = EntityContextType.TABLE_CREATE;
|
||||
break;
|
||||
}
|
||||
case FlinkSqlParser.RULE_viewPath: {
|
||||
syntaxContextType = SyntaxContextType.VIEW;
|
||||
syntaxContextType = EntityContextType.VIEW;
|
||||
break;
|
||||
}
|
||||
case FlinkSqlParser.RULE_viewPathCreate: {
|
||||
syntaxContextType = SyntaxContextType.VIEW_CREATE;
|
||||
syntaxContextType = EntityContextType.VIEW_CREATE;
|
||||
break;
|
||||
}
|
||||
case FlinkSqlParser.RULE_functionName: {
|
||||
syntaxContextType = SyntaxContextType.FUNCTION;
|
||||
syntaxContextType = EntityContextType.FUNCTION;
|
||||
break;
|
||||
}
|
||||
case FlinkSqlParser.RULE_functionNameCreate: {
|
||||
syntaxContextType = SyntaxContextType.FUNCTION_CREATE;
|
||||
syntaxContextType = EntityContextType.FUNCTION_CREATE;
|
||||
break;
|
||||
}
|
||||
case FlinkSqlParser.RULE_columnName: {
|
||||
syntaxContextType = SyntaxContextType.COLUMN;
|
||||
syntaxContextType = EntityContextType.COLUMN;
|
||||
break;
|
||||
}
|
||||
case FlinkSqlParser.RULE_columnNameCreate: {
|
||||
syntaxContextType = SyntaxContextType.COLUMN_CREATE;
|
||||
syntaxContextType = EntityContextType.COLUMN_CREATE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -131,20 +135,3 @@ export default class FlinkSQL extends BasicParser<FlinkSqlLexer, ProgramContext,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class FlinkSqlSplitListener implements FlinkSqlParserListener {
|
||||
private _statementsContext: SingleStatementContext[] = [];
|
||||
|
||||
exitSingleStatement = (ctx: SingleStatementContext) => {
|
||||
this._statementsContext.push(ctx);
|
||||
};
|
||||
|
||||
visitTerminal() {}
|
||||
visitErrorNode() {}
|
||||
enterEveryRule() {}
|
||||
exitEveryRule() {}
|
||||
|
||||
get statementsContext() {
|
||||
return this._statementsContext;
|
||||
}
|
||||
}
|
140
src/parser/hive/hiveEntityCollector.ts
Normal file
140
src/parser/hive/hiveEntityCollector.ts
Normal file
@ -0,0 +1,140 @@
|
||||
import { EntityContextType } from '../..';
|
||||
import { HiveSqlParserListener } from '../../lib';
|
||||
import {
|
||||
ColumnNameCreateContext,
|
||||
CreateDatabaseStatementContext,
|
||||
CreateFunctionStatementContext,
|
||||
CreateMaterializedViewStatementContext,
|
||||
CreateTableStatementContext,
|
||||
CreateViewStatementContext,
|
||||
DbSchemaNameContext,
|
||||
DbSchemaNameCreateContext,
|
||||
FromInsertStmtContext,
|
||||
FromSelectStmtContext,
|
||||
FromStatementContext,
|
||||
FunctionNameCreateContext,
|
||||
InsertStmtContext,
|
||||
SelectStatementContext,
|
||||
StatementContext,
|
||||
TableNameContext,
|
||||
TableNameCreateContext,
|
||||
ViewNameContext,
|
||||
ViewNameCreateContext,
|
||||
} from '../../lib/hive/HiveSqlParser';
|
||||
import EntityCollector, { StmtContextType } from '../common/entityCollector';
|
||||
|
||||
export default class HiveEntityCollector extends EntityCollector implements HiveSqlParserListener {
|
||||
/** ====== Entity Begin */
|
||||
exitTableNameCreate = (ctx: TableNameCreateContext) => {
|
||||
this.pushEntity(ctx, EntityContextType.TABLE_CREATE);
|
||||
};
|
||||
|
||||
exitTableName = (ctx: TableNameContext) => {
|
||||
this.pushEntity(ctx, EntityContextType.TABLE);
|
||||
};
|
||||
|
||||
exitColumnNameCreate = (ctx: ColumnNameCreateContext) => {
|
||||
this.pushEntity(ctx, EntityContextType.COLUMN_CREATE);
|
||||
};
|
||||
|
||||
exitViewNameCreate = (ctx: ViewNameCreateContext) => {
|
||||
this.pushEntity(ctx, EntityContextType.VIEW_CREATE);
|
||||
};
|
||||
|
||||
exitViewName = (ctx: ViewNameContext) => {
|
||||
this.pushEntity(ctx, EntityContextType.VIEW);
|
||||
};
|
||||
|
||||
exitDbSchemaNameCreate(ctx: DbSchemaNameCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.DATABASE_CREATE);
|
||||
}
|
||||
|
||||
exitDbSchemaName(ctx: DbSchemaNameContext) {
|
||||
this.pushEntity(ctx, EntityContextType.DATABASE);
|
||||
}
|
||||
|
||||
exitFunctionNameCreate(ctx: FunctionNameCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.FUNCTION_CREATE);
|
||||
}
|
||||
|
||||
/** ===== Statement begin */
|
||||
enterStatement = (ctx: StatementContext) => {
|
||||
this.pushStmt(ctx, StmtContextType.COMMON_STMT);
|
||||
};
|
||||
|
||||
exitStatement = () => {
|
||||
this.popStmt();
|
||||
};
|
||||
|
||||
enterCreateTableStatement = (ctx: CreateTableStatementContext) => {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_TABLE_STMT);
|
||||
};
|
||||
|
||||
exitCreateTableStatement = () => {
|
||||
this.popStmt();
|
||||
};
|
||||
|
||||
enterSelectStatement = (ctx: SelectStatementContext) => {
|
||||
this.pushStmt(ctx, StmtContextType.SELECT_STMT);
|
||||
};
|
||||
|
||||
exitSelectStatement = (ctx: SelectStatementContext) => {
|
||||
this.popStmt();
|
||||
};
|
||||
|
||||
enterFromSelectStmt = (ctx: FromSelectStmtContext) => {
|
||||
this.pushStmt(ctx, StmtContextType.SELECT_STMT);
|
||||
};
|
||||
|
||||
exitFromSelectStmt = (ctx: FromSelectStmtContext) => {
|
||||
this.popStmt();
|
||||
};
|
||||
|
||||
enterCreateViewStatement = (ctx: CreateViewStatementContext) => {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_VIEW_STMT);
|
||||
};
|
||||
|
||||
exitCreateViewStatement = (ctx: CreateViewStatementContext) => {
|
||||
this.popStmt();
|
||||
};
|
||||
|
||||
enterCreateMaterializedViewStatement = (ctx: CreateMaterializedViewStatementContext) => {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_VIEW_STMT);
|
||||
};
|
||||
|
||||
exitCreateMaterializedViewStatement = (ctx: CreateMaterializedViewStatementContext) => {
|
||||
this.popStmt();
|
||||
};
|
||||
|
||||
enterInsertStmt = (ctx: InsertStmtContext) => {
|
||||
this.pushStmt(ctx, StmtContextType.INSERT_STMT);
|
||||
};
|
||||
|
||||
exitInsertStmt = (ctx: InsertStmtContext) => {
|
||||
this.popStmt();
|
||||
};
|
||||
|
||||
enterFromInsertStmt = (ctx: FromInsertStmtContext) => {
|
||||
this.pushStmt(ctx, StmtContextType.INSERT_STMT);
|
||||
};
|
||||
|
||||
exitFromInsertStmt = (ctx: FromInsertStmtContext) => {
|
||||
this.popStmt();
|
||||
};
|
||||
|
||||
enterCreateDatabaseStatement(ctx: CreateDatabaseStatementContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_DATABASE_STMT);
|
||||
}
|
||||
|
||||
exitCreateDatabaseStatement(ctx: CreateDatabaseStatementContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterFunctionNameCreate(ctx: FunctionNameCreateContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_FUNCTION_STMT);
|
||||
}
|
||||
|
||||
exitCreateFunctionStatement(ctx: CreateFunctionStatementContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
}
|
12
src/parser/hive/hiveSplitListener.ts
Normal file
12
src/parser/hive/hiveSplitListener.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { StatementContext } from '../../lib/hive/HiveSqlParser';
|
||||
import { HiveSqlParserListener } from '../../lib/hive/HiveSqlParserListener';
|
||||
import SplitListener from '../common/splitListener';
|
||||
|
||||
export class HiveSqlSplitListener
|
||||
extends SplitListener<StatementContext>
|
||||
implements HiveSqlParserListener
|
||||
{
|
||||
exitStatement = (ctx: StatementContext) => {
|
||||
this._statementsContext.push(ctx);
|
||||
};
|
||||
}
|
@ -1,10 +1,15 @@
|
||||
import { Token } from 'antlr4ng';
|
||||
import { CandidatesCollection } from 'antlr4-c3';
|
||||
import { HiveSqlLexer } from '../lib/hive/HiveSqlLexer';
|
||||
import { HiveSqlParser, ProgramContext, StatementContext } from '../lib/hive/HiveSqlParser';
|
||||
import BasicParser from './common/basicParser';
|
||||
import { HiveSqlParserListener } from '../lib/hive/HiveSqlParserListener';
|
||||
import { SyntaxContextType, Suggestions, SyntaxSuggestion } from './common/basic-parser-types';
|
||||
import { HiveSqlLexer } from '../../lib/hive/HiveSqlLexer';
|
||||
import { HiveSqlParser, ProgramContext } from '../../lib/hive/HiveSqlParser';
|
||||
import BasicParser from '../common/basicParser';
|
||||
|
||||
import { EntityContextType, Suggestions, SyntaxSuggestion } from '../common/basic-parser-types';
|
||||
import { StmtContextType } from '../common/entityCollector';
|
||||
import { HiveSqlSplitListener } from './hiveSplitListener';
|
||||
import HiveEntityCollector from './hiveEntityCollector';
|
||||
|
||||
export { HiveEntityCollector, HiveSqlSplitListener };
|
||||
|
||||
export default class HiveSQL extends BasicParser<HiveSqlLexer, ProgramContext, HiveSqlParser> {
|
||||
protected createLexerFromCharStream(charStreams) {
|
||||
@ -34,6 +39,10 @@ export default class HiveSQL extends BasicParser<HiveSqlLexer, ProgramContext, H
|
||||
return new HiveSqlSplitListener();
|
||||
}
|
||||
|
||||
protected createEntityCollector(input: string, caretTokenIndex?: number) {
|
||||
return new HiveEntityCollector(input, caretTokenIndex);
|
||||
}
|
||||
|
||||
protected processCandidates(
|
||||
candidates: CandidatesCollection,
|
||||
allTokens: Token[],
|
||||
@ -50,47 +59,47 @@ export default class HiveSQL extends BasicParser<HiveSqlLexer, ProgramContext, H
|
||||
caretTokenIndex + tokenIndexOffset + 1
|
||||
);
|
||||
|
||||
let syntaxContextType: SyntaxContextType;
|
||||
let syntaxContextType: EntityContextType | StmtContextType;
|
||||
switch (ruleType) {
|
||||
case HiveSqlParser.RULE_dbSchemaName: {
|
||||
syntaxContextType = SyntaxContextType.DATABASE;
|
||||
syntaxContextType = EntityContextType.DATABASE;
|
||||
break;
|
||||
}
|
||||
case HiveSqlParser.RULE_dbSchemaNameCreate: {
|
||||
syntaxContextType = SyntaxContextType.DATABASE_CREATE;
|
||||
syntaxContextType = EntityContextType.DATABASE_CREATE;
|
||||
break;
|
||||
}
|
||||
case HiveSqlParser.RULE_tableName: {
|
||||
syntaxContextType = SyntaxContextType.TABLE;
|
||||
syntaxContextType = EntityContextType.TABLE;
|
||||
break;
|
||||
}
|
||||
case HiveSqlParser.RULE_tableNameCreate: {
|
||||
syntaxContextType = SyntaxContextType.TABLE_CREATE;
|
||||
syntaxContextType = EntityContextType.TABLE_CREATE;
|
||||
break;
|
||||
}
|
||||
case HiveSqlParser.RULE_viewName: {
|
||||
syntaxContextType = SyntaxContextType.VIEW;
|
||||
syntaxContextType = EntityContextType.VIEW;
|
||||
break;
|
||||
}
|
||||
case HiveSqlParser.RULE_viewNameCreate: {
|
||||
syntaxContextType = SyntaxContextType.VIEW_CREATE;
|
||||
syntaxContextType = EntityContextType.VIEW_CREATE;
|
||||
break;
|
||||
}
|
||||
case HiveSqlParser.RULE_functionNameForDDL:
|
||||
case HiveSqlParser.RULE_functionNameForInvoke: {
|
||||
syntaxContextType = SyntaxContextType.FUNCTION;
|
||||
syntaxContextType = EntityContextType.FUNCTION;
|
||||
break;
|
||||
}
|
||||
case HiveSqlParser.RULE_functionNameCreate: {
|
||||
syntaxContextType = SyntaxContextType.FUNCTION_CREATE;
|
||||
syntaxContextType = EntityContextType.FUNCTION_CREATE;
|
||||
break;
|
||||
}
|
||||
case HiveSqlParser.RULE_columnName: {
|
||||
syntaxContextType = SyntaxContextType.COLUMN;
|
||||
syntaxContextType = EntityContextType.COLUMN;
|
||||
break;
|
||||
}
|
||||
case HiveSqlParser.RULE_columnNameCreate: {
|
||||
syntaxContextType = SyntaxContextType.COLUMN_CREATE;
|
||||
syntaxContextType = EntityContextType.COLUMN_CREATE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -122,20 +131,3 @@ export default class HiveSQL extends BasicParser<HiveSqlLexer, ProgramContext, H
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class HiveSqlSplitListener implements HiveSqlParserListener {
|
||||
private _statementContext: StatementContext[] = [];
|
||||
|
||||
exitStatement = (ctx: StatementContext) => {
|
||||
this._statementContext.push(ctx);
|
||||
};
|
||||
|
||||
visitTerminal() {}
|
||||
visitErrorNode() {}
|
||||
enterEveryRule() {}
|
||||
exitEveryRule() {}
|
||||
|
||||
get statementsContext() {
|
||||
return this._statementContext;
|
||||
}
|
||||
}
|
143
src/parser/impala/impalaEntityCollector.ts
Normal file
143
src/parser/impala/impalaEntityCollector.ts
Normal file
@ -0,0 +1,143 @@
|
||||
import { ImpalaSqlParserListener } from '../../lib';
|
||||
import {
|
||||
ColumnNamePathCreateContext,
|
||||
CreateAggregateFunctionContext,
|
||||
CreateFunctionContext,
|
||||
CreateKuduTableAsSelectContext,
|
||||
CreateSchemaContext,
|
||||
CreateTableLikeContext,
|
||||
CreateTableSelectContext,
|
||||
CreateViewContext,
|
||||
DatabaseNameCreateContext,
|
||||
DatabaseNamePathContext,
|
||||
FunctionNameCreateContext,
|
||||
FunctionNamePathContext,
|
||||
InsertStatementContext,
|
||||
QueryStatementContext,
|
||||
SingleStatementContext,
|
||||
TableNameCreateContext,
|
||||
TableNamePathContext,
|
||||
ViewNameCreateContext,
|
||||
ViewNamePathContext,
|
||||
} from '../../lib/impala/ImpalaSqlParser';
|
||||
import { EntityContextType } from '../common/basic-parser-types';
|
||||
import EntityCollector, { StmtContextType } from '../common/entityCollector';
|
||||
|
||||
export default class ImpalaEntityCollector
|
||||
extends EntityCollector
|
||||
implements ImpalaSqlParserListener
|
||||
{
|
||||
/** ===== Entity begin */
|
||||
exitTableNameCreate(ctx: TableNameCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.TABLE_CREATE);
|
||||
}
|
||||
|
||||
exitTableNamePath(ctx: TableNamePathContext) {
|
||||
this.pushEntity(ctx, EntityContextType.TABLE);
|
||||
}
|
||||
|
||||
exitColumnNamePathCreate(ctx: ColumnNamePathCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.COLUMN_CREATE);
|
||||
}
|
||||
|
||||
exitViewNameCreate(ctx: ViewNameCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.VIEW_CREATE);
|
||||
}
|
||||
|
||||
exitViewNamePath(ctx: ViewNamePathContext) {
|
||||
this.pushEntity(ctx, EntityContextType.VIEW);
|
||||
}
|
||||
|
||||
exitDatabaseNamePath(ctx: DatabaseNamePathContext) {
|
||||
this.pushEntity(ctx, EntityContextType.DATABASE);
|
||||
}
|
||||
|
||||
exitDatabaseNameCreate(ctx: DatabaseNameCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.DATABASE_CREATE);
|
||||
}
|
||||
|
||||
exitFunctionNameCreate(ctx: FunctionNameCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.FUNCTION_CREATE);
|
||||
}
|
||||
|
||||
/** ===== Statement begin */
|
||||
enterSingleStatement(ctx: SingleStatementContext) {
|
||||
this.pushStmt(ctx, StmtContextType.COMMON_STMT);
|
||||
}
|
||||
|
||||
exitSingleStatement(ctx: SingleStatementContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateTableLike(ctx: CreateTableLikeContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_TABLE_STMT);
|
||||
}
|
||||
|
||||
exitCreateTableLike(ctx: CreateTableLikeContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateTableSelect(ctx: CreateTableSelectContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_TABLE_STMT);
|
||||
}
|
||||
|
||||
exitCreateTableSelect(ctx: CreateTableSelectContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateKuduTableAsSelect(ctx: CreateKuduTableAsSelectContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_TABLE_STMT);
|
||||
}
|
||||
|
||||
exitCreateKuduTableAsSelect(ctx: CreateKuduTableAsSelectContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterQueryStatement(ctx: QueryStatementContext) {
|
||||
this.pushStmt(ctx, StmtContextType.SELECT_STMT);
|
||||
}
|
||||
|
||||
exitQueryStatement(ctx: QueryStatementContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateView(ctx: CreateViewContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_VIEW_STMT);
|
||||
}
|
||||
|
||||
exitCreateView(ctx: CreateViewContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterInsertStatement(ctx: InsertStatementContext) {
|
||||
this.pushStmt(ctx, StmtContextType.INSERT_STMT);
|
||||
}
|
||||
|
||||
exitInsertStatement(ctx: InsertStatementContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateSchema(ctx: CreateSchemaContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_DATABASE_STMT);
|
||||
}
|
||||
|
||||
exitCreateSchema(ctx: CreateSchemaContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateAggregateFunction(ctx: CreateAggregateFunctionContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_FUNCTION_STMT);
|
||||
}
|
||||
|
||||
exitCreateAggregateFunction(ctx: CreateAggregateFunctionContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateFunction(ctx: CreateFunctionContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_FUNCTION_STMT);
|
||||
}
|
||||
|
||||
exitCreateFunction(ctx: CreateFunctionContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
}
|
12
src/parser/impala/impalaSplitListener.ts
Normal file
12
src/parser/impala/impalaSplitListener.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { SingleStatementContext } from '../../lib/impala/ImpalaSqlParser';
|
||||
import { ImpalaSqlParserListener } from '../../lib/impala/ImpalaSqlParserListener';
|
||||
import SplitListener from '../common/splitListener';
|
||||
|
||||
export class ImpalaSqlSplitListener
|
||||
extends SplitListener<SingleStatementContext>
|
||||
implements ImpalaSqlParserListener
|
||||
{
|
||||
exitSingleStatement = (ctx: SingleStatementContext) => {
|
||||
this._statementsContext.push(ctx);
|
||||
};
|
||||
}
|
@ -1,14 +1,14 @@
|
||||
import { Token } from 'antlr4ng';
|
||||
import { CandidatesCollection } from 'antlr4-c3';
|
||||
import { ImpalaSqlLexer } from '../lib/impala/ImpalaSqlLexer';
|
||||
import {
|
||||
ImpalaSqlParser,
|
||||
ProgramContext,
|
||||
SingleStatementContext,
|
||||
} from '../lib/impala/ImpalaSqlParser';
|
||||
import BasicParser from './common/basicParser';
|
||||
import { ImpalaSqlParserListener } from '../lib/impala/ImpalaSqlParserListener';
|
||||
import { SyntaxContextType, Suggestions, SyntaxSuggestion } from './common/basic-parser-types';
|
||||
import { ImpalaSqlLexer } from '../../lib/impala/ImpalaSqlLexer';
|
||||
import { ImpalaSqlParser, ProgramContext } from '../../lib/impala/ImpalaSqlParser';
|
||||
import BasicParser from '../common/basicParser';
|
||||
import { EntityContextType, Suggestions, SyntaxSuggestion } from '../common/basic-parser-types';
|
||||
import { StmtContextType } from '../common/entityCollector';
|
||||
import { ImpalaSqlSplitListener } from './impalaSplitListener';
|
||||
import ImpalaEntityCollector from './impalaEntityCollector';
|
||||
|
||||
export { ImpalaEntityCollector, ImpalaSqlSplitListener };
|
||||
|
||||
export default class ImpalaSQL extends BasicParser<
|
||||
ImpalaSqlLexer,
|
||||
@ -41,6 +41,10 @@ export default class ImpalaSQL extends BasicParser<
|
||||
return new ImpalaSqlSplitListener();
|
||||
}
|
||||
|
||||
protected createEntityCollector(input: string, caretTokenIndex?: number) {
|
||||
return new ImpalaEntityCollector(input, caretTokenIndex);
|
||||
}
|
||||
|
||||
protected processCandidates(
|
||||
candidates: CandidatesCollection,
|
||||
allTokens: Token[],
|
||||
@ -57,46 +61,46 @@ export default class ImpalaSQL extends BasicParser<
|
||||
caretTokenIndex + tokenIndexOffset + 1
|
||||
);
|
||||
|
||||
let syntaxContextType: SyntaxContextType;
|
||||
let syntaxContextType: EntityContextType | StmtContextType;
|
||||
switch (ruleType) {
|
||||
case ImpalaSqlParser.RULE_functionNameCreate: {
|
||||
syntaxContextType = SyntaxContextType.FUNCTION_CREATE;
|
||||
syntaxContextType = EntityContextType.FUNCTION_CREATE;
|
||||
break;
|
||||
}
|
||||
case ImpalaSqlParser.RULE_tableNameCreate: {
|
||||
syntaxContextType = SyntaxContextType.TABLE_CREATE;
|
||||
syntaxContextType = EntityContextType.TABLE_CREATE;
|
||||
break;
|
||||
}
|
||||
case ImpalaSqlParser.RULE_databaseNameCreate: {
|
||||
syntaxContextType = SyntaxContextType.DATABASE_CREATE;
|
||||
syntaxContextType = EntityContextType.DATABASE_CREATE;
|
||||
break;
|
||||
}
|
||||
case ImpalaSqlParser.RULE_viewNameCreate: {
|
||||
syntaxContextType = SyntaxContextType.VIEW_CREATE;
|
||||
syntaxContextType = EntityContextType.VIEW_CREATE;
|
||||
break;
|
||||
}
|
||||
case ImpalaSqlParser.RULE_columnNamePathCreate: {
|
||||
syntaxContextType = SyntaxContextType.COLUMN_CREATE;
|
||||
syntaxContextType = EntityContextType.COLUMN_CREATE;
|
||||
break;
|
||||
}
|
||||
case ImpalaSqlParser.RULE_databaseNamePath: {
|
||||
syntaxContextType = SyntaxContextType.DATABASE;
|
||||
syntaxContextType = EntityContextType.DATABASE;
|
||||
break;
|
||||
}
|
||||
case ImpalaSqlParser.RULE_tableNamePath: {
|
||||
syntaxContextType = SyntaxContextType.TABLE;
|
||||
syntaxContextType = EntityContextType.TABLE;
|
||||
break;
|
||||
}
|
||||
case ImpalaSqlParser.RULE_viewNamePath: {
|
||||
syntaxContextType = SyntaxContextType.VIEW;
|
||||
syntaxContextType = EntityContextType.VIEW;
|
||||
break;
|
||||
}
|
||||
case ImpalaSqlParser.RULE_functionNamePath: {
|
||||
syntaxContextType = SyntaxContextType.FUNCTION;
|
||||
syntaxContextType = EntityContextType.FUNCTION;
|
||||
break;
|
||||
}
|
||||
case ImpalaSqlParser.RULE_columnNamePath: {
|
||||
syntaxContextType = SyntaxContextType.COLUMN;
|
||||
syntaxContextType = EntityContextType.COLUMN;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
@ -127,20 +131,3 @@ export default class ImpalaSQL extends BasicParser<
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class ImpalaSqlSplitListener implements ImpalaSqlParserListener {
|
||||
private _statementContext: SingleStatementContext[] = [];
|
||||
|
||||
exitSingleStatement = (ctx: SingleStatementContext) => {
|
||||
this._statementContext.push(ctx);
|
||||
};
|
||||
|
||||
visitTerminal() {}
|
||||
visitErrorNode() {}
|
||||
enterEveryRule() {}
|
||||
exitEveryRule() {}
|
||||
|
||||
get statementsContext() {
|
||||
return this._statementContext;
|
||||
}
|
||||
}
|
@ -4,5 +4,5 @@ export { default as HiveSQL } from './hive';
|
||||
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 TrinoSQL } from './trino';
|
||||
export { default as ImpalaSQL } from './impala';
|
||||
|
@ -1,10 +1,14 @@
|
||||
import { Token } from 'antlr4ng';
|
||||
import { CandidatesCollection } from 'antlr4-c3';
|
||||
import { MySqlLexer } from '../lib/mysql/MySqlLexer';
|
||||
import { MySqlParser, ProgramContext, SingleStatementContext } from '../lib/mysql/MySqlParser';
|
||||
import BasicParser from './common/basicParser';
|
||||
import { Suggestions, SyntaxContextType, SyntaxSuggestion } from './common/basic-parser-types';
|
||||
import { MySqlParserListener } from '../lib/mysql/MySqlParserListener';
|
||||
import { MySqlLexer } from '../../lib/mysql/MySqlLexer';
|
||||
import { MySqlParser, ProgramContext } from '../../lib/mysql/MySqlParser';
|
||||
import BasicParser from '../common/basicParser';
|
||||
import { Suggestions, EntityContextType, SyntaxSuggestion } from '../common/basic-parser-types';
|
||||
import { StmtContextType } from '../common/entityCollector';
|
||||
import MysqlSplitListener from './mysqlSplitListener';
|
||||
import MySqlEntityCollector from './mysqlEntityCollector';
|
||||
|
||||
export { MySqlEntityCollector, MysqlSplitListener };
|
||||
|
||||
export default class MySQL extends BasicParser<MySqlLexer, ProgramContext, MySqlParser> {
|
||||
protected createLexerFromCharStream(charStreams): MySqlLexer {
|
||||
@ -33,6 +37,10 @@ export default class MySQL extends BasicParser<MySqlLexer, ProgramContext, MySql
|
||||
return new MysqlSplitListener();
|
||||
}
|
||||
|
||||
protected createEntityCollector(input: string, caretTokenIndex?: number) {
|
||||
return new MySqlEntityCollector(input, caretTokenIndex);
|
||||
}
|
||||
|
||||
protected processCandidates(
|
||||
candidates: CandidatesCollection,
|
||||
allTokens: Token[],
|
||||
@ -50,46 +58,46 @@ export default class MySQL extends BasicParser<MySqlLexer, ProgramContext, MySql
|
||||
caretTokenIndex + tokenIndexOffset + 1
|
||||
);
|
||||
|
||||
let syntaxContextType: SyntaxContextType;
|
||||
let syntaxContextType: EntityContextType | StmtContextType;
|
||||
switch (ruleType) {
|
||||
case MySqlParser.RULE_databaseName: {
|
||||
syntaxContextType = SyntaxContextType.DATABASE;
|
||||
syntaxContextType = EntityContextType.DATABASE;
|
||||
break;
|
||||
}
|
||||
case MySqlParser.RULE_databaseNameCreate: {
|
||||
syntaxContextType = SyntaxContextType.DATABASE_CREATE;
|
||||
syntaxContextType = EntityContextType.DATABASE_CREATE;
|
||||
break;
|
||||
}
|
||||
case MySqlParser.RULE_tableName: {
|
||||
syntaxContextType = SyntaxContextType.TABLE;
|
||||
syntaxContextType = EntityContextType.TABLE;
|
||||
break;
|
||||
}
|
||||
case MySqlParser.RULE_tableNameCreate: {
|
||||
syntaxContextType = SyntaxContextType.TABLE_CREATE;
|
||||
syntaxContextType = EntityContextType.TABLE_CREATE;
|
||||
break;
|
||||
}
|
||||
case MySqlParser.RULE_viewName: {
|
||||
syntaxContextType = SyntaxContextType.VIEW;
|
||||
syntaxContextType = EntityContextType.VIEW;
|
||||
break;
|
||||
}
|
||||
case MySqlParser.RULE_viewNameCreate: {
|
||||
syntaxContextType = SyntaxContextType.VIEW_CREATE;
|
||||
syntaxContextType = EntityContextType.VIEW_CREATE;
|
||||
break;
|
||||
}
|
||||
case MySqlParser.RULE_functionName: {
|
||||
syntaxContextType = SyntaxContextType.FUNCTION;
|
||||
syntaxContextType = EntityContextType.FUNCTION;
|
||||
break;
|
||||
}
|
||||
case MySqlParser.RULE_functionNameCreate: {
|
||||
syntaxContextType = SyntaxContextType.FUNCTION_CREATE;
|
||||
syntaxContextType = EntityContextType.FUNCTION_CREATE;
|
||||
break;
|
||||
}
|
||||
case MySqlParser.RULE_columnName: {
|
||||
syntaxContextType = SyntaxContextType.COLUMN;
|
||||
syntaxContextType = EntityContextType.COLUMN;
|
||||
break;
|
||||
}
|
||||
case MySqlParser.RULE_columnNameCreate: {
|
||||
syntaxContextType = SyntaxContextType.COLUMN_CREATE;
|
||||
syntaxContextType = EntityContextType.COLUMN_CREATE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -122,20 +130,3 @@ export default class MySQL extends BasicParser<MySqlLexer, ProgramContext, MySql
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class MysqlSplitListener implements MySqlParserListener {
|
||||
private _statementsContext: SingleStatementContext[] = [];
|
||||
|
||||
exitSingleStatement = (ctx: SingleStatementContext) => {
|
||||
this._statementsContext.push(ctx);
|
||||
};
|
||||
|
||||
visitTerminal() {}
|
||||
visitErrorNode() {}
|
||||
enterEveryRule() {}
|
||||
exitEveryRule() {}
|
||||
|
||||
get statementsContext() {
|
||||
return this._statementsContext;
|
||||
}
|
||||
}
|
147
src/parser/mysql/mysqlEntityCollector.ts
Normal file
147
src/parser/mysql/mysqlEntityCollector.ts
Normal file
@ -0,0 +1,147 @@
|
||||
import type {
|
||||
ColumnCreateTableContext,
|
||||
ColumnNameCreateContext,
|
||||
CopyCreateTableContext,
|
||||
CreateDatabaseContext,
|
||||
CreateFunctionContext,
|
||||
CreateViewContext,
|
||||
DatabaseNameContext,
|
||||
DatabaseNameCreateContext,
|
||||
FunctionNameCreateContext,
|
||||
InsertStatementContext,
|
||||
QueryCreateTableContext,
|
||||
SelectExpressionContext,
|
||||
SelectStatementContext,
|
||||
SingleStatementContext,
|
||||
TableNameContext,
|
||||
TableNameCreateContext,
|
||||
ViewNameContext,
|
||||
ViewNameCreateContext,
|
||||
} from '../../lib/mysql/MySqlParser';
|
||||
import type { MySqlParserListener } from '../../lib/mysql/MySqlParserListener';
|
||||
import { EntityContextType } from '../common/basic-parser-types';
|
||||
import EntityCollector, { StmtContextType } from '../common/entityCollector';
|
||||
|
||||
export default class MySqlEntityCollector extends EntityCollector implements MySqlParserListener {
|
||||
/** ====== Entity Begin */
|
||||
exitDatabaseName(ctx: DatabaseNameContext) {
|
||||
this.pushEntity(ctx, EntityContextType.DATABASE);
|
||||
}
|
||||
|
||||
exitDatabaseNameCreate(ctx: DatabaseNameCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.DATABASE_CREATE);
|
||||
}
|
||||
|
||||
exitTableName(ctx: TableNameContext) {
|
||||
this.pushEntity(ctx, EntityContextType.TABLE);
|
||||
}
|
||||
|
||||
exitTableNameCreate(ctx: TableNameCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.TABLE_CREATE);
|
||||
}
|
||||
|
||||
exitViewName(ctx: ViewNameContext) {
|
||||
this.pushEntity(ctx, EntityContextType.VIEW);
|
||||
}
|
||||
|
||||
exitViewNameCreate(ctx: ViewNameCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.VIEW_CREATE);
|
||||
}
|
||||
|
||||
exitFunctionNameCreate(ctx: FunctionNameCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.FUNCTION_CREATE);
|
||||
}
|
||||
|
||||
exitColumnNameCreate(ctx: ColumnNameCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.COLUMN_CREATE);
|
||||
}
|
||||
|
||||
/** ===== Statement begin */
|
||||
enterSingleStatement(ctx: SingleStatementContext) {
|
||||
this.pushStmt(ctx, StmtContextType.COMMON_STMT);
|
||||
}
|
||||
|
||||
exitSingleStatement(ctx: SingleStatementContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterQueryCreateTable(ctx: QueryCreateTableContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_TABLE_STMT);
|
||||
}
|
||||
|
||||
exitQueryCreateTable(ctx: QueryCreateTableContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterColumnCreateTable(ctx: ColumnCreateTableContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_TABLE_STMT);
|
||||
}
|
||||
|
||||
exitColumnCreateTable(ctx: ColumnCreateTableContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCopyCreateTable(ctx: CopyCreateTableContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_TABLE_STMT);
|
||||
}
|
||||
|
||||
exitCopyCreateTable(ctx: CopyCreateTableContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateView(ctx: CreateViewContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_VIEW_STMT);
|
||||
}
|
||||
|
||||
exitCreateView(ctx: CreateViewContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterSimpleSelect(ctx: SelectStatementContext) {
|
||||
this.pushStmt(ctx, StmtContextType.SELECT_STMT);
|
||||
}
|
||||
|
||||
exitSimpleSelect(ctx: SelectStatementContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterUnionAndLateralSelect(ctx: SelectStatementContext) {
|
||||
this.pushStmt(ctx, StmtContextType.SELECT_STMT);
|
||||
}
|
||||
|
||||
exitUnionAndLateralSelect(ctx: SelectStatementContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterSelectExpression(ctx: SelectStatementContext) {
|
||||
this.pushStmt(ctx, StmtContextType.SELECT_STMT);
|
||||
}
|
||||
|
||||
exitSelectExpression(ctx: SelectStatementContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterInsertStatement(ctx: InsertStatementContext) {
|
||||
this.pushStmt(ctx, StmtContextType.INSERT_STMT);
|
||||
}
|
||||
|
||||
exitInsertStatement(ctx: InsertStatementContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateDatabase(ctx: CreateDatabaseContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_DATABASE_STMT);
|
||||
}
|
||||
|
||||
exitCreateDatabase(ctx: CreateDatabaseContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateFunction(ctx: CreateFunctionContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_FUNCTION_STMT);
|
||||
}
|
||||
|
||||
exitCreateFunction(ctx: CreateFunctionContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
}
|
12
src/parser/mysql/mysqlSplitListener.ts
Normal file
12
src/parser/mysql/mysqlSplitListener.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { SingleStatementContext } from '../../lib/mysql/MySqlParser';
|
||||
import { MySqlParserListener } from '../../lib/mysql/MySqlParserListener';
|
||||
import SplitListener from '../common/splitListener';
|
||||
|
||||
export default class MysqlSplitListener
|
||||
extends SplitListener<SingleStatementContext>
|
||||
implements MySqlParserListener
|
||||
{
|
||||
exitSingleStatement = (ctx: SingleStatementContext) => {
|
||||
this._statementsContext.push(ctx);
|
||||
};
|
||||
}
|
@ -1,10 +1,15 @@
|
||||
import { Token } from 'antlr4ng';
|
||||
import { CandidatesCollection } from 'antlr4-c3';
|
||||
import { PostgreSQLLexer } from '../lib/pgsql/PostgreSQLLexer';
|
||||
import { PostgreSQLParser, ProgramContext, SingleStmtContext } from '../lib/pgsql/PostgreSQLParser';
|
||||
import BasicParser from './common/basicParser';
|
||||
import { PostgreSQLParserListener } from '../lib/pgsql/PostgreSQLParserListener';
|
||||
import { SyntaxContextType, Suggestions, SyntaxSuggestion } from './common/basic-parser-types';
|
||||
import { Token } from 'antlr4ng';
|
||||
|
||||
import { PostgreSQLLexer } from '../../lib/pgsql/PostgreSQLLexer';
|
||||
import { PostgreSQLParser, ProgramContext } from '../../lib/pgsql/PostgreSQLParser';
|
||||
import { EntityContextType, Suggestions, SyntaxSuggestion } from '../common/basic-parser-types';
|
||||
import BasicParser from '../common/basicParser';
|
||||
import { StmtContextType } from '../common/entityCollector';
|
||||
import PostgreSQLEntityCollector from './postgreEntityCollector';
|
||||
import PostgreSqlSplitListener from './postgreSplitListener';
|
||||
|
||||
export { PostgreSQLEntityCollector, PostgreSqlSplitListener };
|
||||
|
||||
export default class PostgresSQL extends BasicParser<
|
||||
PostgreSQLLexer,
|
||||
@ -38,7 +43,11 @@ export default class PostgresSQL extends BasicParser<
|
||||
]);
|
||||
|
||||
protected get splitListener() {
|
||||
return new PgSqlSplitListener();
|
||||
return new PostgreSqlSplitListener();
|
||||
}
|
||||
|
||||
protected createEntityCollector(input: string, caretTokenIndex?: number) {
|
||||
return new PostgreSQLEntityCollector(input, caretTokenIndex);
|
||||
}
|
||||
|
||||
protected processCandidates(
|
||||
@ -57,62 +66,62 @@ export default class PostgresSQL extends BasicParser<
|
||||
caretTokenIndex + tokenIndexOffset + 1
|
||||
);
|
||||
|
||||
let syntaxContextType: SyntaxContextType;
|
||||
let syntaxContextType: EntityContextType | StmtContextType;
|
||||
switch (ruleType) {
|
||||
case PostgreSQLParser.RULE_table_name_create: {
|
||||
syntaxContextType = SyntaxContextType.TABLE_CREATE;
|
||||
syntaxContextType = EntityContextType.TABLE_CREATE;
|
||||
break;
|
||||
}
|
||||
case PostgreSQLParser.RULE_table_name: {
|
||||
syntaxContextType = SyntaxContextType.TABLE;
|
||||
syntaxContextType = EntityContextType.TABLE;
|
||||
break;
|
||||
}
|
||||
case PostgreSQLParser.RULE_function_name_create: {
|
||||
syntaxContextType = SyntaxContextType.FUNCTION_CREATE;
|
||||
syntaxContextType = EntityContextType.FUNCTION_CREATE;
|
||||
break;
|
||||
}
|
||||
case PostgreSQLParser.RULE_function_name: {
|
||||
syntaxContextType = SyntaxContextType.FUNCTION;
|
||||
syntaxContextType = EntityContextType.FUNCTION;
|
||||
break;
|
||||
}
|
||||
case PostgreSQLParser.RULE_schema_name_create: {
|
||||
syntaxContextType = SyntaxContextType.DATABASE_CREATE;
|
||||
syntaxContextType = EntityContextType.DATABASE_CREATE;
|
||||
break;
|
||||
}
|
||||
case PostgreSQLParser.RULE_schema_name: {
|
||||
syntaxContextType = SyntaxContextType.DATABASE;
|
||||
syntaxContextType = EntityContextType.DATABASE;
|
||||
break;
|
||||
}
|
||||
case PostgreSQLParser.RULE_view_name_create: {
|
||||
syntaxContextType = SyntaxContextType.VIEW_CREATE;
|
||||
syntaxContextType = EntityContextType.VIEW_CREATE;
|
||||
break;
|
||||
}
|
||||
case PostgreSQLParser.RULE_view_name: {
|
||||
syntaxContextType = SyntaxContextType.VIEW;
|
||||
syntaxContextType = EntityContextType.VIEW;
|
||||
break;
|
||||
}
|
||||
case PostgreSQLParser.RULE_database_name_create: {
|
||||
syntaxContextType = SyntaxContextType.DATABASE_CREATE;
|
||||
syntaxContextType = EntityContextType.DATABASE_CREATE;
|
||||
break;
|
||||
}
|
||||
case PostgreSQLParser.RULE_database_name: {
|
||||
syntaxContextType = SyntaxContextType.DATABASE;
|
||||
syntaxContextType = EntityContextType.DATABASE;
|
||||
break;
|
||||
}
|
||||
case PostgreSQLParser.RULE_procedure_name_create: {
|
||||
syntaxContextType = SyntaxContextType.PROCEDURE_CREATE;
|
||||
syntaxContextType = EntityContextType.PROCEDURE_CREATE;
|
||||
break;
|
||||
}
|
||||
case PostgreSQLParser.RULE_procedure_name: {
|
||||
syntaxContextType = SyntaxContextType.PROCEDURE;
|
||||
syntaxContextType = EntityContextType.PROCEDURE;
|
||||
break;
|
||||
}
|
||||
case PostgreSQLParser.RULE_column_name_create: {
|
||||
syntaxContextType = SyntaxContextType.COLUMN_CREATE;
|
||||
syntaxContextType = EntityContextType.COLUMN_CREATE;
|
||||
break;
|
||||
}
|
||||
case PostgreSQLParser.RULE_column_name: {
|
||||
syntaxContextType = SyntaxContextType.COLUMN;
|
||||
syntaxContextType = EntityContextType.COLUMN;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -144,20 +153,3 @@ export default class PostgresSQL extends BasicParser<
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class PgSqlSplitListener implements PostgreSQLParserListener {
|
||||
private _statementsContext: SingleStmtContext[] = [];
|
||||
|
||||
exitSingleStmt = (ctx: SingleStmtContext) => {
|
||||
this._statementsContext.push(ctx);
|
||||
};
|
||||
|
||||
visitTerminal() {}
|
||||
visitErrorNode() {}
|
||||
enterEveryRule() {}
|
||||
exitEveryRule() {}
|
||||
|
||||
get statementsContext() {
|
||||
return this._statementsContext;
|
||||
}
|
||||
}
|
151
src/parser/pgsql/postgreEntityCollector.ts
Normal file
151
src/parser/pgsql/postgreEntityCollector.ts
Normal file
@ -0,0 +1,151 @@
|
||||
import type {
|
||||
ColumnCreateTableContext,
|
||||
ColumnNameCreateContext,
|
||||
CreateDatabaseContext,
|
||||
CreateForeignTableContext,
|
||||
CreateMaterializedViewContext,
|
||||
CreatePartitionForeignTableContext,
|
||||
CreateViewContext,
|
||||
CreatefunctionstmtContext,
|
||||
DatabaseNameContext,
|
||||
DatabaseNameCreateContext,
|
||||
FunctionNameCreateContext,
|
||||
InsertStatementContext,
|
||||
QueryCreateTableContext,
|
||||
SelectStatementContext,
|
||||
SingleStmtContext,
|
||||
TableNameContext,
|
||||
TableNameCreateContext,
|
||||
ViewNameContext,
|
||||
ViewNameCreateContext,
|
||||
} from '../../lib/pgsql/PostgreSQLParser';
|
||||
import type { PostgreSQLParserListener } from '../../lib/pgsql/PostgreSQLParserListener';
|
||||
import { EntityContextType } from '../common/basic-parser-types';
|
||||
import EntityCollector, { StmtContextType } from '../common/entityCollector';
|
||||
|
||||
export default class PostgreSQLEntityCollector
|
||||
extends EntityCollector
|
||||
implements PostgreSQLParserListener
|
||||
{
|
||||
/** ====== Entity Begin */
|
||||
exitDatabaseName(ctx: DatabaseNameContext) {
|
||||
this.pushEntity(ctx, EntityContextType.DATABASE);
|
||||
}
|
||||
|
||||
exitDatabaseNameCreate(ctx: DatabaseNameCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.DATABASE_CREATE);
|
||||
}
|
||||
|
||||
exitTableName(ctx: TableNameContext) {
|
||||
this.pushEntity(ctx, EntityContextType.TABLE);
|
||||
}
|
||||
|
||||
exitTableNameCreate(ctx: TableNameCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.TABLE_CREATE);
|
||||
}
|
||||
|
||||
exitViewName(ctx: ViewNameContext) {
|
||||
this.pushEntity(ctx, EntityContextType.VIEW);
|
||||
}
|
||||
|
||||
exitViewNameCreate(ctx: ViewNameCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.VIEW_CREATE);
|
||||
}
|
||||
|
||||
exitFunctionNameCreate(ctx: FunctionNameCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.FUNCTION_CREATE);
|
||||
}
|
||||
|
||||
exitColumnNameCreate(ctx: ColumnNameCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.COLUMN_CREATE);
|
||||
}
|
||||
|
||||
/** ===== Statement begin */
|
||||
enterSingleStatement(ctx: SingleStmtContext) {
|
||||
this.pushStmt(ctx, StmtContextType.COMMON_STMT);
|
||||
}
|
||||
|
||||
exitSingleStatement(ctx: SingleStmtContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateDatabase(ctx: CreateDatabaseContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_DATABASE_STMT);
|
||||
}
|
||||
|
||||
exitCreateDatabase(ctx: CreateDatabaseContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterQueryCreateTable(ctx: QueryCreateTableContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_TABLE_STMT);
|
||||
}
|
||||
|
||||
exitQueryCreateTable(ctx: QueryCreateTableContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterColumnCreateTable(ctx: ColumnCreateTableContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_TABLE_STMT);
|
||||
}
|
||||
|
||||
exitColumnCreateTable(ctx: ColumnCreateTableContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateForeignTable(ctx: CreateForeignTableContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_TABLE_STMT);
|
||||
}
|
||||
|
||||
exitCreateForeignTable(ctx: CreateForeignTableContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreatePartitionForeignTable(ctx: CreatePartitionForeignTableContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_TABLE_STMT);
|
||||
}
|
||||
|
||||
exitCreatePartitionForeignTable(ctx: CreatePartitionForeignTableContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateView(ctx: CreateViewContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_VIEW_STMT);
|
||||
}
|
||||
|
||||
exitCreateView(ctx: CreateViewContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateMaterializedView(ctx: CreateMaterializedViewContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_VIEW_STMT);
|
||||
}
|
||||
|
||||
exitCreateMaterializedView(ctx: CreateMaterializedViewContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterSelectStatement(ctx: SelectStatementContext) {
|
||||
this.pushStmt(ctx, StmtContextType.SELECT_STMT);
|
||||
}
|
||||
|
||||
exitSelectStatement(ctx: SelectStatementContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterInsertStatement(ctx: InsertStatementContext) {
|
||||
this.pushStmt(ctx, StmtContextType.INSERT_STMT);
|
||||
}
|
||||
|
||||
exitInsertStatement(ctx: InsertStatementContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreatefunctionstmt(ctx: CreatefunctionstmtContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_FUNCTION_STMT);
|
||||
}
|
||||
|
||||
exitCreatefunctionstmt(ctx: CreatefunctionstmtContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
}
|
12
src/parser/pgsql/postgreSplitListener.ts
Normal file
12
src/parser/pgsql/postgreSplitListener.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { SingleStmtContext } from '../../lib/pgsql/PostgreSQLParser';
|
||||
import { PostgreSQLParserListener } from '../../lib/pgsql/PostgreSQLParserListener';
|
||||
import SplitListener from '../common/splitListener';
|
||||
|
||||
export default class PostgreSqlSplitListener
|
||||
extends SplitListener<SingleStmtContext>
|
||||
implements PostgreSQLParserListener
|
||||
{
|
||||
exitSingleStmt = (ctx: SingleStmtContext) => {
|
||||
this._statementsContext.push(ctx);
|
||||
};
|
||||
}
|
@ -21,6 +21,10 @@ export default class PLSQL extends BasicParser<PlSqlLexer, ProgramContext, PlSql
|
||||
return null as any;
|
||||
}
|
||||
|
||||
protected createEntityCollector(input: string, caretTokenIndex?: number) {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected processCandidates(
|
||||
candidates: CandidatesCollection,
|
||||
allTokens: Token[],
|
||||
|
@ -1,14 +1,14 @@
|
||||
import { Token } from 'antlr4ng';
|
||||
import { CandidatesCollection } from 'antlr4-c3';
|
||||
import { SparkSqlLexer } from '../lib/spark/SparkSqlLexer';
|
||||
import {
|
||||
SparkSqlParser,
|
||||
ProgramContext,
|
||||
SingleStatementContext,
|
||||
} from '../lib/spark/SparkSqlParser';
|
||||
import BasicParser from './common/basicParser';
|
||||
import { Suggestions, SyntaxContextType, SyntaxSuggestion } from './common/basic-parser-types';
|
||||
import { SparkSqlParserListener } from '../lib/spark/SparkSqlParserListener';
|
||||
import { SparkSqlLexer } from '../../lib/spark/SparkSqlLexer';
|
||||
import { SparkSqlParser, ProgramContext } from '../../lib/spark/SparkSqlParser';
|
||||
import BasicParser from '../common/basicParser';
|
||||
import { Suggestions, EntityContextType, SyntaxSuggestion } from '../common/basic-parser-types';
|
||||
import { StmtContextType } from '../common/entityCollector';
|
||||
import SparkSqlSplitListener from './sparkSplitListener';
|
||||
import SparkEntityCollector from './sparkEntityCollector';
|
||||
|
||||
export { SparkSqlSplitListener, SparkEntityCollector };
|
||||
|
||||
export default class SparkSQL extends BasicParser<SparkSqlLexer, ProgramContext, SparkSqlParser> {
|
||||
protected createLexerFromCharStream(charStreams) {
|
||||
@ -22,8 +22,8 @@ export default class SparkSQL extends BasicParser<SparkSqlLexer, ProgramContext,
|
||||
}
|
||||
|
||||
protected preferredRules: Set<number> = new Set([
|
||||
SparkSqlParser.RULE_dbSchemaName,
|
||||
SparkSqlParser.RULE_dbSchemaNameCreate,
|
||||
SparkSqlParser.RULE_namespaceName,
|
||||
SparkSqlParser.RULE_namespaceNameCreate,
|
||||
SparkSqlParser.RULE_tableName,
|
||||
SparkSqlParser.RULE_tableNameCreate,
|
||||
SparkSqlParser.RULE_viewName,
|
||||
@ -38,6 +38,10 @@ export default class SparkSQL extends BasicParser<SparkSqlLexer, ProgramContext,
|
||||
return new SparkSqlSplitListener();
|
||||
}
|
||||
|
||||
protected createEntityCollector(input: string, caretTokenIndex?: number) {
|
||||
return new SparkEntityCollector(input, caretTokenIndex);
|
||||
}
|
||||
|
||||
protected processCandidates(
|
||||
candidates: CandidatesCollection,
|
||||
allTokens: Token[],
|
||||
@ -55,46 +59,46 @@ export default class SparkSQL extends BasicParser<SparkSqlLexer, ProgramContext,
|
||||
caretTokenIndex + tokenIndexOffset + 1
|
||||
);
|
||||
|
||||
let syntaxContextType: SyntaxContextType;
|
||||
let syntaxContextType: EntityContextType | StmtContextType;
|
||||
switch (ruleType) {
|
||||
case SparkSqlParser.RULE_dbSchemaName: {
|
||||
syntaxContextType = SyntaxContextType.DATABASE;
|
||||
case SparkSqlParser.RULE_namespaceName: {
|
||||
syntaxContextType = EntityContextType.DATABASE;
|
||||
break;
|
||||
}
|
||||
case SparkSqlParser.RULE_dbSchemaNameCreate: {
|
||||
syntaxContextType = SyntaxContextType.DATABASE_CREATE;
|
||||
case SparkSqlParser.RULE_namespaceNameCreate: {
|
||||
syntaxContextType = EntityContextType.DATABASE_CREATE;
|
||||
break;
|
||||
}
|
||||
case SparkSqlParser.RULE_tableName: {
|
||||
syntaxContextType = SyntaxContextType.TABLE;
|
||||
syntaxContextType = EntityContextType.TABLE;
|
||||
break;
|
||||
}
|
||||
case SparkSqlParser.RULE_tableNameCreate: {
|
||||
syntaxContextType = SyntaxContextType.TABLE_CREATE;
|
||||
syntaxContextType = EntityContextType.TABLE_CREATE;
|
||||
break;
|
||||
}
|
||||
case SparkSqlParser.RULE_viewName: {
|
||||
syntaxContextType = SyntaxContextType.VIEW;
|
||||
syntaxContextType = EntityContextType.VIEW;
|
||||
break;
|
||||
}
|
||||
case SparkSqlParser.RULE_viewNameCreate: {
|
||||
syntaxContextType = SyntaxContextType.VIEW_CREATE;
|
||||
syntaxContextType = EntityContextType.VIEW_CREATE;
|
||||
break;
|
||||
}
|
||||
case SparkSqlParser.RULE_functionName: {
|
||||
syntaxContextType = SyntaxContextType.FUNCTION;
|
||||
syntaxContextType = EntityContextType.FUNCTION;
|
||||
break;
|
||||
}
|
||||
case SparkSqlParser.RULE_functionNameCreate: {
|
||||
syntaxContextType = SyntaxContextType.FUNCTION_CREATE;
|
||||
syntaxContextType = EntityContextType.FUNCTION_CREATE;
|
||||
break;
|
||||
}
|
||||
case SparkSqlParser.RULE_columnName: {
|
||||
syntaxContextType = SyntaxContextType.COLUMN;
|
||||
syntaxContextType = EntityContextType.COLUMN;
|
||||
break;
|
||||
}
|
||||
case SparkSqlParser.RULE_columnNameCreate: {
|
||||
syntaxContextType = SyntaxContextType.COLUMN_CREATE;
|
||||
syntaxContextType = EntityContextType.COLUMN_CREATE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -127,20 +131,3 @@ export default class SparkSQL extends BasicParser<SparkSqlLexer, ProgramContext,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class SparkSqlSplitListener implements SparkSqlParserListener {
|
||||
private _statementsContext: SingleStatementContext[] = [];
|
||||
|
||||
exitSingleStatement = (ctx: SingleStatementContext) => {
|
||||
this._statementsContext.push(ctx);
|
||||
};
|
||||
|
||||
visitTerminal() {}
|
||||
visitErrorNode() {}
|
||||
enterEveryRule() {}
|
||||
exitEveryRule() {}
|
||||
|
||||
get statementsContext() {
|
||||
return this._statementsContext;
|
||||
}
|
||||
}
|
151
src/parser/spark/sparkEntityCollector.ts
Normal file
151
src/parser/spark/sparkEntityCollector.ts
Normal file
@ -0,0 +1,151 @@
|
||||
import type {
|
||||
NamespaceNameContext,
|
||||
NamespaceNameCreateContext,
|
||||
SingleStatementContext,
|
||||
TableNameContext,
|
||||
TableNameCreateContext,
|
||||
ViewNameContext,
|
||||
ViewNameCreateContext,
|
||||
FunctionNameCreateContext,
|
||||
ColumnNameCreateContext,
|
||||
CreateTableContext,
|
||||
CreateTableLikeContext,
|
||||
ReplaceTableContext,
|
||||
QueryStatementContext,
|
||||
InsertFromQueryContext,
|
||||
MultipleInsertContext,
|
||||
CreateViewContext,
|
||||
CreateTempViewUsingContext,
|
||||
CreateNamespaceContext,
|
||||
CreateFunctionContext,
|
||||
} from '../../lib/spark/SparkSqlParser';
|
||||
import type { SparkSqlParserListener } from '../../lib/spark/SparkSqlParserListener';
|
||||
import { EntityContextType } from '../common/basic-parser-types';
|
||||
import EntityCollector, { StmtContextType } from '../common/entityCollector';
|
||||
|
||||
export default class SparkEntityCollector
|
||||
extends EntityCollector
|
||||
implements SparkSqlParserListener
|
||||
{
|
||||
/** ====== Entity Begin */
|
||||
exitNamespaceName(ctx: NamespaceNameContext) {
|
||||
this.pushEntity(ctx, EntityContextType.DATABASE);
|
||||
}
|
||||
|
||||
exitNamespaceNameCreate(ctx: NamespaceNameCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.DATABASE_CREATE);
|
||||
}
|
||||
|
||||
exitTableName(ctx: TableNameContext) {
|
||||
this.pushEntity(ctx, EntityContextType.TABLE);
|
||||
}
|
||||
|
||||
exitTableNameCreate(ctx: TableNameCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.TABLE_CREATE);
|
||||
}
|
||||
|
||||
exitViewName(ctx: ViewNameContext) {
|
||||
this.pushEntity(ctx, EntityContextType.VIEW);
|
||||
}
|
||||
|
||||
exitViewNameCreate(ctx: ViewNameCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.VIEW_CREATE);
|
||||
}
|
||||
|
||||
exitFunctionNameCreate(ctx: FunctionNameCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.FUNCTION_CREATE);
|
||||
}
|
||||
|
||||
exitColumnNameCreate(ctx: ColumnNameCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.COLUMN_CREATE);
|
||||
}
|
||||
|
||||
/** ===== Statement begin */
|
||||
enterSingleStatement(ctx: SingleStatementContext) {
|
||||
this.pushStmt(ctx, StmtContextType.COMMON_STMT);
|
||||
}
|
||||
|
||||
exitSingleStatement(ctx: SingleStatementContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateTable(ctx: CreateTableContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_TABLE_STMT);
|
||||
}
|
||||
|
||||
exitCreateTable(ctx: CreateTableContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateTableLike(ctx: CreateTableLikeContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_TABLE_STMT);
|
||||
}
|
||||
|
||||
exitCreateTableLike(ctx: CreateTableLikeContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterReplaceTable(ctx: ReplaceTableContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_TABLE_STMT);
|
||||
}
|
||||
|
||||
exitReplaceTable(ctx: ReplaceTableContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateView(ctx: CreateViewContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_VIEW_STMT);
|
||||
}
|
||||
|
||||
exitCreateView(ctx: CreateViewContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateTempViewUsing(ctx: CreateTempViewUsingContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_VIEW_STMT);
|
||||
}
|
||||
|
||||
exitCreateTempViewUsing(ctx: CreateTempViewUsingContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterQueryStatement(ctx: QueryStatementContext) {
|
||||
this.pushStmt(ctx, StmtContextType.SELECT_STMT);
|
||||
}
|
||||
|
||||
exitQueryStatement(ctx: QueryStatementContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterInsertFromQuery(ctx: InsertFromQueryContext) {
|
||||
this.pushStmt(ctx, StmtContextType.INSERT_STMT);
|
||||
}
|
||||
|
||||
exitInsertFromQuery(ctx: InsertFromQueryContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterMultipleInsert(ctx: MultipleInsertContext) {
|
||||
this.pushStmt(ctx, StmtContextType.INSERT_STMT);
|
||||
}
|
||||
|
||||
exitMultipleInsert(ctx: MultipleInsertContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateNamespace(ctx: CreateNamespaceContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_DATABASE_STMT);
|
||||
}
|
||||
|
||||
exitCreateNamespace(ctx: CreateNamespaceContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateFunction(ctx: CreateFunctionContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_FUNCTION_STMT);
|
||||
}
|
||||
|
||||
exitCreateFunction(ctx: CreateFunctionContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
}
|
13
src/parser/spark/sparkSplitListener.ts
Normal file
13
src/parser/spark/sparkSplitListener.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { SingleStatementContext } from '../../lib/spark/SparkSqlParser';
|
||||
|
||||
import { SparkSqlParserListener } from '../../lib/spark/SparkSqlParserListener';
|
||||
import SplitListener from '../common/splitListener';
|
||||
|
||||
export default class SparkSqlSplitListener
|
||||
extends SplitListener<SingleStatementContext>
|
||||
implements SparkSqlParserListener
|
||||
{
|
||||
exitSingleStatement = (ctx: SingleStatementContext) => {
|
||||
this._statementsContext.push(ctx);
|
||||
};
|
||||
}
|
@ -1,14 +1,14 @@
|
||||
import { Token } from 'antlr4ng';
|
||||
import { CandidatesCollection } from 'antlr4-c3';
|
||||
import { TrinoSqlLexer } from '../lib/trinosql/TrinoSqlLexer';
|
||||
import {
|
||||
TrinoSqlParser,
|
||||
ProgramContext,
|
||||
SingleStatementContext,
|
||||
} from '../lib/trinosql/TrinoSqlParser';
|
||||
import { TrinoSqlListener } from '../lib/trinosql/TrinoSqlListener';
|
||||
import BasicParser from './common/basicParser';
|
||||
import { Suggestions, SyntaxContextType, SyntaxSuggestion } from './common/basic-parser-types';
|
||||
import { TrinoSqlLexer } from '../../lib/trinosql/TrinoSqlLexer';
|
||||
import { TrinoSqlParser, ProgramContext } from '../../lib/trinosql/TrinoSqlParser';
|
||||
import BasicParser from '../common/basicParser';
|
||||
import { Suggestions, EntityContextType, SyntaxSuggestion } from '../common/basic-parser-types';
|
||||
import { StmtContextType } from '../common/entityCollector';
|
||||
import TrinoSqlSplitListener from './trinoSplitListener';
|
||||
import TrinoEntityCollector from './trinoEntityCollector';
|
||||
|
||||
export { TrinoSqlSplitListener, TrinoEntityCollector };
|
||||
|
||||
export default class TrinoSQL extends BasicParser<TrinoSqlLexer, ProgramContext, TrinoSqlParser> {
|
||||
protected createLexerFromCharStream(charStreams) {
|
||||
@ -25,6 +25,10 @@ export default class TrinoSQL extends BasicParser<TrinoSqlLexer, ProgramContext,
|
||||
return new TrinoSqlSplitListener();
|
||||
}
|
||||
|
||||
protected createEntityCollector(input: string, caretTokenIndex?: number) {
|
||||
return new TrinoEntityCollector(input, caretTokenIndex);
|
||||
}
|
||||
|
||||
protected preferredRules: Set<number> = new Set([
|
||||
TrinoSqlParser.RULE_catalogName,
|
||||
TrinoSqlParser.RULE_catalogNameCreate,
|
||||
@ -56,46 +60,46 @@ export default class TrinoSQL extends BasicParser<TrinoSqlLexer, ProgramContext,
|
||||
caretTokenIndex + tokenIndexOffset + 1
|
||||
);
|
||||
|
||||
let syntaxContextType: SyntaxContextType;
|
||||
let syntaxContextType: EntityContextType | StmtContextType;
|
||||
switch (ruleType) {
|
||||
case TrinoSqlParser.RULE_catalogName: {
|
||||
syntaxContextType = SyntaxContextType.CATALOG;
|
||||
syntaxContextType = EntityContextType.CATALOG;
|
||||
break;
|
||||
}
|
||||
case TrinoSqlParser.RULE_schemaName: {
|
||||
syntaxContextType = SyntaxContextType.DATABASE;
|
||||
syntaxContextType = EntityContextType.DATABASE;
|
||||
break;
|
||||
}
|
||||
case TrinoSqlParser.RULE_schemaNameCreate: {
|
||||
syntaxContextType = SyntaxContextType.DATABASE_CREATE;
|
||||
syntaxContextType = EntityContextType.DATABASE_CREATE;
|
||||
break;
|
||||
}
|
||||
case TrinoSqlParser.RULE_tableName: {
|
||||
syntaxContextType = SyntaxContextType.TABLE;
|
||||
syntaxContextType = EntityContextType.TABLE;
|
||||
break;
|
||||
}
|
||||
case TrinoSqlParser.RULE_tableNameCreate: {
|
||||
syntaxContextType = SyntaxContextType.TABLE_CREATE;
|
||||
syntaxContextType = EntityContextType.TABLE_CREATE;
|
||||
break;
|
||||
}
|
||||
case TrinoSqlParser.RULE_viewName: {
|
||||
syntaxContextType = SyntaxContextType.VIEW;
|
||||
syntaxContextType = EntityContextType.VIEW;
|
||||
break;
|
||||
}
|
||||
case TrinoSqlParser.RULE_viewNameCreate: {
|
||||
syntaxContextType = SyntaxContextType.VIEW_CREATE;
|
||||
syntaxContextType = EntityContextType.VIEW_CREATE;
|
||||
break;
|
||||
}
|
||||
case TrinoSqlParser.RULE_functionName: {
|
||||
syntaxContextType = SyntaxContextType.FUNCTION;
|
||||
syntaxContextType = EntityContextType.FUNCTION;
|
||||
break;
|
||||
}
|
||||
case TrinoSqlParser.RULE_columnNameCreate: {
|
||||
syntaxContextType = SyntaxContextType.COLUMN_CREATE;
|
||||
syntaxContextType = EntityContextType.COLUMN_CREATE;
|
||||
break;
|
||||
}
|
||||
case TrinoSqlParser.RULE_columnName: {
|
||||
syntaxContextType = SyntaxContextType.COLUMN;
|
||||
syntaxContextType = EntityContextType.COLUMN;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -127,20 +131,3 @@ export default class TrinoSQL extends BasicParser<TrinoSqlLexer, ProgramContext,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class TrinoSqlSplitListener implements TrinoSqlListener {
|
||||
private _statementsContext: SingleStatementContext[] = [];
|
||||
|
||||
exitSingleStatement = (ctx: SingleStatementContext) => {
|
||||
this._statementsContext.push(ctx);
|
||||
};
|
||||
|
||||
visitTerminal() {}
|
||||
visitErrorNode() {}
|
||||
enterEveryRule() {}
|
||||
exitEveryRule() {}
|
||||
|
||||
get statementsContext() {
|
||||
return this._statementsContext;
|
||||
}
|
||||
}
|
117
src/parser/trino/trinoEntityCollector.ts
Normal file
117
src/parser/trino/trinoEntityCollector.ts
Normal file
@ -0,0 +1,117 @@
|
||||
import type {
|
||||
ColumnNameCreateContext,
|
||||
CreateMaterializedViewContext,
|
||||
CreateSchemaContext,
|
||||
CreateTableAsSelectContext,
|
||||
CreateTableContext,
|
||||
CreateViewContext,
|
||||
InsertIntoContext,
|
||||
QueryStatementContext,
|
||||
SchemaNameContext,
|
||||
SchemaNameCreateContext,
|
||||
SingleStatementContext,
|
||||
TableNameContext,
|
||||
TableNameCreateContext,
|
||||
ViewNameContext,
|
||||
ViewNameCreateContext,
|
||||
} from '../../lib/trinosql/TrinoSqlParser';
|
||||
import type { TrinoSqlListener } from '../../lib/trinosql/TrinoSqlListener';
|
||||
import { EntityContextType } from '../common/basic-parser-types';
|
||||
import EntityCollector, { StmtContextType } from '../common/entityCollector';
|
||||
|
||||
export default class TrinoEntityCollector extends EntityCollector implements TrinoSqlListener {
|
||||
/** ====== Entity Begin */
|
||||
exitSchemaName(ctx: SchemaNameContext) {
|
||||
this.pushEntity(ctx, EntityContextType.DATABASE);
|
||||
}
|
||||
|
||||
exitSchemaNameCreate(ctx: SchemaNameCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.DATABASE_CREATE);
|
||||
}
|
||||
|
||||
exitTableName(ctx: TableNameContext) {
|
||||
this.pushEntity(ctx, EntityContextType.TABLE);
|
||||
}
|
||||
|
||||
exitTableNameCreate(ctx: TableNameCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.TABLE_CREATE);
|
||||
}
|
||||
|
||||
exitViewName(ctx: ViewNameContext) {
|
||||
this.pushEntity(ctx, EntityContextType.VIEW);
|
||||
}
|
||||
|
||||
exitViewNameCreate(ctx: ViewNameCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.VIEW_CREATE);
|
||||
}
|
||||
|
||||
exitColumnNameCreate(ctx: ColumnNameCreateContext) {
|
||||
this.pushEntity(ctx, EntityContextType.COLUMN_CREATE);
|
||||
}
|
||||
|
||||
/** ===== Statement begin */
|
||||
|
||||
enterSingleStatement(ctx: SingleStatementContext) {
|
||||
this.pushStmt(ctx, StmtContextType.COMMON_STMT);
|
||||
}
|
||||
|
||||
exitSingleStatement(ctx: SingleStatementContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateSchema(ctx: CreateSchemaContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_DATABASE_STMT);
|
||||
}
|
||||
|
||||
exitCreateSchema(ctx: CreateSchemaContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateTableAsSelect(ctx: CreateTableAsSelectContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_TABLE_STMT);
|
||||
}
|
||||
|
||||
exitCreateTableAsSelect(ctx: CreateTableAsSelectContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateTable(ctx: CreateTableContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_TABLE_STMT);
|
||||
}
|
||||
|
||||
exitCreateTable(ctx: CreateTableContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateView(ctx: CreateViewContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_VIEW_STMT);
|
||||
}
|
||||
|
||||
exitCreateView(ctx: CreateViewContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterCreateMaterializedView(ctx: CreateMaterializedViewContext) {
|
||||
this.pushStmt(ctx, StmtContextType.CREATE_VIEW_STMT);
|
||||
}
|
||||
|
||||
exitCreateMaterializedView(ctx: CreateMaterializedViewContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterQueryStatement(ctx: QueryStatementContext) {
|
||||
this.pushStmt(ctx, StmtContextType.SELECT_STMT);
|
||||
}
|
||||
|
||||
exitQueryStatement(ctx: QueryStatementContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
|
||||
enterInsertInto(ctx: InsertIntoContext) {
|
||||
this.pushStmt(ctx, StmtContextType.INSERT_STMT);
|
||||
}
|
||||
|
||||
exitInsertInto(ctx: InsertIntoContext) {
|
||||
this.popStmt();
|
||||
}
|
||||
}
|
12
src/parser/trino/trinoSplitListener.ts
Normal file
12
src/parser/trino/trinoSplitListener.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { SingleStatementContext } from '../../lib/trinosql/TrinoSqlParser';
|
||||
import { TrinoSqlListener } from '../../lib/trinosql/TrinoSqlListener';
|
||||
import SplitListener from '../common/splitListener';
|
||||
|
||||
export default class TrinoSqlSplitListener
|
||||
extends SplitListener<SingleStatementContext>
|
||||
implements TrinoSqlListener
|
||||
{
|
||||
exitSingleStatement = (ctx: SingleStatementContext) => {
|
||||
this._statementsContext.push(ctx);
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user