Apache Calcite教程-SQL解析-Calcite SQL解析

Calcite SQL解析

一、代码结构

在这里插入图片描述

其中,在codegen文件夹下,  config.fmpp (主要制定实现类路径)表示calcite 模板配置,Parser.jj是JavaCC解析器所需解析文件(比如增加函数时的主要修改文件),parserImpls.ftl/compoundIdentifier.ftl 附加模版文件. (都注释掉了, 暂时没有使用过)

生成解析器的流程, 如图:

在这里插入图片描述

二、例子引入

calcite 主要api,其中比如Span、SqlParser等概念可以查阅

Overview (Apache Calcite API)icon-default.png?t=M4ADhttps://calcite.apache.org/javadocAggregate/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 解析简单介绍

调用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
SqlParserPos的建造者
具体使用还不太清楚

SqlAbstractParserImpl
抽象解析器,Calcite所有的解析的父类,主要是设置一些解析的配置信息


SqlParseException
SQL解析异常


SqlParser
解析SQL语句


SqlParserImplFactory
解析器的工厂类接口,可以自定义解析工厂


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


SqlParserUtil
SQL解析工具类

SqlNode
SQL解析树,是所有解析的节点的父类
 

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> T getValueAs(Class<T> clazz)获取字段值

常用子类


SqlNumericLiteral
数字常量

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

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

SqlCharStringLiteral
类型为SqlTypeName.CHAR的信息

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

SqlDateLiteral
样例: 2004-10-22


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


SqlTimeLiteral
样例: 14:33:44.567


SqlIntervalLiteral
时间间隔常量
例子:

INTERVAL '1' SECOND
INTERVAL '1:00:05.345' HOUR
INTERVAL '3:4' YEAR TO MONTH


SqlIdentifier
Sql中的Id标示符


SqlNodeList
SqlNode的集合


SqlDataTypeSpec
SQL数据类型规范.

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


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
SqlNode类型


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


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


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


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;
}


 

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是学习 Apache Calcite 的一些步骤和资源: 1. 了解 Apache Calcite - 了解 Apache Calcite 的基本概念和特点。可以查看 Apache Calcite 官方网站和文档,了解 Calcite 的功能和用途。 2. 学习 SQL - Apache Calcite 是一个 SQL 解析器和查询优化器,因此了解 SQL 语言的基本语法和特性是非常重要的。可以阅读 SQL 教程或书籍来学习 SQL。 3. 安装和配置 Apache Calcite - 从 Apache Calcite 的官方网站下载最新版本的 Calcite,并按照官方文档的指导进行安装和配置。 4. 编写 SQL 查询 - 编写一些简单的 SQL 查询并在 Apache Calcite 中运行它们,可以使用 Calcite 的命令行界面,也可以在 Java 应用程序中集成 Calcite。 5. 学习 Apache Calcite 的 API - 学习 Apache Calcite 的 API,并尝试使用它们来开发自己的应用程序。可以查看官方文档和示例代码来学习 Calcite 的 API。 6. 参与社区 - 加入 Apache Calcite 的邮件列表和社区,与其他开发者交流,了解 Calcite 的最新动态和发展方向。 推荐一些 Apache Calcite 的学习资源: - Apache Calcite 官方网站:https://calcite.apache.org/ - Apache Calcite 官方文档:https://calcite.apache.org/docs/ - Apache Calcite 示例代码:https://github.com/apache/calcite/tree/master/example - Apache Calcite 的邮件列表:https://calcite.apache.org/mailing-lists.html - SQL 教程:https://www.w3schools.com/sql/ - 《Apache Calcite: A Foundational Framework for Optimized Query Processing》一书,由 Apache Calcite 的核心开发者编写,介绍了 Apache Calcite 的设计和实现。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值