0.0.1-alpha.6:
1. 修改 `package.json` 中的项目名称和版本号。 2. 更新 `node_modules` 中的依赖包版本。 3. 修改 `src/index.ts` 中的 SQL 语句和 `caretColumn` 的计算方式。 4. 修改 `src/parse/default-rules.ts` 中的规则和导入语句。 5. 修改 `src/parse/visitor.ts` 中的访问者和规则。 6. 修改 `src/preprocess/default-preprocessor.ts` 中的预处理逻辑。 7. 修改 `src/types.ts` 中的导入语句。
This commit is contained in:
		@ -12,7 +12,7 @@
 | 
			
		||||
    <script type="module">
 | 
			
		||||
      const { DtSqlParserSemAnalysePlugin } = await import(/* @vite-ignore */import.meta.env.VITE_ENTRY_PATH)
 | 
			
		||||
      const myPlugin = new DtSqlParserSemAnalysePlugin()
 | 
			
		||||
      const sql = 'SELECT a.b| FROM t'
 | 
			
		||||
      const sql = 'SELECT a.| AS c'
 | 
			
		||||
      const caretColumn = sql.indexOf('|') + 1
 | 
			
		||||
      const result = myPlugin.parse(sql.replace('|', ''), { lineNumber: 1, columnNumber: caretColumn })
 | 
			
		||||
      console.log(result)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										45
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										45
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@ -1,12 +1,14 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "dt-sql-parser-analyse-demo",
 | 
			
		||||
  "name": "dt-sql-parser-semantic-analyse-plugin",
 | 
			
		||||
  "version": "0.0.1-alpha.7",
 | 
			
		||||
  "lockfileVersion": 3,
 | 
			
		||||
  "requires": true,
 | 
			
		||||
  "packages": {
 | 
			
		||||
    "": {
 | 
			
		||||
      "name": "dt-sql-parser-analyse-demo",
 | 
			
		||||
      "name": "dt-sql-parser-semantic-analyse-plugin",
 | 
			
		||||
      "version": "0.0.1-alpha.6",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "dt-sql-parser": "^4.0.0-beta.4.11"
 | 
			
		||||
        "dt-sql-parser": "^4.0.0-beta.4.12"
 | 
			
		||||
      },
 | 
			
		||||
      "devDependencies": {
 | 
			
		||||
        "@eslint/eslintrc": "^3.0.2",
 | 
			
		||||
@ -1099,17 +1101,29 @@
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/antlr4-c3": {
 | 
			
		||||
      "version": "3.1.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/antlr4-c3/-/antlr4-c3-3.1.1.tgz",
 | 
			
		||||
      "integrity": "sha512-S7DixV12kxWexTkQYGvooCgHYU5AjF74oYio+ZNgm0XN3EzxDY3J6Si9GprQ4KksvgWwK//EgZnL/26WB+bOpw==",
 | 
			
		||||
      "version": "3.3.7",
 | 
			
		||||
      "resolved": "http://npm.oushu.com:14837/antlr4-c3/-/antlr4-c3-3.3.7.tgz",
 | 
			
		||||
      "integrity": "sha512-F3ndE38wwA6z6AjUbL3heSdEGl4TxulGDPf9xB0/IY4dbRHWBh6XNaqFwur8vHKQk9FS5yNABHeg2wqlqIYO0w==",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "antlr4ts": "0.5.0-alpha.4"
 | 
			
		||||
        "antlr4ng": "2.0.11"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/antlr4ts": {
 | 
			
		||||
      "version": "0.5.0-alpha.4",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz",
 | 
			
		||||
      "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ=="
 | 
			
		||||
    "node_modules/antlr4ng": {
 | 
			
		||||
      "version": "2.0.11",
 | 
			
		||||
      "resolved": "http://npm.oushu.com:14837/antlr4ng/-/antlr4ng-2.0.11.tgz",
 | 
			
		||||
      "integrity": "sha512-9jM91VVtHSqHkAHQsXHaoaiewFETMvUTI1/tXvwTiFw4f7zke3IGlwEyoKN9NS0FqIwDKFvUNW2e1cKPniTkVQ==",
 | 
			
		||||
      "peerDependencies": {
 | 
			
		||||
        "antlr4ng-cli": "1.0.7"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/antlr4ng-cli": {
 | 
			
		||||
      "version": "1.0.7",
 | 
			
		||||
      "resolved": "http://npm.oushu.com:14837/antlr4ng-cli/-/antlr4ng-cli-1.0.7.tgz",
 | 
			
		||||
      "integrity": "sha512-qN2FsDBmLvsQcA5CWTrPz8I8gNXeS1fgXBBhI78VyxBSBV/EJgqy8ks6IDTC9jyugpl40csCQ4sL5K4i2YZ/2w==",
 | 
			
		||||
      "peer": true,
 | 
			
		||||
      "bin": {
 | 
			
		||||
        "antlr4ng": "index.js"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/argparse": {
 | 
			
		||||
      "version": "2.0.1",
 | 
			
		||||
@ -1890,11 +1904,12 @@
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/dt-sql-parser": {
 | 
			
		||||
      "version": "4.0.0-beta.4.11",
 | 
			
		||||
      "integrity": "sha512-bgMJAMImikNwE0OPZApI+R+PjpI8xoJAksQIUJdtS4+piZII1LHzbmlp8T7iRJ4Fo56EwY5ILmv9VcZ/PwKV1A==",
 | 
			
		||||
      "version": "4.0.0-beta.4.12",
 | 
			
		||||
      "resolved": "http://npm.oushu.com:14837/dt-sql-parser/-/dt-sql-parser-4.0.0-beta.4.12.tgz",
 | 
			
		||||
      "integrity": "sha512-kfLRecn+dfdZjrKt3Ovm52ryoh9UGF+dCjNzV2pk8XI5kgF7lgQJhPZdRi+2yn1AU/BWQ1/0E6LnvFYbZ7Wr9Q==",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "antlr4-c3": "3.1.1",
 | 
			
		||||
        "antlr4ts": "0.5.0-alpha.4"
 | 
			
		||||
        "antlr4-c3": "3.3.7",
 | 
			
		||||
        "antlr4ng": "2.0.11"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/elliptic": {
 | 
			
		||||
 | 
			
		||||
@ -37,6 +37,6 @@
 | 
			
		||||
    "vite-plugin-node-polyfills": "^0.21.0"
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "dt-sql-parser": "^4.0.0-beta.4.11"
 | 
			
		||||
    "dt-sql-parser": "^4.0.0-beta.4.12"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,10 @@
 | 
			
		||||
import { defaultEntities, defaultRules, defaultStmts } from './parse/default-rules'
 | 
			
		||||
import { defaultAlias, defaultEntities, defaultRules, defaultStmts } from './parse/default-rules'
 | 
			
		||||
import { parse } from './parse'
 | 
			
		||||
import { preprocess } from './preprocess'
 | 
			
		||||
import { type PluginSettings, type InsertCaretPlaceholderConfig } from './types'
 | 
			
		||||
import { defaultPreprocessorList } from './preprocess/default-preprocessor'
 | 
			
		||||
import { insertCaret } from './caret'
 | 
			
		||||
import { PostgresSQL } from 'dt-sql-parser'
 | 
			
		||||
import { PostgreSQL } from 'dt-sql-parser'
 | 
			
		||||
 | 
			
		||||
export class DtSqlParserSemAnalysePlugin {
 | 
			
		||||
  private readonly settings: PluginSettings = {}
 | 
			
		||||
@ -18,10 +18,11 @@ export class DtSqlParserSemAnalysePlugin {
 | 
			
		||||
    const sqlAfterPreprocess = preprocess(sqlAfterInsertCaret, this.settings.preprocessor || defaultPreprocessorList)
 | 
			
		||||
    const sqlParseResult = parse(
 | 
			
		||||
      sqlAfterPreprocess,
 | 
			
		||||
      this.settings.parse?.parser || new PostgresSQL(),
 | 
			
		||||
      this.settings.parse?.parser || new PostgreSQL(),
 | 
			
		||||
      this.settings.parse?.stmts || defaultStmts,
 | 
			
		||||
      this.settings.parse?.entities || defaultEntities,
 | 
			
		||||
      this.settings.parse?.rules || defaultRules
 | 
			
		||||
      this.settings.parse?.rules || defaultRules,
 | 
			
		||||
      this.settings.parse?.alias || defaultAlias
 | 
			
		||||
    )
 | 
			
		||||
    return sqlParseResult
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -1,89 +1,39 @@
 | 
			
		||||
import { PostgreSQLParser } from 'dt-sql-parser/dist/lib/pgsql/PostgreSQLParser'
 | 
			
		||||
import { PostgreSqlParser } from 'dt-sql-parser/dist/lib/postgresql/PostgreSqlParser'
 | 
			
		||||
 | 
			
		||||
export const defaultAlias = {
 | 
			
		||||
  selectstmt: 'selectStatement',
 | 
			
		||||
  target_el: 'target_label'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const defaultStmts = [
 | 
			
		||||
  'stmt',
 | 
			
		||||
  // select statement
 | 
			
		||||
  'selectstmt'
 | 
			
		||||
  'simple_select',
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
export const defaultEntities = [
 | 
			
		||||
  // column_name directly. ex: select column1
 | 
			
		||||
  'column_name',
 | 
			
		||||
  // column_name indirectly. ex: select schema.column1
 | 
			
		||||
  'columnref',
 | 
			
		||||
  'table_name',
 | 
			
		||||
  'view_name',
 | 
			
		||||
  'function_name',
 | 
			
		||||
  'schema_name',
 | 
			
		||||
  'target_el',
 | 
			
		||||
  'colid',
 | 
			
		||||
  'attr_name',
 | 
			
		||||
  'collabel',
 | 
			
		||||
  'func_arg_expr'
 | 
			
		||||
  'collabel'
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
export const defaultRules: Record<string, number[]> = {
 | 
			
		||||
  // 通用的简单column规则(不带.运算符的column)
 | 
			
		||||
  common_column_simple: [
 | 
			
		||||
    PostgreSQLParser.RULE_stmt,
 | 
			
		||||
    PostgreSQLParser.RULE_column_name
 | 
			
		||||
  select_target: [
 | 
			
		||||
    PostgreSqlParser.RULE_simple_select,
 | 
			
		||||
    PostgreSqlParser.RULE_target_el,
 | 
			
		||||
  ],
 | 
			
		||||
  // 通用的复合column规则(带.运算符的column)
 | 
			
		||||
  common_column_ref: [
 | 
			
		||||
    PostgreSQLParser.RULE_stmt,
 | 
			
		||||
    PostgreSQLParser.RULE_columnref
 | 
			
		||||
  select_target_colid: [
 | 
			
		||||
    PostgreSqlParser.RULE_target_el,
 | 
			
		||||
    PostgreSqlParser.RULE_function_name,
 | 
			
		||||
    PostgreSqlParser.RULE_colid
 | 
			
		||||
  ],
 | 
			
		||||
  select_target_column_simple: [
 | 
			
		||||
    PostgreSQLParser.RULE_selectstmt,
 | 
			
		||||
    PostgreSQLParser.RULE_select_clause,
 | 
			
		||||
    PostgreSQLParser.RULE_target_list,
 | 
			
		||||
    PostgreSQLParser.RULE_column_name
 | 
			
		||||
  select_target_attr: [
 | 
			
		||||
    PostgreSqlParser.RULE_target_el,
 | 
			
		||||
    PostgreSqlParser.RULE_function_name,
 | 
			
		||||
    PostgreSqlParser.RULE_attr_name
 | 
			
		||||
  ],
 | 
			
		||||
  select_target_column_ref: [
 | 
			
		||||
    PostgreSQLParser.RULE_selectstmt,
 | 
			
		||||
    PostgreSQLParser.RULE_select_clause,
 | 
			
		||||
    PostgreSQLParser.RULE_target_list,
 | 
			
		||||
    PostgreSQLParser.RULE_columnref
 | 
			
		||||
  ],
 | 
			
		||||
  select_target_function: [
 | 
			
		||||
    PostgreSQLParser.RULE_selectstmt,
 | 
			
		||||
    PostgreSQLParser.RULE_select_clause,
 | 
			
		||||
    PostgreSQLParser.RULE_target_list,
 | 
			
		||||
    PostgreSQLParser.RULE_function_name
 | 
			
		||||
  ],
 | 
			
		||||
  select_column_alias: [
 | 
			
		||||
    PostgreSQLParser.RULE_selectstmt,
 | 
			
		||||
    PostgreSQLParser.RULE_select_clause,
 | 
			
		||||
    PostgreSQLParser.RULE_target_list,
 | 
			
		||||
    PostgreSQLParser.RULE_collabel
 | 
			
		||||
  ],
 | 
			
		||||
  select_from_table: [
 | 
			
		||||
    PostgreSQLParser.RULE_selectstmt,
 | 
			
		||||
    PostgreSQLParser.RULE_select_clause,
 | 
			
		||||
    PostgreSQLParser.RULE_from_clause,
 | 
			
		||||
    PostgreSQLParser.RULE_table_name
 | 
			
		||||
  ],
 | 
			
		||||
  select_from_view: [
 | 
			
		||||
    PostgreSQLParser.RULE_selectstmt,
 | 
			
		||||
    PostgreSQLParser.RULE_select_clause,
 | 
			
		||||
    PostgreSQLParser.RULE_from_clause,
 | 
			
		||||
    PostgreSQLParser.RULE_view_name
 | 
			
		||||
  ],
 | 
			
		||||
  select_from_function: [
 | 
			
		||||
    PostgreSQLParser.RULE_selectstmt,
 | 
			
		||||
    PostgreSQLParser.RULE_select_clause,
 | 
			
		||||
    PostgreSQLParser.RULE_from_clause,
 | 
			
		||||
    PostgreSQLParser.RULE_function_name
 | 
			
		||||
  ],
 | 
			
		||||
  column_ref_colid: [
 | 
			
		||||
    PostgreSQLParser.RULE_columnref,
 | 
			
		||||
    PostgreSQLParser.RULE_colid
 | 
			
		||||
  ],
 | 
			
		||||
  column_ref_attr: [
 | 
			
		||||
    PostgreSQLParser.RULE_columnref,
 | 
			
		||||
    PostgreSQLParser.RULE_attr_name
 | 
			
		||||
  ],
 | 
			
		||||
  function_arg_expr: [
 | 
			
		||||
    PostgreSQLParser.RULE_function_name,
 | 
			
		||||
    PostgreSQLParser.RULE_func_arg_expr
 | 
			
		||||
  select_target_alias: [
 | 
			
		||||
    PostgreSqlParser.RULE_target_el,
 | 
			
		||||
    -PostgreSqlParser.RULE_attr_name,
 | 
			
		||||
    PostgreSqlParser.RULE_collabel
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,18 +1,20 @@
 | 
			
		||||
import { PostgresSQL } from 'dt-sql-parser'
 | 
			
		||||
import { PostgreSQL } from 'dt-sql-parser'
 | 
			
		||||
import { SQLVisitor } from './visitor'
 | 
			
		||||
import { type SQLParseResult } from '../types'
 | 
			
		||||
import type BasicParser from 'dt-sql-parser/dist/parser/common/basicParser'
 | 
			
		||||
import { type BasicSQL } from 'dt-sql-parser/dist/parser/common/basicSQL'
 | 
			
		||||
 | 
			
		||||
export function parse (
 | 
			
		||||
  sql: string,
 | 
			
		||||
  parser: BasicParser = new PostgresSQL(),
 | 
			
		||||
  parser: BasicSQL = new PostgreSQL(),
 | 
			
		||||
  stmts: string[] = [],
 | 
			
		||||
  entities: string[] = [],
 | 
			
		||||
  rules: Record<string, number[]> = {}
 | 
			
		||||
  rules: Record<string, number[]> = {},
 | 
			
		||||
  alias: Record<string, string> = {},
 | 
			
		||||
): SQLParseResult {
 | 
			
		||||
  const tree = parser.parse(sql)
 | 
			
		||||
  console.log('tree', tree)
 | 
			
		||||
  const visitor = new SQLVisitor()
 | 
			
		||||
  visitor.visitorAlias = alias
 | 
			
		||||
  stmts.forEach(stmt => { visitor.addStmt(stmt) })
 | 
			
		||||
  entities.forEach(entity => { visitor.addEntity(entity) })
 | 
			
		||||
  Object.keys(rules).forEach(name => { visitor.addRules(name, rules[name]) })
 | 
			
		||||
 | 
			
		||||
@ -1,21 +1,24 @@
 | 
			
		||||
import { type ParserRuleContext } from 'antlr4ts'
 | 
			
		||||
import { AbstractParseTreeVisitor, type PostgreSQLParserVisitor } from 'dt-sql-parser'
 | 
			
		||||
import { type ProgramContext, PostgreSQLParser } from 'dt-sql-parser/dist/lib/pgsql/PostgreSQLParser'
 | 
			
		||||
import { AbstractParseTreeVisitor, type RuleContext } from 'antlr4ng'
 | 
			
		||||
import { type PostgreSqlParserVisitor } from 'dt-sql-parser'
 | 
			
		||||
import { type ProgramContext, PostgreSqlParser } from 'dt-sql-parser/dist/lib/postgresql/PostgreSqlParser'
 | 
			
		||||
import { type Entity, type SQLParseResult, type Stmt } from '../types'
 | 
			
		||||
import { caretPlaceholder } from '../caret'
 | 
			
		||||
 | 
			
		||||
function withCaret (ctx: ParserRuleContext) {
 | 
			
		||||
  return ctx.text.includes(caretPlaceholder)
 | 
			
		||||
function toVisitorAlias (node: string, alias: Record<string, string>) {
 | 
			
		||||
  const result = alias[node] || node
 | 
			
		||||
  return `visit${result.slice(0, 1).toUpperCase()}${result.slice(1)}`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class SQLVisitor extends AbstractParseTreeVisitor<void> implements PostgreSQLParserVisitor<void> {
 | 
			
		||||
function withCaret (ctx: RuleContext) {
 | 
			
		||||
  return ctx.getText().includes(caretPlaceholder)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class SQLVisitor extends AbstractParseTreeVisitor<void> implements PostgreSqlParserVisitor<void> {
 | 
			
		||||
  private result: SQLParseResult = {
 | 
			
		||||
    stmtList: [],
 | 
			
		||||
    nerestCaretEntityList: []
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected defaultResult = () => ({ list: [], nerestCaret: null })
 | 
			
		||||
 | 
			
		||||
  public clear () {
 | 
			
		||||
    this.result = { stmtList: [], nerestCaretEntityList: [] }
 | 
			
		||||
  }
 | 
			
		||||
@ -24,6 +27,8 @@ export class SQLVisitor extends AbstractParseTreeVisitor<void> implements Postgr
 | 
			
		||||
    return this.result
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public visitorAlias = {}
 | 
			
		||||
 | 
			
		||||
  private readonly stmtStack: Stmt[] = []
 | 
			
		||||
 | 
			
		||||
  private readonly entityStack: Entity[] = []
 | 
			
		||||
@ -50,12 +55,12 @@ export class SQLVisitor extends AbstractParseTreeVisitor<void> implements Postgr
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public addEntity (name: string) {
 | 
			
		||||
    this.entityRules.set((PostgreSQLParser as any)[`RULE_${name}`], [])
 | 
			
		||||
    this.entityRules.set((PostgreSqlParser as any)[`RULE_${name}`], [])
 | 
			
		||||
    let isHitRule = false
 | 
			
		||||
    const visitorName = `visit${name.slice(0, 1).toUpperCase()}${name.slice(1)}`
 | 
			
		||||
    const visitorName = toVisitorAlias(name, this.visitorAlias)
 | 
			
		||||
    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
 | 
			
		||||
    const rules = this.entityRules.get((PostgreSQLParser as any)[`RULE_${name}`])!;
 | 
			
		||||
    (this as any)[visitorName] = (ctx: ParserRuleContext) => {
 | 
			
		||||
    const rules = this.entityRules.get((PostgreSqlParser as any)[`RULE_${name}`])!;
 | 
			
		||||
    (this as any)[visitorName] = (ctx: RuleContext) => {
 | 
			
		||||
      const chain = this.getNodeChain(ctx)
 | 
			
		||||
      for (const rule of rules) {
 | 
			
		||||
        const ruleChain = this.rules.get(rule)
 | 
			
		||||
@ -66,7 +71,7 @@ export class SQLVisitor extends AbstractParseTreeVisitor<void> implements Postgr
 | 
			
		||||
          const beginEntity = this.entityStack.find(entity => entity.type === ruleChainBegin)
 | 
			
		||||
          const result: Entity = {
 | 
			
		||||
            rule,
 | 
			
		||||
            text: ctx.text,
 | 
			
		||||
            text: ctx.getText(),
 | 
			
		||||
            type: ctx.ruleIndex,
 | 
			
		||||
            caret: withCaret(ctx),
 | 
			
		||||
            belongsToStmt: beginStmt || null,
 | 
			
		||||
@ -91,11 +96,11 @@ export class SQLVisitor extends AbstractParseTreeVisitor<void> implements Postgr
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public addStmt (name: string) {
 | 
			
		||||
    this.stmtRules.set((PostgreSQLParser as any)[`RULE_${name}`], [])
 | 
			
		||||
    const visitorName = `visit${name.slice(0, 1).toUpperCase()}${name.slice(1)}`;
 | 
			
		||||
    (this as any)[visitorName] = (ctx: ParserRuleContext) => {
 | 
			
		||||
    this.stmtRules.set((PostgreSqlParser as any)[`RULE_${name}`], [])
 | 
			
		||||
    const visitorName = toVisitorAlias(name, this.visitorAlias);
 | 
			
		||||
    (this as any)[visitorName] = (ctx: RuleContext) => {
 | 
			
		||||
      this.stmtStack.push({
 | 
			
		||||
        text: ctx.text,
 | 
			
		||||
        text: ctx.getText(),
 | 
			
		||||
        type: ctx.ruleIndex,
 | 
			
		||||
        caret: withCaret(ctx),
 | 
			
		||||
        relatedEntities: {}
 | 
			
		||||
@ -106,8 +111,8 @@ export class SQLVisitor extends AbstractParseTreeVisitor<void> implements Postgr
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private getNodeChain (ctx: ParserRuleContext) {
 | 
			
		||||
    let _ctx: ParserRuleContext | undefined = ctx
 | 
			
		||||
  private getNodeChain (ctx: RuleContext) {
 | 
			
		||||
    let _ctx: RuleContext | null = ctx
 | 
			
		||||
    const result = []
 | 
			
		||||
    while (_ctx) {
 | 
			
		||||
      result.unshift(_ctx.ruleIndex)
 | 
			
		||||
@ -118,10 +123,13 @@ export class SQLVisitor extends AbstractParseTreeVisitor<void> implements Postgr
 | 
			
		||||
 | 
			
		||||
  private matchRules (chain: number[], ruleChain: number[] | undefined) {
 | 
			
		||||
    // 只要ruleChain里面每个元素都出现在chain里面,且顺序一致,则返回true。否则返回false
 | 
			
		||||
    // 当元素value为负数时,表示NOT,即不出现id为-value的规则。
 | 
			
		||||
    if (!ruleChain) return false
 | 
			
		||||
    let index = 0
 | 
			
		||||
    for (let i = 0; i < ruleChain.length; i++) {
 | 
			
		||||
      if (chain.indexOf(ruleChain[i]) < index) return false
 | 
			
		||||
      if (ruleChain[i] < 0) {
 | 
			
		||||
        if (chain.indexOf(-ruleChain[i]) >= index) return false
 | 
			
		||||
      } else if (chain.indexOf(ruleChain[i]) < index) return false
 | 
			
		||||
      else index = chain.indexOf(ruleChain[i])
 | 
			
		||||
    }
 | 
			
		||||
    return true
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,14 @@
 | 
			
		||||
import { type Preprocessor } from '../types'
 | 
			
		||||
 | 
			
		||||
export const addSuffixForParseSelectProcessor: Preprocessor = (sql: string) => {
 | 
			
		||||
  const suffix = ' '
 | 
			
		||||
  const maxWords = 3
 | 
			
		||||
  if (/select( )+/.test(sql.toLowerCase()) && sql.split(' ').filter(item => item).length < maxWords) {
 | 
			
		||||
    return sql + '' + suffix
 | 
			
		||||
  }
 | 
			
		||||
  return sql
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const addSuffixForParseAlterFunctionProcessor: Preprocessor = (sql: string) => {
 | 
			
		||||
  const suffix = 'RESET ALL'
 | 
			
		||||
  const maxWords = 4
 | 
			
		||||
@ -20,5 +29,6 @@ export const addSuffixForParseAlterTableProcessor: Preprocessor = (sql: string)
 | 
			
		||||
 | 
			
		||||
export const defaultPreprocessorList = [
 | 
			
		||||
  addSuffixForParseAlterFunctionProcessor,
 | 
			
		||||
  addSuffixForParseAlterTableProcessor
 | 
			
		||||
  addSuffixForParseAlterTableProcessor,
 | 
			
		||||
  addSuffixForParseSelectProcessor
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
import type BasicParser from 'dt-sql-parser/dist/parser/common/basicParser'
 | 
			
		||||
import { type BasicSQL } from 'dt-sql-parser/dist/parser/common/basicSQL'
 | 
			
		||||
 | 
			
		||||
export interface InsertCaretPlaceholderConfig {
 | 
			
		||||
  lineNumber: number
 | 
			
		||||
@ -24,10 +24,11 @@ export interface PluginSettings {
 | 
			
		||||
   * 自定义解析逻辑
 | 
			
		||||
   */
 | 
			
		||||
  parse?: {
 | 
			
		||||
    parser?: BasicParser
 | 
			
		||||
    parser?: BasicSQL
 | 
			
		||||
    stmts?: string[]
 | 
			
		||||
    entities?: string[]
 | 
			
		||||
    rules?: Record<string, number[]>
 | 
			
		||||
    alias?: Record<string, string>
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user