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:
Hayden
2024-03-26 14:28:27 +08:00
committed by GitHub
parent 3f62ad0d32
commit a99721162b
230 changed files with 56908 additions and 46672 deletions

View File

@ -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;
}

View File

@ -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();
}
}

View 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;

View File

@ -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)

View 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;

View File

@ -0,0 +1,17 @@
abstract class SplitListener<T> {
protected _statementsContext: T[] = [];
visitTerminal() {}
visitErrorNode() {}
enterEveryRule() {}
exitEveryRule() {}
get statementsContext() {
return this._statementsContext;
}
}
export default SplitListener;

View 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,
};
}

View 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();
}
}

View 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);
};
}

View File

@ -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;
}
}

View 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();
}
}

View 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);
};
}

View File

@ -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;
}
}

View 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();
}
}

View 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);
};
}

View File

@ -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;
}
}

View File

@ -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';

View File

@ -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;
}
}

View 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();
}
}

View 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);
};
}

View File

@ -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;
}
}

View 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();
}
}

View 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);
};
}

View File

@ -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[],

View File

@ -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;
}
}

View 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();
}
}

View 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);
};
}

View File

@ -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;
}
}

View 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();
}
}

View 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);
};
}