limit 语句的预查询转换成 tabledual计划,生成的tabledual 计划与预期不符

tidb 版本 v4.0.11
最近在研究tidb 源码中关于sql语句转换成计划树的过程。
发现 使用普通查询:select * from student where name = ‘tom’ limit 1 offset 1;
得到的是一个 limit 计划树,下面包含selection ,projection 等子计划,这没啥问题。

那么接下来使用预查询: prepare stmt1 from “select * from student where name = $1 limit $2 offset $3”;
set @a = ‘tom’;
set @b =
execute stmt1 using @a,@b,@c
得到的结果与普通查询相同。但是构造的计划却是tabledual树。

追踪到 logical_plan_builder 的 buildSelect 方法,也就是构造select计划的地方。
继续进到 buildLimit 构造子计划的方法,发现如下

	if offset+count == 0 {
		tableDual := LogicalTableDual{RowCount: 0}.Init(b.ctx, b.getSelectOffset())
		tableDual.schema = src.Schema()
		tableDual.names = src.OutputNames()
		return tableDual, nil
	}

因为预查询的prepare阶段是不会传参的,limit,offset现在默认值为0,所以判断通过,直接创建了一个新的tabledual计划返回。
这一点有大佬能告诉一下为啥是这样的呢。我的一开始想的是返回limit计划,里面limit,offset 值是变量,只是暂时没赋值。

可以到开发者社区交流~

1 个赞

此话题已在最后回复的 1 分钟后被自动关闭。不再允许新回复。