SQL解析 如何轻松实现新语句

小夏 科技 更新 2024-01-31

KaiwuDB 支持多种不同类型的 SQL 语句,如 create、insert 等。 本文介绍在 KaiwuDB SQL 解析器(以下简称解析器)中添加新语句的流程及其实现。 我们将了解如何使用 goyacc 工具更新解析器,以及执行器和查询计划器如何协同工作来执行此语句。

添加新的 SQL 语句首先要向 SQL 解析器添加必要的语法。 解析器由 goyacc 生成,goyacc 是流行的 yacc 编译器的 go 版本。 语法定义位于 pkg sql parser sql 中y 文件。 解析器的输出是一个抽象语法树 (AST),其中节点类型在 pkg SQL SEM 树目录中的各种文件中定义。

向 SQL 解析器添加新语句有三个主要组件:添加新关键字、向解析器添加语法以及添加新的语法节点类型。

在此示例中,我们将使用 KaiwuDB 中的一个新语句:frobnicate。 此语句将随机修改数据库的设置。 它将有三个选项:frobnicate cluster,用于操作集群设置;frobnicate session,用于操作会话设置;frobnicate all,用于同时处理两者。

让我们首先检查是否定义了所有关键字。 打开 pkg sql 解析器 sqlY 文件和搜索"ordinary key words"。您将看到一系列按字母顺序排列的标记定义。 由于其他语法已经定义了会话、集群和所有关键字,因此我们不需要添加它们,但我们确实需要为 frobnicate 创建一个关键字。 它应如下所示:

%token frobnicate
这告诉词法分析器识别关键字,但我们仍然需要将其添加到其中一个类别列表中。 如果关键字可以出现在标识符位置,则必须保留该关键字(这要求必须将其引在引号中才能用于其他用途,例如作为列名)。 由于我们的新关键字用作 SQL 语句的开头,因此它不会被误认为是标识符,因此我们可以安全地将其添加到非保留关键字列表中。 在 pkg sql 解析器 sql 中yfile,搜索 unreserved 关键字: 并添加 |,如下所示 frobnicate:

unreserved_keyword:

frobnicate

现在词法分析器知道了我们所有的关键字,我们需要教解析器如何处理我们的新语句。 我们需要在三个地方添加引用:语句类型列表、语句大小写列表和解析子句。

在语法文件 (pkg sql parser sqly),您将找到类型列表。添加一行关于我们的新语句类型,如下所示:

%type frobnicate_stmt
因此,我们将创建一个新的语句类型"frobnicatestmt"添加了类型声明。 请注意"frobnicatestmt"只是一个示例名称,您可以根据自己的实际情况进行自定义。

接下来,我们需要将新的语句类型添加到语句大小写的列表中。 继续搜索语法文件并找到它"stmt"(例如 stmt select、stmt insert 等)。 将以下情况添加到这些规则中:

stmt:

frobnicate_stmt // extend with help: frobnicate

最后,我们需要在语句中添加一个生成规则。 在 pkg sql 解析器 sql 中Y 文件:

frobnicate_stmt:

frobnicate cluster

frobnicate session

frobnicate all

以下是我们允许的三个表达式的列表,用垂直字符分隔。 每个生成器还有一个用大括号括起来的实现(它暂时报告错误并显示“未实现”错误消息)。

最后,将帮助文档添加到我们的声明中。 在我们刚刚添加的生成规则上方,添加以下注释:

// %help: frobnicate - twiddle the various settings

category: misc

text: frobnicate

现在,我们的解析器将能够识别新的句子类型,并生成一些关于新语法的注释,以帮助用户。 重新编译后,尝试执行此语句,得到如下结果:

$ kwbase sql --insecure -e "frobnicate cluster"

error: at or near "cluster": syntax error: unimplemented: this syntax

sqlstate: 0a000

detail: source sql:

frobnicate cluster

这意味着我们的新语法已成功解析,但我们无法执行任何操作,因为它尚未实现。

现在添加了语法层,我们需要为新语句提供适当的语义。 我们需要一个 ast 来将语句的结构从解析器传递到运行时。 如上所述,我们的语句是 %type,这意味着它需要实现 tree语句接口,可以在 PKG SQL SEM 树 stmt 中找到去。

我们需要编写四个函数:三个用于 Statement 接口本身(StatementReturnType、StatementType 和 StatementTag),一个用于 NodeFormatter(Format) 和标准 FMTstringer。

请为我们的语句类型创建一个新文件:pkg sql sem tree frobnicatego。在其中,输入我们 AST 节点的格式和定义。

package tree

type frobnicate struct

type frobnicatemode int

const (

frobnicatemodeall frobnicatemode = iota

frobnicatemodecluster

frobnicatemodesession

func (node *frobnicate) format(ctx *fmtctx)

要向 ast 树添加语句和字符串表示形式,请打开 pkg sql sem tree stmt转到文件并搜索 StatementReturnType 实现 Statement 接口。 现在,您可以看到不同类型 AST 的实现列表。 按字母顺序插入以下内容:

func (node *frobnicate) statementreturntype() statementreturntype 

statementtype implements the statement interface.

func (node *frobnicate) statementtype() statementtype

statementtag returns a short string identifying the type of statement.

func (node *frobnicate) statementtag() string

接下来,按字母顺序添加以下内容:

func (n *frobnicate) string() string
现在,我们需要更新解析器,以便在遇到语法时返回具有适当模式类型的 frobnicate 节点 (AST)。 返回 pkg sql 解析器 sqly 文件,搜索 %help: frobnicate,并将语句替换为以下内容:

frobnicate_stmt:

frobnicate cluster }

frobnicate session }

frobnicate all }

特殊符号 $$val 表示此规则生成的节点值。 还有一些其他的 $ 符号可以在 yacc 中使用。 一种更有用的形式是引用子生成器的节点值(例如,在这三个语句中,$1 将是令牌的 frobnicate)。

接下来,重新编译 kaiwudb 并重新输入新语法,得到如下结果:

$ kwbase sql --insecure -e "frobnicate cluster"

error: pq: unknown statement type: *tree.frobnicate

failed running "sql"

现在我们看到的错误与以前不同。 此错误来自 SQL Planner,当遇到新的语句类型时,它不知道该怎么做。 我们需要教它新语句的含义。 尽管我们的语句在任何查询计划中都不起作用,但我们将通过向计划器添加方法来实现。 这是集中式语句的分发位置,因此语义被添加到那里。

找到我们当前看到的错误的来源**,你会看到它位于 pkg sql opaque 中在 go 文件中一长串类型选择语句的末尾。 让我们添加一个案例:

case *tree.frobnicate:

return p.frobnicate(ctx, n)

同样,在同一文件中 pkg sql 不透明Go 的 init() 函数:

&tree.frobnicate{},
这将在规划器本身(尚未实现)上调用一个方法。 让我们从 pkg sql frobnicate 开始GO 文件。

package sql

import (

context"

github.com/kwbasedb/kwbase/pkg/sql/sem/tree"

github.com/kwbasedb/errors"

func (p *planner) frobnicate(ctx context.context, stmt *tree.frobnicate) (plannode, error) {

return nil, errors.assertionfailedf("we're not quite frobnicating yet...")

此时,重新编译 kaiwudb 并再次执行语句:

$ kwbase sql --insecure -e "frobnicate cluster"

error: pq: we're not quite frobnicating yet...

failed running "sql"

此时,我们已经能够将错误传递给 SQL 客户端。 我们只需要添加上面的接口函数,就可以使语句生效。

相似文章

    如何使用SuperSu轻松扎根Android手机?

    伙计们,你有没有想过让你的 Android 手机更强大 更个性化 更省电?如果是这样,那么您可能需要获得 root 权限,即超级用户权限。然而,获得root访问权限并不是一件容易的事情,它需要一定的技能和风险。如果操作不当,可能会导致手机变砖 失去保修,甚至被黑客入侵。那么,有没有一种简单方便的方法...

    如何在Word中轻松实现文本倒立效果

    本文将向您介绍如何在Word中轻松实现文本倒立效果,让您在排版时更加独特。通过在Word中使用一个小技巧,您可以轻松地将文本倒置显示,并为您的文档添加一丝趣味。一 引言。在word文档中,有时我们需要将文本倒置显示以增加排版的独特性。这不仅会增加文档的趣味性,而且还会让读者更加关注你在说什么。那么,...

    如何才能轻松实现桃树的高产?一些不用担心效率低下的技巧

    在我们中国传统的记忆中,桃子本身就是吉祥的象征,在 西游记 中,玉皇大帝和太后每次举行生日宴,都会让一群天上的仙女去桃园采摘桃子,可见桃子的寓意是吉祥的,而且桃木自古以来就被用来辟邪,在家里种一棵桃树也是一件美妙的事情。作为桃子的品种之一,黑桃也是许多种植者的首选。桃树适合种植在院子的东南 西南 西...

    在线考试系统如何轻松实现考试的全过程?

    与传统的线下考试相比,无需打印试卷,可以进行智能监考 智能阅卷 智能分析,提高了工作效率,减少了考试事务的工作量,使考试更加高效便捷。作为专业的在线考试组织平台,考试系统功能和设置非常齐全,可以轻松实现考试的全过程。组织考试的第一步 将试题导入系统题库,方便后续管理和操作。管理员可以先在考试系统的试...

    移动数据用不完?教你如何轻松实现移动数据传输!

    如果您想将手机中无法使用的部分捐赠给其他人,您可以按照以下步骤进行操作 确认您的手机号码和移动运营商。不同的运营商可能有不同的数据移植方式,因此您需要先查看您的手机号码所属的移动运营商。打开手机营业厅APP或登录手机官 使用您的手机号码和密码登录您的账户 在应用程序或 上。找到 传输 或 数据共享 ...