前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >自己动手写数据库:实现一个小型 SQL 解释器(下)

自己动手写数据库:实现一个小型 SQL 解释器(下)

作者头像
望月从良
发布2023-09-14 08:12:35
2430
发布2023-09-14 08:12:35
举报
文章被收录于专栏:Coding迪斯尼Coding迪斯尼

本节我们完成 SQL 解释器的最后一部分,它涉及到数据的删除和更改,首先我们看删除语句的解析。我们先看 delete 对应的语法:

代码语言:javascript
复制
Delete -> DELETE FROM ID (where Predicate)?

从语法规则可以看出,delete 语句必须以关键字 DELETE , FROM 开始,然后接着的字符串必须要满足 ID 的定义,最后可能接着 where 关键字,然后进入 Predicate 的解析,我们看看代码实现,在 parser.go 中的 Delete 函数增加代码如下:

代码语言:javascript
复制
func (p *SQLParser) Delete() interface{} {
    /*
        第一个关键字 delete,第二个关键字必须 from
    */
    p.checkWordTag(lexer.DELETE)
    p.checkWordTag(lexer.FROM)
    p.checkWordTag(lexer.ID)
    tblName := p.sqlLexer.Lexeme
    pred := query.NewPredicate()
    if p.isMatchTag(lexer.WHERE) {
        pred = p.Predicate()
    }
    return NewDeleteData(tblName, pred)
}

新增一个 delete_data.go 文件,添加代码如下:

代码语言:javascript
复制
package parser

import "query"

type DeleteData struct {
    tblName string
    pred    *query.Predicate
}

func NewDeleteData(tblName string, pred *query.Predicate) *DeleteData {
    return &DeleteData{
        tblName: tblName,
        pred:    pred,
    }
}

func (d *DeleteData) TableName() string {
    return d.tblName
}

func (d *DeleteData) Pred() *query.Predicate {
    return d.pred
}

最后在 main.go 增加代码如下:

代码语言:javascript
复制
func main() {
    sql := "DELETE FROM Customers WHERE CustomerName=\"Alfreds Futterkiste\""
    sqlParser := parser.NewSQLParser(sql)
    sqlParser.UpdateCmd()

}

以上代码的调试演示过程请在 B 站搜索 coding 迪斯尼查看相关视频。我们还剩下最后一个语句,那就是 update,先看看 update 语句对应的语法:

代码语言:javascript
复制
Modify -> UPDATE ID SET Field EQUAL Expression (WHERE Predicate)?

首先它必须以关键字 update 开头,然后跟着的字符串必须满足 ID 的定义,然后跟着关键字 SET, 后面跟着的一系列字符串要满足 Field 的定义,其实这里 Field 对应列名,下面跟着等号关键字,等号后面则是一个计算表达式,在最后我们还得判断是否接着 where 关键字,如果有,我们还要解析 where 后面对应的表达式,我们看看对应代码实现:

代码语言:javascript
复制
func (p *SQLParser) Modify() interface{} {
    p.checkWordTag(lexer.UPDATE)
    p.checkWordTag(lexer.ID)
    //获得表名
    tblName := p.sqlLexer.Lexeme
    p.checkWordTag(lexer.SET)
    _, fldName := p.Field()
    p.checkWordTag(lexer.ASSIGN_OPERATOR)
    newVal := p.Expression()
    pred := query.NewPredicate()
    if p.isMatchTag(lexer.WHERE) {
        pred = p.Predicate()
    }
    return NewModifyData(tblName, fldName, newVal, pred)
}

接下来增加一个文件 modify_data.go,添加如下代码:

代码语言:javascript
复制
package parser

import "query"

type ModifyData struct {
    tblName string
    fldName string
    newVal  *query.Expression
    pred    *query.Predicate
}

func NewModifyData(tblName string, fldName string, newVal *query.Expression, pred *query.Predicate) *ModifyData {
    return &ModifyData{
        tblName: tblName,
        fldName: fldName,
        newVal:  newVal,
        pred:    pred,
    }
}

func (m *ModifyData) TableName() string {
    return m.tblName
}

func (m *ModifyData) TargetField() string {
    return m.fldName
}

func (m *ModifyData) NewValue() *query.Expression {
    return m.newVal
}

func (m *ModifyData) Pred() *query.Predicate {
    return m.pred
}

到这里我们就基本完成了一个小型 SQL 解释器,更详细的调试演示和讲解请在 B 站参看 coding 迪斯尼,代码下载地址: https://github.com/wycl16514/SQL_PARSER_FINISH.git

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-09-01 17:09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Coding迪斯尼 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档