这篇文章上次修改于 373 天前,可能其部分内容已经发生变化,如有疑问可询问作者。
初识
最初是从朋友那里听说,他有一个很厉害的朋友在一个叫 matrixone的社区贡献代码,并且社区的前景很好,这便是我对matrixone
对最初印象了.
参与
偶然间,看到了 good first issue的labels
,发现我完全有能力去解决其中一些问题,于是在朋友的建议下,带着初次参与社区的好奇与热爱,第一次开始了参与开源社区并且为之贡献代码的精力.
开始coding
很快,我选择了一个比较简单的issue
[Feature Request]: Mathematical Built-in function pi() #1821](https://github.com/matrixorigin/matrixone/issues/1821) ,为sql
实现内置的pi()
函数,这个功能从实现上来说没有任何难度,所以更方便我把重点放在学习如何把内置函数嵌入到sql
查询中,并直观的显示返回给使用者
根据https://github.com/matrixorigin/matrixone/issues/1821#issue-1161068080提到的 开发文档开发内置函数,我便开始照猫画虎的去修改样例来实现我的功能.
首先是要求具备一定的golang
语言能力,这个恰好在几个月前学过一阵子,虽然平时不怎么用,但是看代码还是能改改的,复习的话也很快就能回忆起来,这个不是难点
其次,文档介绍到
数据库中有两种函数,内置函数是数据库自带的函数,而自定义函数是用户自定义的。内置函数可以根据它们操作的数据类型进行分类,即字符串、日期和数字内置函数。
并且给出了执行开发内置函数的步骤
困难
第一步:注册功能
函数名注册
这一部分简单,只需要在 `pkg/builtin/types.go`中添加函数名即可
声明函数参数类型和返回类型。
开始有一点点复杂了, > 在 Golang 中,初始化包时会调用 init 函数。我们将 all 的功能包装`ABS()`在这个 init 函数中,因此我们不需要显式调用它。 在 `init`中,我们要按照案例的写法,根据不同函数和参数返回值的情况,去注册不同的函数 有个坑点是 > 在该目录`pkg/builtin/unary`中,创建一个新的 go 文件`abs.go`。 > > 目录下的函数`unary`只接受一个值作为输入。目录下的函数`binary`只接受两个值作为输入。其他形式的函数放在`multi`目录下。 所以,在注册时,要根据输入值的不同数目,在不同的个目录下新建文件,并且将 `extend.UnaryReturnTypes[builtin.Abs]`等改换成`extend.BinaryReturnTypes[builtin.xxx]` 确实是个不容易注意到的地方呢.
函数调用准备
重点到了,也是整个卡了我很久的地方
overload.UnaryOps[builtin.Abs] = []*overload.UnaryOp{ Typ: types.T_float32, ReturnType: types.T_float32, Fn: func(origVec *vector.Vector, proc *process.Process, _ bool) (*vector.Vector, error) { origVecCol := origVec.Col.([]float32) resultVector, err := process.Get(proc, 4*int64(len(origVecCol)), types.Type{Oid: types.T_float32, Size: 4}) // get a new types.T_float32 vector to store the result vector if err != nil { return nil, err } results := encoding.DecodeFloat32Slice(resultVector.Data) results = results[:len(origVecCol)] resultVector.Col = results nulls.Set(resultVector.Nsp, origVec.Nsp) // the new vector's nulls are the same as the original vector vector.SetCol(resultVector, abs.AbsFloat32(origVecCol, results)) // set the vector col with the return value from abs.AbsFloat32 function return resultVector, nil }, }
这个部分的文档写的非常晦涩,很难理解,于是我根据其他已经实现的内置函数的写法,推测这个部分的写法.
不过运气不是很好,因为几乎没有与我的功能相似的情况,所以没有现成的解决方案可以借鉴.
于是我开始放弃借鉴,直接点进去看上下文逻辑,看源码,然后修改,编译运行,其客户端去测试,看报错,看日志,总的来说,过程很复杂,很麻烦,但是离终点非常接近了,我可不想放弃
解决,不知道试了多少次,终于正确结果出来了,我很难忘记当时的激动和欣喜.
虽然不知道是否时最适合的写法,但是 ~能跑就行 (dog
其他步骤,编译运行什么的,都是再正常不过的逻辑了,不需要多费口舌,
merge
很快,提了pr,通过了review,终于merge进了主分支,期间我也感受到了社区的issue回复速度和pr的审查速度,大家都是很热情积极的关注并解决,整个社区看起来充满了活力.
最后,也和matrixone
社区的运营人员交流了一下对社区和这次任务的感受,感觉还是很棒的氛围,以后有机会也会继续参与社区的.
开心~~~~
没有评论