DELETE Statement,懂你不容易

书接上文 , 自从团队对外公布了TiDBforPostgreSQL项目之后 , 团队成员正在紧锣密鼓的为下一个里程碑做努力 , 目前我们主要的工作集中在以下几个方面:
完善PGSQL的通信协议
实现PGSQL关键字和语法
修复单元测试
数据库Chaos测试平台 ,
我们先回顾一下往期内容 , 再进入本文主题:
除此之外 , 我们的项目也有幸入选PingCapDevCon2021大会论坛话题 , 同时还进入了第二期TiDBHackingCamp , 欢迎大家多多关注我们 , 更欢迎大家加入我们 。
书归正文 , 这期文章主要介绍DataManipulationLanguage中的DeleteStatement , 也就是CRUD中的最后一个字母 。 让我们先看看Mysql , PostgreSQL , SQL-2003Standard都是怎么定义Delete的语法 。
MySQLSingle-TableSyntax
From
Multiple-TableSyntax
From
ThiscommandconformstotheSQLstandard,exceptthattheUSINGandRETURNINGclausesarePostgreSQLextensions,asistheabilitytouseWITHwithDELETE.
From
SQL-2003BNF从这三个数据库的定义是不是觉得只有SQL-2003跟常用的DeleteFromTable删表跑路的语法差不多 , 其他两个数据库加入了一些自定义的语法功能 , 尤其是MySQL , 长得像个远房亲戚 。 这里不对各个自定义语法功能做解释 , 想了解的读者可以点击对应的官方链接查阅 。
Yacc实现了解语法定义是远远不够的 , 我们还需要看看parser.y对DeleteStatement的MySQL实现 , 从DeleteStatement开始 , 分成了DeleteWithoutUsingStmt和DeleteWithUsingStmt两个分支 , 每个分支中又定义了对应的语法 , 可以看出每一个语法定义都基本符合MySQL的定义 , 整个过程就是把SQL解析成AST , 下一步就是拿现有的parser做个demo , 看看是否能正常解析我们的DeleteSQL 。
可以点击这个链接直接查看文件
https://link.zhihu.com/?target=https%3A//docs.pingcap.com/zh/tidb/stable/sql-statement-delete
我们直接定位到DeleteStatement部分 , 需要了解tidb官方文档对Delete的解释 , 可以点击上方链接 。
验证Yacc
我们新建一个golang项目 , 如下 。 这个demo解析了两个DeleteSQL , 第一个比较简单 , 第二个几乎把所有的参数都填上了 , 我们看看执行后的效果 。
项目设置断点后运行 , 对"DELETEFROMsomelog;"的解析呈现AST结构 , 可以看到TableName正确获取到了 , 其他的参数where,order,limit , priority,ignore,quick等等都是空值 。
DELETE Statement,懂你不容易

【DELETE Statement,懂你不容易】对二个SQL解析时"DELETE/*+BKA(somelog)*/LOW_PRIORITYQUICKIGNOREFROMsomelogPARTITION(p1,p2)AStFORCEINDEXFORORDERBY(timestamp_column)WHEREuser='jcole'ORDERBYtimestamp_columnLIMIT1;" , 整个AST就变得庞大很多 , 包括where里的相等操作也能正确解析 , 说明这个parser可以工作正常 , 接下来我们开始删除对于PG来说不需要的语法参数 。
DELETE Statement,懂你不容易

修改Yacc
我们开始删除PostgreSQL中没有的参数 , 如以下代码所示 , 对应的代码解析部分也要做相应的调整 , 不然会编译报错 , 当然中间也确实遇到了一个很麻烦的问题 , 如果你也遇到了类似conflict的问题 , 可以看看文末的troubleshooting 。
利用项目自带的goyacc进行编译 , 记住 , 一定是用项目再带的goyacc编译 , 因为tidb对yyLexer接口一些改动 , 如果用go自带的goyacc编译会报没有实现方法的错误 。 好了 , 执行完之后就会生成一个新的parser.go文件 , 恭喜修改成功~!
不过 , 最后还需要把yacc修改导致的UT错误给修复了:)
DELETE Statement,懂你不容易

本文删除MySQL自定义语法的目标已经接近完成 , 剩下的几个语法功能就留给读者自己尝试删除 , 关于如何加入PostgreSQL语法功能 , 我们会在下次分解 。