当前位置: 首页 > news >正文

长春市网站制作局域网电脑做网站服务器

长春市网站制作,局域网电脑做网站服务器,物流公司图片,网站的首页标题在哪里设置的KaiwuDB 支持多种不同类型的 SQL 语句,例如 create、insert 等。本文将介绍在 KaiwuDB SQL Parser(下文统称解析器)中添加新语句的过程及其实现。我们将了解如何使用 goyacc 工具更新解析器,以及执行器和查询计划器(pl…

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

一、语法和关键字

添加新的 SQL 语句需要从向 SQL 解析器添加必要的语法开始。解析器是通过 goyacc 生成的,它是流行的 yacc 编译器的 Go 版本。语法定义位于 pkg/sql/parser/sql.y 文件中。解析器的输出是一个抽象语法树(AST),其中的节点类型(node)在 pkg/sql/sem/tree 目录下的各个文件中定义。

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

二、FROBNICATE STATEMENT

本文以在 KaiwuDB 新增一个新的语句为例:FROBNICATE。这个语句将会随机修改数据库的设置。它将有三个选项:FROBNICATE CLUSTER,用于操作集群设置;FROBNICATE SESSION,用于操作会话设置;FROBNICATE ALL,用于同时处理两者。

让我们从检查所有关键字是否已定义开始。打开 pkg/sql/parser/sql.y 文件并搜索"Ordinary key words"。你会看到一系列按字母顺序排列的标记定义。由于其他语法已经定义了 SESSION、CLUSTER 和 ALL 关键字,我们不需要添加它们,但我们需要为 FROBNICATE 创建一个关键字。它应该如下所示:

%token <str> FROBNICATE

这告诉词法分析器识别关键字,但我们仍然需要将它添加到其中一个类别列表中。如果关键字可以出现在标识符位置,它必须是保留的(reserved_keyword, 这要求对其的其他用途,例如作为列名,必须使用引号引用)。由于我们的新关键字作为一条 SQL 语句的开始,它不能被误认为是标识符,所以我们可以安全地将它添加到非保留关键字列表中。在 pkg/sql/parser/sql.y 文件中搜索 unreserved_keyword:,并按照以下方式添加 | FROBNICATE:

unreserved_keyword:
...
| FROBNICATE
...

既然词法分析器已经知道了我们所有的关键字,我们需要教会解析器如何处理我们的新语句。有三个地方我们需要添加引用:语句类型列表语句情况列表解析子句

在语法文件(pkg/sql/parser/sql.y)中搜索<tree.Statement>,你将找到类型列表。添加一行关于我们新语句类型的内容,类似于:

%type <tree.Statement> frobnicate_stmt

这样我们就为新语句类型"frobnicateStmt"添加了一个类型声明。请注意,"frobnicateStmt"只是一个示例名称,你可以根据实际情况自定义。

接下来,我们需要将新语句类型添加到语句情况列表中。继续搜索语法文件,找到以"stmt"开头的规则(如 stmt_select、stmt_insert 等)。在这些规则中添加以下情况:

stmt:
...
| frobnicate_stmt // EXTEND WITH HELP: FROBNICATE
...

最后,我们需要为我们的语句添加一个产生式规则。在 pkg/sql/parser/sql.y 文件中添加以下规则:

frobnicate_stmt:FROBNICATE CLUSTER { return unimplemented(sqllex, "frobnicate cluster") }
| FROBNICATE SESSION { return unimplemented(sqllex, "frobnicate session") }
| FROBNICATE ALL { return unimplemented(sqllex, "frobnicate all") }

这里列出了我们允许的三种表达形式,用竖线字符分隔。每个产生式还有一个用大括号括起来的实现(暂时报错并显示“未实现”的错误信息)。

最后为我们的语句添加 help 文档。在我们刚刚添加的产生式规则上方,添加以下注释:

// %Help: FROBNICATE - twiddle the various settings
// %Category: Misc
// %Text: FROBNICATE { CLUSTER | SESSION | ALL }

现在我们的解析器将能够识别新的语句类型,并且生成一些新语法相关的注释以为用户提供帮助。重新编译代码后,尝试执行这条语句,得到以下结果:

$ kwbase sql --insecure -e "frobnicate cluster"
ERROR: at or near "cluster": syntax error: unimplemented: this syntax
SQLSTATE: 0A000
DETAIL: source SQL:
frobnicate cluster^HINT: You have attempted to use a feature that is not yet implemented.Please check the public issue tracker to check whether this problem is
already tracked. If you cannot find it there, please report the error
with details by creating a new issue.If you would rather not post publicly, please contact us directly
using the support form.We appreciate your feedback.
Failed running "sql"

这代表我们新加的语法成功解析了,但是由于尚未实现,无法执行任何操作。

三、添加抽象语法树

语法层添加完成后,现在我们需要为新的语句赋予适当的语义。我们需要一个 AST 来从解析器向运行时传递语句的结构。上文说过我们的语句是 %type <tree.Statement>,这意味着它需要实现 tree.Statement接口,可以在 pkg/sql/sem/tree/stmt.go 中找到。

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

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

package treetype Frobnicate struct {Mode FrobnicateMode
}var _ Statement = &Frobnicate{}type FrobnicateMode intconst (FrobnicateModeAll FrobnicateMode = iotaFrobnicateModeClusterFrobnicateModeSession
)func (node *Frobnicate) Format(ctx *FmtCtx) {ctx.WriteString("FROBNICATE ")switch node.Mode {case FrobnicateModeAll:ctx.WriteString("ALL")case FrobnicateModeCluster:ctx.WriteString("CLUSTER")case FrobnicateModeSession:ctx.WriteString("SESSION")}
} 

要添加我们 AST 树的语句和字符串表示,打开 pkg/sql/sem/tree/stmt.go 文件并搜索 // StatementReturnType implements the Statement interface。现在你可以看到不同类型 AST 的实现列表。按照字母顺序将以下内容插入其中:

func (node *Frobnicate) StatementReturnType() StatementReturnType { return Ack }// StatementType implements the Statement interface.
func (node *Frobnicate) StatementType() StatementType { return TypeDCL }// StatementTag returns a short string identifying the type of statement.
func (node *Frobnicate) StatementTag() string               { return "FROBNICATE" }

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

func (n *Frobnicate) String() string            { return AsString(n) }

现在我们需要更新解析器,在遇到我们的语法时返回一个带有适当模式类型 FROBNICATE 节点(AST)。返回到 pkg/sql/parser/sql.y 文件,搜索 // %Help: FROBNICATE,并将语句替换为以下内容:

frobnicate_stmt:FROBNICATE CLUSTER { $$.val = &tree.Frobnicate{Mode: tree.FrobnicateModeCluster} }
| FROBNICATE SESSION { $$.val = &tree.Frobnicate{Mode: tree.FrobnicateModeSession} }
| FROBNICATE ALL { $$.val = &tree.Frobnicate{Mode: tree.FrobnicateModeAll} }

特殊符号 $$.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:

case *tree.Frobnicate:return p.Frobnicate(ctx, n)

同样,在同一文件 /pkg/sql/opaque.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 客户端了。我们只需要上述接口添加功能能代码,让语句生效即可。

http://www.yayakq.cn/news/893548/

相关文章:

  • 龙岩找工作网站软件开发有用吗
  • 最好的php网站开发工具用visual做的网站
  • 论坛网站怎么做排名小程序token
  • 网页设计与网站建设标准数据qq空间钓鱼网站后台怎么做
  • 东莞网站建设流程图1 分析seo做的不好的网站
  • 建立一个网站的前期资金网站访问量数据
  • 南京网站优化公司排名wordpress 提供了 支持
  • 佛山北京网站建设公司重庆建筑材料价格信息网
  • 网站开发需要多久北京网站设计的公司
  • 东莞大朗网站建设哪家口碑好关键词下载
  • 谁有做爰网站南京网站建设网站制作
  • 网站推广明细报价表攸县网站定制
  • 淘宝做详情页代码网站建设工程消防设计备案凭证查询网站
  • 美瞳网站建设制作网站需要wordpress
  • 如何用.net做网站竞价推广
  • 沈阳网站建设找哪家seo推广的方法
  • 网站建设与管理自考重点工商网企业信息查询系统上海
  • 西安建设公司网站中国的网站做欧美风
  • 怎么做网站步骤免费的wordpress插件恢复图片
  • 淘客网站难做吗建筑招标信息网官网
  • 网站做调查需要考虑的内容网站页面设计流程
  • 建行信用卡网站官网入口政务网站建设 紧急通知
  • 公司加强网站建设做网站工作内容
  • wordpress怎么做301跳转seo研究中心论坛
  • 中卫市建设网站汕头教育学会网站建设
  • 网站背景图片代码微营销软件
  • 苏州网站开发建设服务合肥网站建设的公司
  • 兰州手机网站建设东莞市建设局质量监督网站
  • 果洛州wap网站建设公司邢台做网站企业
  • 彩票网站怎么做系统网站域名备案