Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/parser/common/basicSQL.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export abstract class BasicSQL<
*/
protected abstract createEntityCollector(
input: string,
allTokens?: Token[],
caretTokenIndex?: number
): EntityCollector;

Expand Down Expand Up @@ -378,7 +379,7 @@ export abstract class BasicSQL<
? findCaretTokenIndex(caretPosition, allTokens)
: void 0;

const collectListener = this.createEntityCollector(input, caretTokenIndex);
const collectListener = this.createEntityCollector(input, allTokens, caretTokenIndex);
// const parser = this.createParserWithCache(input);

// parser.entityCollecting = true;
Expand Down
25 changes: 22 additions & 3 deletions src/parser/common/entityCollector.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ParserRuleContext } from 'antlr4ng';
import { ParserRuleContext, Token } from 'antlr4ng';
import { EntityContextType } from './types';
import { WordPosition, TextPosition } from './textAndWord';
import { ctxToText, ctxToWord } from './textAndWord';
Expand Down Expand Up @@ -96,15 +96,17 @@ export function toEntityContext(
* @todo: [may be need] Combine the entities in each clause.
*/
export abstract class EntityCollector {
constructor(input: string, caretTokenIndex?: number) {
constructor(input: string, allTokens?: Token[], caretTokenIndex?: number) {
this._input = input;
this._allTokens = allTokens || [];
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 _allTokens: Token[];
private readonly _caretTokenIndex: number;
private readonly _entitiesSet: Set<EntityContext>;
/** Staging statements that have already entered. */
Expand Down Expand Up @@ -136,14 +138,31 @@ export abstract class EntityCollector {
this._rootStmt = null;
}

/**
* The antlr4 will ignore hidden tokens, if we type whitespace at the end of a statement,
* the whitespace token will not as stop token, so we consider the whitespace token as a part of the nonhidden token in front of it
*/
protected getPrevNonHiddenTokenIndex(caretTokenIndex: number) {
if (this._allTokens[caretTokenIndex].channel !== Token.HIDDEN_CHANNEL)
return caretTokenIndex;
for (let i = caretTokenIndex - 1; i >= 0; i--) {
const token = this._allTokens[i];
if (token.channel !== Token.HIDDEN_CHANNEL) {
// If prev nonhidden token is ';', the current token does not belong to any statement.
return token.text === ';' ? +Infinity : token.tokenIndex;
}
}
return +Infinity;
}

protected pushStmt(ctx: ParserRuleContext, type: StmtContextType) {
let isContainCaret: boolean | undefined;
if (this._caretTokenIndex >= 0) {
isContainCaret =
!!ctx.start &&
!!ctx.stop &&
ctx.start.tokenIndex <= this._caretTokenIndex &&
ctx.stop.tokenIndex >= this._caretTokenIndex;
ctx.stop.tokenIndex >= this.getPrevNonHiddenTokenIndex(this._caretTokenIndex);
}
const stmtContext = toStmtContext(
ctx,
Expand Down
4 changes: 2 additions & 2 deletions src/parser/flink/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ export class FlinkSQL extends BasicSQL<FlinkSqlLexer, ProgramContext, FlinkSqlPa
return new FlinkSqlSplitListener();
}

protected createEntityCollector(input: string, caretTokenIndex?: number) {
return new FlinkEntityCollector(input, caretTokenIndex);
protected createEntityCollector(input: string, allTokens?: Token[], caretTokenIndex?: number) {
return new FlinkEntityCollector(input, allTokens, caretTokenIndex);
}

protected processCandidates(
Expand Down
4 changes: 2 additions & 2 deletions src/parser/hive/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ export class HiveSQL extends BasicSQL<HiveSqlLexer, ProgramContext, HiveSqlParse
return new HiveSqlSplitListener();
}

protected createEntityCollector(input: string, caretTokenIndex?: number) {
return new HiveEntityCollector(input, caretTokenIndex);
protected createEntityCollector(input: string, allTokens?: Token[], caretTokenIndex?: number) {
return new HiveEntityCollector(input, allTokens, caretTokenIndex);
}

protected processCandidates(
Expand Down
4 changes: 2 additions & 2 deletions src/parser/impala/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ export class ImpalaSQL extends BasicSQL<ImpalaSqlLexer, ProgramContext, ImpalaSq
return new ImpalaSqlSplitListener();
}

protected createEntityCollector(input: string, caretTokenIndex?: number) {
return new ImpalaEntityCollector(input, caretTokenIndex);
protected createEntityCollector(input: string, allTokens?: Token[], caretTokenIndex?: number) {
return new ImpalaEntityCollector(input, allTokens, caretTokenIndex);
}

protected processCandidates(
Expand Down
4 changes: 2 additions & 2 deletions src/parser/mysql/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ export class MySQL extends BasicSQL<MySqlLexer, ProgramContext, MySqlParser> {
return new MysqlSplitListener();
}

protected createEntityCollector(input: string, caretTokenIndex?: number) {
return new MySqlEntityCollector(input, caretTokenIndex);
protected createEntityCollector(input: string, allTokens?: Token[], caretTokenIndex?: number) {
return new MySqlEntityCollector(input, allTokens, caretTokenIndex);
}

protected processCandidates(
Expand Down
4 changes: 2 additions & 2 deletions src/parser/postgresql/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ export class PostgreSQL extends BasicSQL<PostgreSqlLexer, ProgramContext, Postgr
return new PostgreSqlSplitListener();
}

protected createEntityCollector(input: string, caretTokenIndex?: number) {
return new PostgreSqlEntityCollector(input, caretTokenIndex);
protected createEntityCollector(input: string, allTokens?: Token[], caretTokenIndex?: number) {
return new PostgreSqlEntityCollector(input, allTokens, caretTokenIndex);
}

protected processCandidates(
Expand Down
4 changes: 2 additions & 2 deletions src/parser/spark/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ export class SparkSQL extends BasicSQL<SparkSqlLexer, ProgramContext, SparkSqlPa
return new SparkSqlSplitListener();
}

protected createEntityCollector(input: string, caretTokenIndex?: number) {
return new SparkEntityCollector(input, caretTokenIndex);
protected createEntityCollector(input: string, allTokens?: Token[], caretTokenIndex?: number) {
return new SparkEntityCollector(input, allTokens, caretTokenIndex);
}

protected processCandidates(
Expand Down
4 changes: 2 additions & 2 deletions src/parser/trino/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ export class TrinoSQL extends BasicSQL<TrinoSqlLexer, ProgramContext, TrinoSqlPa
return new TrinoSqlSplitListener();
}

protected createEntityCollector(input: string, caretTokenIndex?: number) {
return new TrinoEntityCollector(input, caretTokenIndex);
protected createEntityCollector(input: string, allTokens?: Token[], caretTokenIndex?: number) {
return new TrinoEntityCollector(input, allTokens, caretTokenIndex);
}

protected preferredRules: Set<number> = new Set([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@ INSERT INTO insert_tb PARTITION (country, state) SELECT col1, col2, country, sta

CREATE TABLE IF NOT EXISTS derived_table WITH ('connector' = 'kafka') AS SELECT FROM origin_table;

CREATE TABLE IF NOT EXISTS derived_table WITH ('connector' = 'kafka') AS SELECT id, FROM origin_table;
CREATE TABLE IF NOT EXISTS derived_table WITH ('connector' = 'kafka') AS SELECT id, FROM origin_table;

SELECT id FROM tb WHERE

SELECT id FROM tb GROUP BY ;
20 changes: 20 additions & 0 deletions test/parser/flink/suggestion/suggestionWithEntity.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,24 @@ describe('Flink SQL Syntax Suggestion with collect entity', () => {
expect(entities[1].entityContextType).toBe(EntityContextType.TABLE);
expect(entities[1].belongStmt.isContainCaret).toBeTruthy();
});

test('isContainCaret should be truthy if caret position is whitespace at the end of statement', () => {
const pos: CaretPosition = {
lineNumber: 13,
column: 25,
};
const sql = commentOtherLine(syntaxSql, pos.lineNumber);
const entities = flink.getAllEntities(sql, pos);
expect(entities[0].belongStmt.isContainCaret).toBeTruthy();
});

test('isContainCaret should be falsy if caret position is whitespace after semicolon', () => {
const pos: CaretPosition = {
lineNumber: 15,
column: 32,
};
const sql = commentOtherLine(syntaxSql, pos.lineNumber);
const entities = flink.getAllEntities(sql, pos);
expect(entities[0].belongStmt.isContainCaret).toBeFalsy();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,8 @@ INSERT INTO insert_tb PARTITION (country, state) SELECT col1, col2, country, sta

CREATE TABLE IF NOT EXISTS derived_table AS SELECT FROM origin_table

CREATE TABLE IF NOT EXISTS derived_table AS SELECT id, FROM origin_table
CREATE TABLE IF NOT EXISTS derived_table AS SELECT id, FROM origin_table

SELECT id FROM tb WHERE

SELECT id FROM tb GROUP BY ;
36 changes: 28 additions & 8 deletions test/parser/hive/suggestion/suggestionWithEntity.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,12 @@ describe('Hive SQL Syntax Suggestion with collect entity', () => {
expect(entities.length).toBe(2);
expect(entities[0].text).toBe('a');
expect(entities[0].entityContextType).toBe(EntityContextType.TABLE);
expect(entities[0].belongStmt.isContainCaret).toBeFalsy();
expect(entities[0].belongStmt.isContainCaret).toBeTruthy();
expect(entities[0].belongStmt.rootStmt.isContainCaret).toBeTruthy();

expect(entities[1].text).toBe('b');
expect(entities[1].entityContextType).toBe(EntityContextType.TABLE);
expect(entities[1].belongStmt.isContainCaret).toBeFalsy();
expect(entities[1].belongStmt.isContainCaret).toBeTruthy();
expect(entities[1].belongStmt.rootStmt.isContainCaret).toBeTruthy();
});

Expand All @@ -145,12 +145,12 @@ describe('Hive SQL Syntax Suggestion with collect entity', () => {
expect(entities.length).toBe(2);
expect(entities[0].text).toBe('a');
expect(entities[0].entityContextType).toBe(EntityContextType.TABLE);
expect(entities[0].belongStmt.isContainCaret).toBeFalsy();
expect(entities[0].belongStmt.isContainCaret).toBeTruthy();
expect(entities[0].belongStmt.rootStmt.isContainCaret).toBeTruthy();

expect(entities[1].text).toBe('b');
expect(entities[1].entityContextType).toBe(EntityContextType.TABLE);
expect(entities[1].belongStmt.isContainCaret).toBeFalsy();
expect(entities[1].belongStmt.isContainCaret).toBeTruthy();
expect(entities[1].belongStmt.rootStmt.isContainCaret).toBeTruthy();
});

Expand All @@ -172,12 +172,12 @@ describe('Hive SQL Syntax Suggestion with collect entity', () => {
expect(entities.length).toBe(2);
expect(entities[0].text).toBe('page_view_stg');
expect(entities[0].entityContextType).toBe(EntityContextType.TABLE);
expect(entities[0].belongStmt.isContainCaret).toBeFalsy();
expect(entities[0].belongStmt.isContainCaret).toBeTruthy();
expect(entities[0].belongStmt.rootStmt.isContainCaret).toBeTruthy();

expect(entities[1].text).toBe('page_view');
expect(entities[1].entityContextType).toBe(EntityContextType.TABLE);
expect(entities[1].belongStmt.isContainCaret).toBeFalsy();
expect(entities[1].belongStmt.isContainCaret).toBeTruthy();
expect(entities[1].belongStmt.rootStmt.isContainCaret).toBeTruthy();
});

Expand All @@ -199,12 +199,12 @@ describe('Hive SQL Syntax Suggestion with collect entity', () => {
expect(entities.length).toBe(2);
expect(entities[0].text).toBe('page_view_stg');
expect(entities[0].entityContextType).toBe(EntityContextType.TABLE);
expect(entities[0].belongStmt.isContainCaret).toBeFalsy();
expect(entities[0].belongStmt.isContainCaret).toBeTruthy();
expect(entities[0].belongStmt.rootStmt.isContainCaret).toBeTruthy();

expect(entities[1].text).toBe('page_view');
expect(entities[1].entityContextType).toBe(EntityContextType.TABLE);
expect(entities[1].belongStmt.isContainCaret).toBeFalsy();
expect(entities[1].belongStmt.isContainCaret).toBeTruthy();
expect(entities[1].belongStmt.rootStmt.isContainCaret).toBeTruthy();
});

Expand Down Expand Up @@ -307,4 +307,24 @@ describe('Hive SQL Syntax Suggestion with collect entity', () => {
expect(entities[1].entityContextType).toBe(EntityContextType.TABLE);
expect(entities[1].belongStmt.isContainCaret).toBeTruthy();
});

test('isContainCaret should be truthy if caret position is whitespace at the end of statement', () => {
const pos: CaretPosition = {
lineNumber: 25,
column: 25,
};
const sql = commentOtherLine(syntaxSql, pos.lineNumber);
const entities = hive.getAllEntities(sql, pos);
expect(entities[0].belongStmt.isContainCaret).toBeTruthy();
});

test('isContainCaret should be falsy if caret position is whitespace after semicolon', () => {
const pos: CaretPosition = {
lineNumber: 27,
column: 32,
};
const sql = commentOtherLine(syntaxSql, pos.lineNumber);
const entities = hive.getAllEntities(sql, pos);
expect(entities[0].belongStmt.isContainCaret).toBeFalsy();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ INSERT INTO insert_tb SELECT id, FROM from_tb;
CREATE TABLE sorted_census_data AS SELECT FROM unsorted_census_data;

CREATE TABLE sorted_census_data AS SELECT id, FROM unsorted_census_data;

SELECT id FROM tb WHERE

SELECT id FROM tb GROUP BY ;
20 changes: 20 additions & 0 deletions test/parser/impala/suggestion/suggestionWithEntity.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,4 +155,24 @@ describe('Impala SQL Syntax Suggestion with collect entity', () => {
expect(entities[1].entityContextType).toBe(EntityContextType.TABLE);
expect(entities[1].belongStmt.isContainCaret).toBeTruthy();
});

test('isContainCaret should be truthy if caret position is whitespace at the end of statement', () => {
const pos: CaretPosition = {
lineNumber: 13,
column: 25,
};
const sql = commentOtherLine(syntaxSql, pos.lineNumber);
const entities = impala.getAllEntities(sql, pos);
expect(entities[0].belongStmt.isContainCaret).toBeTruthy();
});

test('isContainCaret should be falsy if caret position is whitespace after semicolon', () => {
const pos: CaretPosition = {
lineNumber: 15,
column: 32,
};
const sql = commentOtherLine(syntaxSql, pos.lineNumber);
const entities = impala.getAllEntities(sql, pos);
expect(entities[0].belongStmt.isContainCaret).toBeFalsy();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@ INSERT INTO insert_tb SELECT id, age, FROM from_tb;

CREATE TABLE sorted_census_data AS SELECT FROM unsorted_census_data;

CREATE TABLE sorted_census_data AS SELECT id, age, FROM unsorted_census_data;
CREATE TABLE sorted_census_data AS SELECT id, age, FROM unsorted_census_data;

SELECT id FROM tb WHERE

SELECT id FROM tb GROUP BY ;
20 changes: 20 additions & 0 deletions test/parser/mysql/suggestion/suggestionWithEntity.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,4 +153,24 @@ describe('MySQL Syntax Suggestion with collect entity', () => {
expect(entities[1].entityContextType).toBe(EntityContextType.TABLE);
expect(entities[1].belongStmt.isContainCaret).toBeTruthy();
});

test('isContainCaret should be truthy if caret position is whitespace at the end of statement', () => {
const pos: CaretPosition = {
lineNumber: 13,
column: 25,
};
const sql = commentOtherLine(syntaxSql, pos.lineNumber);
const entities = mysql.getAllEntities(sql, pos);
expect(entities[0].belongStmt.isContainCaret).toBeTruthy();
});

test('isContainCaret should be falsy if caret position is whitespace after semicolon', () => {
const pos: CaretPosition = {
lineNumber: 15,
column: 32,
};
const sql = commentOtherLine(syntaxSql, pos.lineNumber);
const entities = mysql.getAllEntities(sql, pos);
expect(entities[0].belongStmt.isContainCaret).toBeFalsy();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@ CREATE TABLE sorted_census_data AS SELECT FROM unsorted_census_data;

CREATE TABLE sorted_census_data AS SELECT id, age, FROM unsorted_census_data;

ALTER TABLE my_table DROP a_column;
ALTER TABLE my_table DROP a_column;

SELECT id FROM tb WHERE

SELECT id FROM tb GROUP BY ;
20 changes: 20 additions & 0 deletions test/parser/postgresql/suggestion/suggestionWithEntity.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,4 +174,24 @@ describe('PostgreSql Syntax Suggestion with collect entity', () => {
expect(entities[0].entityContextType).toBe(EntityContextType.TABLE);
expect(entities[0].belongStmt?.isContainCaret).toBeTruthy();
});

test('isContainCaret should be truthy if caret position is whitespace at the end of statement', () => {
const pos: CaretPosition = {
lineNumber: 15,
column: 25,
};
const sql = commentOtherLine(syntaxSql, pos.lineNumber);
const entities = postgre.getAllEntities(sql, pos);
expect(entities[0].belongStmt.isContainCaret).toBeTruthy();
});

test('isContainCaret should be falsy if caret position is whitespace after semicolon', () => {
const pos: CaretPosition = {
lineNumber: 17,
column: 32,
};
const sql = commentOtherLine(syntaxSql, pos.lineNumber);
const entities = postgre.getAllEntities(sql, pos);
expect(entities[0].belongStmt.isContainCaret).toBeFalsy();
});
});
Loading
Loading