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

相关推荐
qq_422152571 分钟前
PDF 加水印工具怎么选?2026 年文档版权保护方案对比
前端·pdf·github
kyriewen13 分钟前
手写 Promise.all、race、any:不到 30 行代码,解决并发异步的所有姿势
前端·javascript·面试
洪晓露37 分钟前
将 rke2 集群证书延长至 10 年
运维·服务器·数据库
程序猿乐锅1 小时前
【MySQL | 第八篇】MySQL 视图
数据库·mysql
brucelee1861 小时前
OpenClaw 浏览器控制(Chrome MCP)完整教程
前端·chrome
ct9781 小时前
React 状态管理方案深度对比
开发语言·前端·react
胡志辉的博客2 小时前
深入浅出理解浏览器事件循环:从一道输出题讲到 Chrome 源码
前端·javascript·chrome·chromium·event loop
代码不加糖2 小时前
js中不会冒泡的事件有哪些?
前端·javascript·vue.js
jieyucx2 小时前
SQL 查询终极高阶通鉴:从零基础拆解到工业级多表联查、窗口函数与索引优化
数据库·sql
懂懂tty2 小时前
Vue2与Vue3之间API差异
前端·javascript·vue.js