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

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

go 复制代码
Delete -> DELETE FROM ID (where Predicate)?

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

go 复制代码
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 文件,添加代码如下:

go 复制代码
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 增加代码如下:

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

}

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

go 复制代码
Modify -> UPDATE ID SET Field EQUAL Expression (WHERE Predicate)?

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

go 复制代码
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,添加如下代码:

go 复制代码
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

相关推荐
m0_741412241 分钟前
大文件上传与文件下载
前端
wu_jing_sheng02 分钟前
Python中使用HTTP 206状态码实现大文件下载的完整指南
开发语言·前端·python
90后的晨仔8 分钟前
Vue3项目全面部署指南:从构建到上线
前端·vue.js
小于小于091216 分钟前
npx 与 npm 区别
前端·npm·node.js
小桥流水人家哇16 分钟前
性能测试单场景测试时,是设置并发读多个文件,还是设置不同的用户读不同的文件?
数据库·性能测试技巧
表示这么伤脑筋的题我不会20 分钟前
Oracle 21C 部署ogg踩过的坑
数据库·oracle
你不是我我23 分钟前
【Java 开发日记】MySQL 与 Redis 如何保证双写一致性?
数据库·redis·缓存
望获linux34 分钟前
【实时Linux实战系列】实时 Linux 在边缘计算网关中的应用
java·linux·服务器·前端·数据库·操作系统
qq_2529241936 分钟前
PHP 8.0+ 现代Web开发实战指南 引
android·前端·php
Jeled36 分钟前
Android 本地存储方案深度解析:SharedPreferences、DataStore、MMKV 全面对比
android·前端·缓存·kotlin·android studio·android jetpack