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


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

    Delete -> DELETE FROM ID (where Predicate)?
    
    • 1

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

    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)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    新增一个 delete_data.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
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

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

    func main() {
    	sql := "DELETE FROM Customers WHERE CustomerName=\"Alfreds Futterkiste\""
    	sqlParser := parser.NewSQLParser(sql)
    	sqlParser.UpdateCmd()
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

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

    Modify -> UPDATE ID SET Field EQUAL Expression (WHERE Predicate)?
    
    • 1

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

    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)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    接下来增加一个文件 modify_data.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
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

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

  • 相关阅读:
    mysql bin_log日志恢复数据
    Spark 中的分桶分化
    创建型模式-抽象工厂模式
    面向对象编程原则(08)——合成复用原则
    DW大学生网页作业制作设计 ——旅游门户网站(21页)HTML+CSS+JavaScript
    elasticsearch之使用正则表达式自定义分词逻辑
    提升企业网络安全的重要性:EventLog Analyzer的角色
    【Qt】Qt Style Sheets (QSS) 指南:打造个性化用户界面
    全球化浪潮下的数据库革新:嘉里物流 TiDB 实践价值的设想
    十八、【模糊工具组】
  • 原文地址:https://blog.csdn.net/tyler_download/article/details/132610585