Calcite SQL解析

代码目录

如图:

bad5ec0a4a53b4ad3994108cee12fbf8.pngjava

config.fmpp

calcite 模板配置mysql

Parser.jj

JavaCC解析器git

parserImpls.ftl/compoundIdentifier.ftl

自定义JavaCC语法格式的解析SQL代码github

生成解析器的流程

如图:

ee37f4fc45b89ba57f895ba599898b6f.pngweb

Sql解析使用

解析示例代码

public class SqlParserSample {

public static void main(String[] args) throws SqlParseException {

// Sql语句

String sql = "select * from emps where id = 1";

// 解析配置

SqlParser.Config mysqlConfig = SqlParser.configBuilder().setLex(Lex.MYSQL).build();

// 建立解析器

SqlParser parser = SqlParser.create(sql, mysqlConfig);

// 解析sql

SqlNode sqlNode = parser.parseQuery();

// 还原某个方言的SQL

System.out.println(sqlNode.toSqlString(OracleSqlDialect.DEFAULT));

}

}

解析流程

首先生成SQL解析器SqlParser.Config,SqlParser.Config中存在获取解析工厂类SqlParser.Config#parserFactory()方法,能够在SqlParser.configBuilder()配置类中设置解析工厂

SqlParserImplFactory解析工厂中调用getParser方法获取解析器

SqlAbstractParserImpl抽象解析器,JavaCC中生成的解析器的父类,Calcite中默认的解析类名为SqlParserImpl

SqlParserImpl中,有静态字段FACTORY,主要是实现SqlParserImplFactory,并建立解析器

SqlParser调用create方法,从SqlParser.Config中获取工厂SqlParserImplFactory,并建立解析器

调用SqlParser#parseQuery方法,解析SQL,最终调用SqlAbstractParserImpl(默认实现类SqlParserImpl)的parseSqlStmtEof或者parseSqlExpressionEof方法,获取解析后的抽象语法树SqlNode

Parser.jj 解析简单介绍sql

调用SqlParserImplFactory的SqlAbstractParserImpl getParser(Reader stream);方法,解析获取解器,

或者,直接调用SqlParser#parseQuery传入sql语句,解析器从新传入sqlparser.ReInit(new StringReader(sql));

解析器入口类SqlAbstractParserImpl#parseSqlExpressionEof或者SqlAbstractParserImpl#parseSqlStmtEof

Parser.jj解析SQL语句入口SqlStmtEof() 解析SQL语句,直到文件结束符,SqlStmtEof()调用SqlStmt()

SqlStmt()中定义各个类型的解析,例如 SqlExplain()(explain语句),OrderedQueryOrExpr()(select语句),以后解析各个关键字

经常使用类

Span

Span

SqlParserPos的建造者

具体使用还不太清楚apache

SqlAbstractParserImpl

SqlAbstractParserImpl

抽象解析器,Calcite全部的解析的父类,主要是设置一些解析的配置信息api

SqlParseException

SqlParser

SqlParserImplFactory

SqlParserPos

SqlParserPos

表示SQL语句文本中已解析标记的位置

SqlParserUtil

SqlNode

SQL解析树,是全部解析的节点的父类

SqlNode

SqlCall

SqlCall是对操做符的调用.

操做符能够用来描述任何语法结构,所以在实践中,SQL解析树中的每一个非叶节点都是某种类型的SqlCall

经常使用类子类

// update语句

SqlUpdate (org.apache.calcite.sql)

// insert语句

SqlInsert (org.apache.calcite.sql)

// case语句

SqlCase (org.apache.calcite.sql.fun)

// explain语句

SqlExplain (org.apache.calcite.sql)

// delete语句

SqlDelete (org.apache.calcite.sql)

// with 列语句,mysql不支持,oracle支持

SqlWithItem (org.apache.calcite.sql)

// merge语法,mysql不支持,oracle支持

SqlMerge (org.apache.calcite.sql)

// ddl语句中的check语句

SqlCheckConstraint (org.apache.calcite.sql.ddl)

// 保存全部的操做

SqlBasicCall (org.apache.calcite.sql)

// 模式匹配

SqlMatchRecognize (org.apache.calcite.sql)

// alter语句

SqlAlter (org.apache.calcite.sql)

// UNIQUE,PRIMARY KEY,FOREIGN KEY解析

SqlKeyConstraint (org.apache.calcite.sql.ddl)

// with语句

SqlWith (org.apache.calcite.sql)

// order by 语句

SqlOrderBy (org.apache.calcite.sql)

// DESCRIBE SCHEMA 语句

SqlDescribeSchema (org.apache.calcite.sql)

// ddl语句

SqlDdl (org.apache.calcite.sql)

// join语句

SqlJoin (org.apache.calcite.sql)

// window语句

SqlWindow (org.apache.calcite.sql)

// select语句

SqlSelect (org.apache.calcite.sql)

//

SqlAttributeDefinition (org.apache.calcite.sql.ddl)

// DESCRIBE TABLE 语句

SqlDescribeTable (org.apache.calcite.sql)

// UNIQUE,PRIMARY KEY,FOREIGN KEY解析

SqlColumnDeclaration (org.apache.calcite.sql.ddl)

SqlLiteral

常量,表示输入的常量,须要返回值,则调用public Object getValue()方法,或者public T getValueAs(Class clazz)获取字段值

经常使用子类

SqlNumericLiteral

SqlNumericLiteral

数字常量

SqlAbstractStringLiteral

SqlAbstractStringLiteral

字符和二进制字符串文字常量

SqlBinaryStringLiteral

SqlBinaryStringLiteral

二进制(或十六进制)字符串。

SqlCharStringLiteral

SqlCharStringLiteral

类型为SqlTypeName.CHAR的信息

SqlAbstractDateTimeLiteral

SqlAbstractDateTimeLiteral

表示日期、时间或时间戳值的常量

SqlDateLiteral

SqlDateLiteral

样例: 2004-10-22

SqlTimestampLiteral

SqlTimestampLiteral

样例: 1969-07-21 03:15 GMT

SqlTimeLiteral

SqlTimeLiteral

样例: 14:33:44.567

SqlIntervalLiteral

SqlIntervalLiteral

时间间隔常量

例子:

INTERVAL '1' SECOND

INTERVAL '1:00:05.345' HOUR

INTERVAL '3:4' YEAR TO MONTH

SqlIdentifier

SqlNodeList

SqlDataTypeSpec

目前,它只支持简单的数据类型,如CHAR、VARCHAR和DOUBLE

SqlDynamicParam

SqlDynamicParam

表示SQL语句中的动态参数标记

SqlIntervalQualifier

标示区间定义

Examples include:

INTERVAL '1:23:45.678' HOUR TO SECOND

INTERVAL '1 2:3:4' DAY TO SECOND

INTERVAL '1 2:3:4' DAY(4) TO SECOND(4)

SqlKind

SqlKind

SqlNode类型

SqlOperator

SqlOperator

Sql解析的节点类型,包括:函数,操做符(=),语法结构(case)等操做

SqlOperatorTable

SqlOperatorTable

定义了一个用于枚举和查找SQL运算符(=)和函数(cast)的目录接口。

SqlStdOperatorTable

SqlStdOperatorTable

包含标准运算符和函数的SqlOperatorTable的实现

OracleSqlOperatorTable

OracleSqlOperatorTable

仅包含Oracle特定功能和运算符的运算符表

SqlParser.Config 配置信息

配置项

public interface Config {

/** 默认配置. */

Config DEFAULT = configBuilder().build();

/**

* 最大字段长度

*/

int identifierMaxLength();

/**

* 转义内 大小写转换

*/

Casing quotedCasing();

/**

* 转义字符外 大小写转换

*/

Casing unquotedCasing();

/**

* 转义字符符号

*/

Quoting quoting();

/**

* 大小写匹配 - 在planner内生效

*/

boolean caseSensitive();

/**

* sql模式

*/

SqlConformance conformance();

@Deprecated // to be removed before 2.0

boolean allowBangEqual();

/**

* 解析工厂类

*/

SqlParserImplFactory parserFactory();

}

默认配置项

public static class ConfigBuilder {

// Casing.UNCHANGED

private Casing quotedCasing = Lex.ORACLE.quotedCasing;

// Quoting.DOUBLE_QUOTE

private Casing unquotedCasing = Lex.ORACLE.unquotedCasing;

// Casing.TO_UPPER

private Quoting quoting = Lex.ORACLE.quoting;

// 128

private int identifierMaxLength = DEFAULT_IDENTIFIER_MAX_LENGTH;

// true

private boolean caseSensitive = Lex.ORACLE.caseSensitive;

// Calcite's default SQL behavior.

private SqlConformance conformance = SqlConformanceEnum.DEFAULT;

// 解析工厂类

private SqlParserImplFactory parserFactory = SqlParserImpl.FACTORY;

}

代码示例

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐