Skip to content

Kijin-Seija/dt-sql-parser-semantic-analyse-plugin

Repository files navigation

dt-sql-parser-semantic-analyse-plugin

A dt-sql-parser plugin with semantic result. Theory(zh-CN).

Installation

npm install dt-sql-parser-semantic-analyse-plugin

Quick Usage

import { PostgreSQL } from 'dt-sql-parser'
import { PostgreSqlParser } from 'dt-sql-parser/dist/lib/postgresql/PostgreSqlParser'

const myPlugin = new DtSqlParserSemAnalysePlugin({
  parse: {
    sql: new PostgreSQL(),
    parser: PostgreSqlParser,
    alias: {
      selectstmt: 'selectStatement',
    },
    stmts: [
      'selectstmt',
    ],
    entities: [
      'target_el',
    ],
    rules: {
      select_target: [
        PostgreSqlParser.RULE_selectstmt,
        PostgreSqlParser.RULE_target_el,
      ]
    }
  }
})

const sql = 'SELECT a| FROM t'
const caretColumn = sql.indexOf('|') + 1
const result = myPlugin.parse(sql.replace('|', ''), { lineNumber: 1, columnNumber: caretColumn })
console.log(result)

This will use a postgresql Parser. You can get select_target text from parse result.

{
  // all wrapped Entities around your caret/cursor
  nearestCaretEntityList: [
    {
      // your definition of the rule that contains the entity.
      rule: 'select_target',
      // entity's text. __CARET_PLACEHOLDER__ is the placeholder of caret. You can replace it.
      text: 'a__CARET_PLACEHOLDER__',
      // entity's type code in PostgreSqlParser
      type: 694,
      // whether this entity contains caret.
      caret: true,
      // stmt which the entity belongs to. Equals to stmtList[0] in this example.
      belongsToStmt: {
        text: 'SELECTa__CARET_PLACEHOLDER__FROMt',
        type: 500,
        caret: true,
        relatedEntities: { ... }
      },
      // if this entity is a sub entity, this param will show its parent entity with the same struct. Currently in this example it's null.
      belongsToEntity: null
      // if this entity has sub entities, they will be collected in this param, with the same struct.
      relatedEntities: [...]
    }
  ],
  stmtList: [
    {
      // stmt's text. __CARET_PLACEHOLDER__ is the placeholder of caret. You can replace it.
      text: 'SELECTa__CARET_PLACEHOLDER__FROMt',
      // stmt's type code in PostgreSqlParser
      type: 500,
      // whether this stmt contains caret.
      caret: true,
      // those entities collected in this stmt. Divided by rules.
      relatedEntities: {
        // your definition of the rule.
        select_target: [
          {
            rule: 'select_target',
            text: 'a__CARET_PLACEHOLDER__',
            type: 694,
            caret: true,
            belongsToStmt: { ... },
            belongsToEntity: null
            relatedEntities: [...]
          }
        ]
      }
    }
  ]
}

Notice: A rule must start with a/an statement/entity and stop with an entity. You should add a node keywords(keyword is in your parser with format: RULE_[keyword]) into stmts/entities before using it.

Add a preprocessor

const myPlugin = new DtSqlParserSemAnalysePlugin({
  preprocessor: [
    (sql) => sql.toUpperCase(),
    ...
  ],
  parse: {
    ...
  }
})

Rule Chain Operator

You can set a negative number whose abs equals to a ruleIndex. That means exclude this rule.

Example:

select_target_alias: [
  PostgreSqlParser.RULE_target_el,
  -PostgreSqlParser.RULE_attr_name,
  PostgreSqlParser.RULE_collabel
]

🚧 I will later work on Operator.AND and Operator.OR.

Alias

Some node names in dt-sql-parser's code are different from their antlr4's definition. You should declare them in alias params.

Example:

const myPlugin = new DtSqlParserSemAnalysePlugin({
  parse: {
    ...
    alias: {
      selectstmt: 'selectStatement',
      target_el: 'target_label',
      table_name: 'tableName',
      ...
    }
    ...
  }
})

You can find possible alias in https://github.com/DTStack/dt-sql-parser/blob/main/src/grammar/postgresql/PostgreSqlParser.g4, then add it into alias option.

alt text

Customize dt-sql-parser

If you want to use your custom dt-sql-parser, with external grammar(such as DISTRIBUTED, etc.), follow steps below:

  1. fork dt-sql-parser.
  2. change its ANTLR4 file as whatever you want.
  3. build and publish your dt-sql-parser npm package(npm run antlr4 && npm publish). Suppose to be my-dt-sql-parser.
  4. use my-dt-sql-parser instead of dt-sql-parser to provide parse.sql and parse.parser.

Example:

import { PostgreSQL } from 'my-dt-sql-parser'
import { PostgreSqlParser } from 'my-dt-sql-parser/dist/lib/postgresql/PostgreSqlParser'
const myPlugin = new DtSqlParserSemAnalysePlugin({
  parse: {
    sql: new PostgreSQL(),
    parser: PostgreSqlParser,
    ...
  }
})

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published