TiDB源码的ParamMarker相关用法

TiDB源码中,有个概念叫ParamMarker,代表的是prepared sql中的参数符号?及其执行阶段填充的值
ParamMarker用ExprNode来填充,即当成了表达式的值,分为两个阶段,即prepared阶段的?以及execute阶段的set = @“值”
在Parser包里,以ExprNode代表ast中的节点,以及其Accept, Restore, Format等相应方法
在表达式expression包里,对应Constant Expression, 用expression ParamMakerExpression来承载

有个概念叫ParamMarker,代表的是prepared sql中的参数符号

对的,是这个含义。一开始在 Parser 里面会被解析成 ast.ParamMarkerExpr。后面在计算的时候会被转换成 expression.ParamMarker 同时被封装进 expression.Constant 里面。到了真正需要知道具体的值的时候,会通过 expression.Constant 相关函数进一步调用解析 expression.ParamMarker, 从而得到具体的值。

在MySQL的预处理查询中,即使是在Prepare 阶段,也会构造一个完整的执行计划,去假装执行一下,Prepare阶段放入 “?” 会被解析成 ParamMarker, 假装执行的时候,会用一个空数据代替 “?”,在中间 Set 绑定参数和值,绑定的值会放到数据库的参数池里面,等你 Execute 调用时,就直接把之前Prepare生成的计划树拿过来,从参数池里面抽出你用到的参数,代替掉计划树里面的 ParamMarker,去执行。

补充一点,TiDB 在 Prepare 阶段不会根据随机参数生成一个具体的计划,只会将 prepare 文本进行解析得到 ast,然后将 ast 和一些执行必要的信息保存起来。直到 Execute 阶段,会去得到 Prepare 语句保存的内容,然后进行解析,优化,在优化和执行的过程中会按照参数具体的值进行一些操作。