2019独角兽企业重金招聘Python工程师标准>>>

背景知识

SQL 语句发送到 TiDB 后首先会经过 parser,从文本 parse 成为 AST(抽象语法树),通过 Query Optimizer 生成执行计划,得到一个可以执行的 plan,通过执行这个 plan 即可得到结果,这期间会涉及到如何获取 table 中的数据,如何对数据进行过滤、计算、排序、聚合、滤重以及如何对表达式进行求值。 对于一个 builtin 函数,比较重要的是进行语法解析以及如何求值。其中语法解析部分需要了解如何写 yacc 以及如何修改 TiDB 的词法解析器,较为繁琐,我们已经将这部分工作提前做好,大多数 builtin 函数的语法解析工作已经做完。 对 builtin 函数的求值需要在 TiDB 的表达式求值框架下完成,每个 builtin 函数被认为是一个表达式,用一个 ScalarFunction 来表示,每个 builtin 函数通过其函数名以及参数,获取对应的函数类型以及函数签名,然后通过函数签名进行求值。 总体而言,上述流程对于不熟悉 TiDB 的朋友而言比较复杂,我们对这部分做了些工作,将一些流程性、较为繁琐的工作做了统一处理,目前已经将大多数未实现的 buitlin 函数的语法解析以及寻找函数签名的工作完成,但是函数实现部分留空。换句话说,只要找到留空的函数实现,将其补充完整,即可作为一个 PR。

添加 builtin 函数整体流程

  • 找到未实现的函数 在 TiDB 源码中的 expression 目录下搜索 errFunctionNotExists,即可找到所有未实现的函数,从中选择一个感兴趣的函数,比如 SHA2 函数:
func (b *builtinSHA2Sig) eval(row []types.Datum) (d types.Datum, err error) {return d, errFunctionNotExists.GenByArgs("SHA2")
}
  • 实现函数签名 接下来要做的事情就是实现 eval 方法,函数的功能请参考 MySQL 文档,具体的实现方法可以参考目前已经实现函数。

  • 在 typeinferer 中添加类型推导信息 在 plan/typeinferer.go 中的 handleFuncCallExpr() 里面添加这个函数的返回结果类型,请保持和 MySQL 的结果一致。全部类型定义参见 MySQL Const。

    * 注意大多数函数除了需要填写返回值类型之外,还需要获取返回值的长度。
  • 写单元测试 在 expression 目录下,为函数的实现增加单元测试,同时也要在 plan/typeinferer_test.go 文件中添加 typeinferer 的单元测试

  • 运行 make dev,确保所有的 test case 都能跑过

示例

这里以新增 SHA1() 函数的 PR 为例,进行详细说明 首先看 expression/builtin_encryption.go: 将 SHA1() 的求值方法补充完整

func (b *builtinSHA1Sig) eval(row []types.Datum) (d types.Datum, err error) {// 首先对参数进行求值,这块一般不用修改args, err := b.evalArgs(row)if err != nil {return types.Datum{}, errors.Trace(err)}// 每个参数的意义请参考 MySQL 文档// SHA/SHA1 function only accept 1 parameterarg := args[0]if arg.IsNull() {return d, nil}// 这里对参数值做了一个类型转换,函数的实现请参考 util/types/datum.gobin, err := arg.ToBytes()if err != nil {return d, errors.Trace(err)}hasher := sha1.New()hasher.Write(bin)data := fmt.Sprintf("%x", hasher.Sum(nil))// 设置返回值d.SetString(data)return d, nil
}

接下来给函数实现添加单元测试,参见 expression/builtin_encryption_test.go

var shaCases = []struct {origin interface{}crypt  string}{{"test", "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"},{"c4pt0r", "034923dcabf099fc4c8917c0ab91ffcd4c2578a6"},{"pingcap", "73bf9ef43a44f42e2ea2894d62f0917af149a006"},{"foobar", "8843d7f92416211de9ebb963ff4ce28125932878"},{1024, "128351137a9c47206c4507dcf2e6fbeeca3a9079"},{123.45, "22f8b438ad7e89300b51d88684f3f0b9fa1d7a32"},}func (s *testEvaluatorSuite) TestShaEncrypt(c *C) {defer testleak.AfterTest(c)() // 监测 goroutine 泄漏的工具,可以直接照搬fc := funcs[ast.SHA]for _, test := range shaCases {in := types.NewDatum(test.origin)f, _ := fc.getFunction(datumsToConstants([]types.Datum{in}), s.ctx)crypt, err := f.eval(nil)c.Assert(err, IsNil)res, err := crypt.ToString()c.Assert(err, IsNil)c.Assert(res, Equals, test.crypt)}// test NULL input for shavar argNull types.Datumf, _ := fc.getFunction(datumsToConstants([]types.Datum{argNull}), s.ctx)crypt, err := f.eval(nil)c.Assert(err, IsNil)c.Assert(crypt.IsNull(), IsTrue)
}
* 注意,除了正常 case 之外,最好能添加一些异常的case,如输入值为 nil,或者是多种类型的参数

最后还需要添加类型推导信息以及 test case,参见 plan/typeinferer.goplan/typeinferer_test.go

case ast.SHA, ast.SHA1:tp = types.NewFieldType(mysql.TypeVarString)chs = v.defaultCharsettp.Flen = 40
        {`sha1(123)`, mysql.TypeVarString, "utf8"},{`sha(123)`, mysql.TypeVarString, "utf8"},

编辑按:添加 TiDB Robot 微信,加入 TiDB Contributor Club,无门槛参与开源项目,改变世界从这里开始吧(萌萌哒)。

听说现在成为 TiDB Contributor 就送限量版马克杯呦~

转载于:https://my.oschina.net/zhaiyuan/blog/859106

十分钟成为 TiDB Contributor,还送限量版马克杯相关推荐

  1. 十分钟开发物联网:智能加湿器(Wifi版)

    智能加湿器设备集成了温湿度传感器.加湿器控制单元.以及Wifi传输模块,ShineBlink万能核心板采集温湿度传感器数据,并将它们上传至机智云,然后我们就可以在远程通过手机App或者Web网页端来访 ...

  2. 十分钟成为 Contributor 系列 | 为 TiDB 重构 built-in 函数

    2019独角兽企业重金招聘Python工程师标准>>> 这是十分钟成为 TiDB Contributor 系列的第二篇文章,让大家可以无门槛参与大型开源项目,感谢社区为 TiDB 带 ...

  3. arduino esp8266_你还用Arduino?上PlatformIO开发Esp、AVR、STM32,十分钟亲测ESP8266

    简介 对单片机最早的认识是大一的时候刷到的C51单片机,那时候玩了一阵子感觉可玩性不高,后来有了解到Arduino,买了两Uno回来用Arduino开发感觉可玩性和快速开发都比C51强多了,再后来了解 ...

  4. 自学python编程免费教程-Python十分钟入门 自学python基础教程送你参考

    python十分钟入门.简介Python是一种动态解释型的编程语言.Python可以在Windows.UNIX.MAC等多种操作系统上使用,也可以在Java..NET开发平台上使用. 特点 1 Pyt ...

  5. 用计算机连续计算五道题,事业单位数量关系:数学运算-给我十分钟,还你五道题...

    [导读] 中公事业单位为帮助各位考生顺利通过事业单位招聘考试!今天为大家带来事业单位数量关系:数学运算-给我十分钟,还你五道题 . 数学运算在行测考试之中是大家"最不待见"的一种题 ...

  6. 飞机的“黑色十分钟”能被人工智能消灭吗?

    [导读]近年来,"AI的应用和落地"逐渐成了具化的关键词,它和很多事物很多行业结合在一起,形成了奇妙的"化学反应".例如,在日常生活中,AI可以推送我们喜欢的新 ...

  7. 0基础玩转CV的利器绝了,还送万元礼金,机不可失!

    世界瞬息万变,虽有颗进步的心但总跟不上节奏是一种什么体验?当高楼里又迸发出因财富自由而激动的呐喊声时,你在不分昼夜地闷头POC:当24岁程序猿辞职去环游世界时,你才懵懂地开始摸索转型AI开发:当别人正 ...

  8. 空中交警:借你一双“慧眼”,让你看透这飞机的“黑色十分钟”

    本文分享自华为云社区<[华为云 EI]飞机的"黑色十分钟"能被人工智能消灭吗?>,原文作者:HWCloudAI . 近年来,"AI的应用和落地"逐渐 ...

  9. 为机场按上一双“慧眼”消灭飞机的“黑色十分钟”

    近年来,"AI的应用和落地"逐渐成了具化的关键词,它和很多事物很多行业结合在一起,形成了奇妙的"化学反应".例如,在日常生活中,AI可以推送我们喜欢的新闻或视频 ...

最新文章

  1. 以技术面试官的经验分享毕业生和初级程序员通过面试的技巧(Java后端方向)...
  2. lighttpd防御 Slow HTTP Denial of Service Attack 解决办法
  3. COM编程之四 引用计数
  4. 均线交易策略的回测 r_使用r创建交易策略并进行回测
  5. 北京大学计算机复试分数线,2014北京大学考研复试分数线公布
  6. 的driver_Spark源码解析(三)----Driver启动、注册Application
  7. 微信表情包小程序源码-更新登录接口+增加举牌功能
  8. mysql poolsize_thread_pool_size的调整
  9. 最新android proguard下载
  10. 对象间相互调用时互相控制的几种方法
  11. java 序列化理解_Java序列化的相关认知
  12. python0309
  13. 服务器维护 灵魂兽,魔兽世界7.0新灵魂兽麋鹿捕捉方法
  14. animation-delay负值妙用,你不来了解一下吗
  15. android仿微信红包动画,Android仿微信打开红包动画(逐帧动画)
  16. OpenWrt路由开启DDNS+端口转发进行外网访问
  17. python异步读写文件_一文彻底搞懂python文件读写
  18. [2021-09-10] 【入门1】顺序结构——多行字符串的打印
  19. BIM计算-属于自己的减肥小程序
  20. 报数游戏(约瑟夫环问题)

热门文章

  1. 局部特征用于图像检索 Aggregating local features for Image Retrieval
  2. Python计算机视觉:安装
  3. 鸟哥的Linux私房菜(服务器)- 簡易 APT/YUM 伺服器設定
  4. 深度学习用于基于内容的图像检索 Deep Learning for Content-Based Image Retrieval
  5. Day 9: TextBlob——对文本进行情感分析
  6. 信息检索(IR)的评价指标介绍-准确率、召回率、F1、mAP、ROC、AUC
  7. Matlab矩阵函数
  8. 12.6 Nginx安装 12.7 默认虚拟主机 12.8 Nginx用户认证 12.9 Nginx
  9. AD域服务器卸载---WindowsServer2012R2
  10. C++ 强制类型转换(转载)