diff --git a/package.json b/package.json index a131854..d5e78f3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dt-sql-parser-semantic-analyse-plugin", - "version": "0.0.1-alpha.4", + "version": "0.0.1-alpha.5", "description": "an dt-sql-parser plugin with semantic result", "type": "module", "files": [ diff --git a/src/parse/default-rules.ts b/src/parse/default-rules.ts index f130de3..9771302 100644 --- a/src/parse/default-rules.ts +++ b/src/parse/default-rules.ts @@ -1,6 +1,7 @@ import { PostgreSQLParser } from 'dt-sql-parser/dist/lib/pgsql/PostgreSQLParser' export const defaultStmts = [ + 'stmt', // select statement 'selectstmt' ] @@ -21,6 +22,16 @@ export const defaultEntities = [ ] export const defaultRules: Record = { + // 通用的简单column规则(不带.运算符的column) + common_column_simple: [ + PostgreSQLParser.RULE_stmt, + PostgreSQLParser.RULE_column_name + ], + // 通用的复合column规则(带.运算符的column) + common_column_ref: [ + PostgreSQLParser.RULE_stmt, + PostgreSQLParser.RULE_columnref + ], select_target_column_simple: [ PostgreSQLParser.RULE_selectstmt, PostgreSQLParser.RULE_select_clause, diff --git a/src/parse/visitor.ts b/src/parse/visitor.ts index dcedbec..e5f08e7 100644 --- a/src/parse/visitor.ts +++ b/src/parse/visitor.ts @@ -58,26 +58,31 @@ export class SQLVisitor extends AbstractParseTreeVisitor implements Postgr (this as any)[visitorName] = (ctx: ParserRuleContext) => { const chain = this.getNodeChain(ctx) for (const rule of rules) { - if (this.matchRules(chain, this.rules.get(rule))) { + const ruleChain = this.rules.get(rule) + if (!ruleChain) continue + if (this.matchRules(chain, ruleChain)) { + const ruleChainBegin = ruleChain[0] + const beginStmt = this.stmtStack.find(stmt => stmt.type === ruleChainBegin) + const beginEntity = this.entityStack.find(entity => entity.type === ruleChainBegin) const result: Entity = { rule, text: ctx.text, type: ctx.ruleIndex, caret: withCaret(ctx), - belongsToStmt: this.stmtStack[this.stmtStack.length - 1], + belongsToStmt: beginStmt || null, + belongsToEntity: beginEntity || null, relatedEntities: {} } - if (this.entityStack[this.entityStack.length - 1]) { - if (!this.entityStack[this.entityStack.length - 1].relatedEntities[rule]) this.entityStack[this.entityStack.length - 1].relatedEntities[rule] = [] - this.entityStack[this.entityStack.length - 1].relatedEntities[rule].push(result) - } else { - if (!this.stmtStack[this.stmtStack.length - 1].relatedEntities[rule]) this.stmtStack[this.stmtStack.length - 1].relatedEntities[rule] = [] - this.stmtStack[this.stmtStack.length - 1].relatedEntities[rule].push(result) + if (beginEntity) { + if (!beginEntity.relatedEntities[rule]) beginEntity.relatedEntities[rule] = [] + beginEntity.relatedEntities[rule].push(result) + } else if (beginStmt) { + if (!beginStmt.relatedEntities[rule]) beginStmt.relatedEntities[rule] = [] + beginStmt.relatedEntities[rule].push(result) } if (withCaret(ctx)) this.result.nerestCaretEntityList.push(result) this.entityStack.push(result) isHitRule = true - break } } this.visitChildren(ctx) diff --git a/src/types.ts b/src/types.ts index 66f67f4..5d10762 100644 --- a/src/types.ts +++ b/src/types.ts @@ -52,7 +52,8 @@ export interface Entity { text: string type: number caret: boolean - belongsToStmt: Stmt + belongsToStmt: Stmt | null + belongsToEntity: Entity | null relatedEntities: Record }