美文网首页
Doris 源码分析 (三) 基础语法

Doris 源码分析 (三) 基础语法

作者: 走在成长的道路上 | 来源:发表于2021-10-08 17:58 被阅读0次

常见使用语句

# 查看创建表帮助文档
> HELP CREATE TABLE;

# 查看 ALTER 进度状态
> SHOW ALTER TABLE COLUMN;

# 取消 ALTER 进度
> CANCEL ALTER TABLE COLUMN FROM table1

# 查看 ALTER 相关命令
> HELP ALTER TABLE

语法解析过程

Doris SQL 解析具体包括了五个步骤:词法分析,语法分析,生成单机逻辑计划,生成分布式逻辑计划,生成物理执行计划。

具体代码实现上包含以下五个步骤:Parse, Analyze, SinglePlan, DistributedPlan, Schedule。如下图所示:

解析执行过程

上图中未提及 Parse 过程,而该过程在 Doris 系统中语法解析分为三个阶段 jflex 词法分析、java cup parser 进行语法分析、生成抽象语法树(AST),AST 是种树状结构,将不同的查询语句 select, insert, show, set, alter table, create table 等经过 Parse 阶段后生成不同的数据结构(SelectStmt, InsertStmt, ShowStmt, SetStmt, AlterStmt, AlterTableStmt, CreateTableStmt 等)之后,根据语法规则进行逻辑处理即可。

因此整体流程下来即如下图:


一个简单的查询 SQL 在 Doris 的解析实现

使用 SqlParserUtils 实现 sql 解析过程,如下是 parse 结果实例:

String originStmt = "select username, sum(distinct link) from tbl_event_log  group by username;";
SqlScanner input = new SqlScanner(new StringReader(originStmt), ctx.getSessionVariable().getSqlMode());
SqlParser parser = new SqlParser(input);
StatementBase statementBase = SqlParserUtils.getFirstStmt(parser);

实际解析过程在 org.apache.doris.qe.StmtExecutor 类进行解析,然后生成执行计划,实例如下:

String sql7 = "select * from db1.tbl1 where k1='a' and k4=1\n"
        + "except distinct\n"
        + "select * from db1.tbl1 where k1='a' and k4=1\n"
        + "except\n"
        + "select * from db1.tbl1 where k1='a' and k4=2\n"
        + "except\n"
        + "(select * from db1.tbl1 where k1='a' and k4=2)\n"
        + "order by 3 limit 3";
StmtExecutor stmtExecutor7 = new StmtExecutor(ctx, sql7);
stmtExecutor7.execute();
Planner planner7 = stmtExecutor7.planner();
List<PlanFragment> fragments7 = planner7.getFragments();
String plan7 = planner7.getExplainString(fragments7, new ExplainOptions(false, false));

Doris 解析过程如下所示:

# 在 org.apache.doris.qe.ConnectProcessor 类 handleQuery() 函数中获取 sql 内容,并将 sql 转化为 StatementBase 列表

// process COM_QUERY statement,
// 只有在与请求客户端交互出现问题时候才抛出异常
private void handleQuery() {
    // ... 省略 ....
        originStmt = new String(bytes, 1, ending, "UTF-8");
    // ... 省略 ....
    String sqlHash = DigestUtils.md5Hex(originStmt);
    ctx.setSqlHash(sqlHash);
    // 匹配数据 block 规则, 如果符合 block 规则则取消执行
    Catalog.getCurrentCatalog().getSqlBlockRuleMgr().matchSql(originStmt, sqlHash, ctx.getQualifiedUser());
    // ... 省略 ....
    ctx.getAuditEventBuilder().reset();
    ctx.getAuditEventBuilder()
        .setTimestamp(System.currentTimeMillis())
        .setClientIp(ctx.getMysqlChannel().getRemoteHostPortString())
        .setUser(ctx.getQualifiedUser())
        .setDb(ctx.getDatabase())
        .setSqlHash(ctx.getSqlHash());
    // execute this query.
    StatementBase parsedStmt = null;
    List<Pair<StatementBase, Data.PQueryStatistics>> auditInfoList = Lists.newArrayList();
    boolean alreadyAddedToAuditInfoList = false;
    try {
        // 分析语法并将其转化为相应的 StatementBase 类
        List<StatementBase> stmts = analyze(originStmt);
        for (int i = 0; i < stmts.size(); ++i) {
            alreadyAddedToAuditInfoList = false;
            ctx.getState().reset();
            if (i > 0) {
               ctx.resetReturnRows();
            }
            parsedStmt = stmts.get(i);
            parsedStmt.setOrigStmt(new OriginStatement(originStmt, i));
            parsedStmt.setUserInfo(ctx.getCurrentUserIdentity());
            // 将 StatementBase 类封装为 StmtExecutor 类
            executor = new StmtExecutor(ctx, parsedStmt);
            ctx.setExecutor(executor);
            // 将 StatementBase 类解析为执行计划
            executor.execute();
            if (i != stmts.size() - 1) {
                ctx.getState().serverStatus |= MysqlServerStatusFlag.SERVER_MORE_RESULTS_EXISTS;
                finalizeCommand();
            }
            auditInfoList.add(new Pair<>(executor.getParsedStmt(), executor.getQueryStatisticsForAuditLog()));
            alreadyAddedToAuditInfoList = true;
        }
    } catch (IOException e) {
    // ... 省略 ....
}

相关文章

  • Doris 源码分析 (三) 基础语法

    常见使用语句 语法解析过程 Doris SQL 解析具体包括了五个步骤:词法分析,语法分析,生成单机逻辑计划,生成...

  • Java 集合类原理

    Java基础——HashMap源码分析 Java基础——HashSet源码分析 Java基础——HashTable...

  • Kotlin进阶学习笔记

    Kotlin进阶学习笔记 从源码分析学习Kotlin,知其然、知其所以然。 通用基础语法学习Kotlin官网[ht...

  • 阅读框架开源代码技巧

    基础性结构语法 注解,反射,泛型,并发,OOP,设计模式,数据结构算法 移动端源码分析入口 一步一步分析,如果AP...

  • Doris 源码分析 (二) 代码结构分析

    主交互逻辑 主交互架构 注 正如上图所示,FE 端主要是 PaloFe 开启的服务入口, 后端为 doris_ma...

  • python3从零学习-4.1、基础语法(上)

    基础语法(上) Python源码文件后缀: Python源码文件都以.py为后缀,可以用vscode/pychar...

  • 树与二叉树解析

    早在分析Java集合源码时,我们对树和二叉树就有了基本的了解,部分知识可以查看Java集合源码分析之基础(三):树...

  • 黑马day02

    day02.01_java基础语法_案列需求介绍 day02.02_java基础语法_小票界面结构分析  ...

  • Python3学习 - 第四节

    1. 基础语法 简单介绍几个比较常用的基础语法知识: a.编码默认情况下,Python 3 源码文件以UTF-8编...

  • 线程学习->05wait、notify、yield、joi

    一、参考文章: JVM源码分析之Object.wait/notify实现 二、基础api: 三、wait与noti...

网友评论

      本文标题:Doris 源码分析 (三) 基础语法

      本文链接:https://www.haomeiwen.com/subject/paatoltx.html