自己动手写数据库:实现一个小型 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

相关推荐
程序员Agions30 分钟前
useMemo、useCallback、React.memo,可能真的要删了
前端·react.js
·云扬·30 分钟前
MySQL Redo Log落盘机制深度解析
数据库·mysql
滕青山32 分钟前
Vue项目BMI计算器技术实现
前端·vue.js
子兮曰36 分钟前
深入浏览器指纹:Canvas、WebGL、Audio是如何暴露你的身份的?
前端·浏览器·canvas
月亮补丁38 分钟前
AntiGravity只能生成 1:1 图片?一招破解尺寸限制
前端
何中应42 分钟前
MindMap部署
前端·node.js
用户9828630256843 分钟前
pg内核实现细节
数据库
NAGNIP1 小时前
程序员效率翻倍的快捷键大全!
前端·后端·程序员
一个网络学徒1 小时前
python5
java·服务器·前端
tiantian_cool1 小时前
Claude Opus 4.6 模型新特性(2026年2月5日发布)
前端