如何在每一条SQL前加一个统一的注释 #2200

Open
opened 2022-12-01 08:50:24 +00:00 by ssfyn · 3 comments

比如proxysql之类一些mysql中间件对外只提供一个服务,中间件自己去处理读写分离。但当业务需要指定访问主库时需要在查询的前面增加一段注释,如/*master*/ SELECT * FROM xxx,现在通过SQL的方式可以手动拼,但是通过Find/Get之类的好像没有一个很好的办法,如果使用Hook.BeforeProcess处理,好像在处理Prepare的时候会有问题

比如proxysql之类一些mysql中间件对外只提供一个服务,中间件自己去处理读写分离。但当业务需要指定访问主库时需要在查询的前面增加一段注释,如`/*master*/ SELECT * FROM xxx`,现在通过SQL的方式可以手动拼,但是通过Find/Get之类的好像没有一个很好的办法,如果使用Hook.BeforeProcess处理,好像在处理Prepare的时候会有问题
Author
https://help.aliyun.com/document_detail/477438.html 比如这个
lunny added the
kind
proposal
label 2023-01-30 02:08:49 +00:00
Contributor

我们也正好碰到这个问题,需要在 SQL 执行之前对 SQL 改写(修改表名),让不同的租户执行不同的表;或者就是类似你想的,添加一个注释在最前面,然后让 proxy 去解析,解析完成之后进行处理。

然后,我们尝试了很多方式当下均无法实现,比如你说的使用 ContextHook,但是 ContextHook 中的 SQL 并不是最终执行的 SQL,它仅仅只是 query 的一个复制而已。我们也尝试包装了一个新的 Dialect 去替换已有的 mysql 的 Dialect,并且添加自定义的 Filters 方法来返回过滤器来过滤 SQL,这个方法可以解析并改写 SQL,但问题是,Filter 的 接口是 Do(sql string) string 无法获取到 context 也就是说无法获取到具体的用户信息(租户id),也就无法对它传递信息。

所以,现在我们的解决方案是,修改源码中的 Filter 接口,对于 Do(sql string) string 添加 context 参数,将当前 session 的 context 传递进来,获取对应信息进行改写。不过,我们并不确定这个方案是否完美覆盖到所有场景,至少现在测试下来没有问题,SQL 可以被成功改写。

@ssfyn 对于你的问题,或许,可能不需要像我们一样改写源码,只需要通过 Filter 识别到所需要查询主库的对应 SQL 加注释就可以了。

@lunny 你觉得对于 FilterDo 接口添加 context 是否为一种比较好的解决方案,如果可行,我可以提交一个 PR。或者说让 ContextHook 中的 sql 替换最终执行的 sql 更加友好呢?

我们也正好碰到这个问题,需要在 SQL 执行之前对 SQL 改写(修改表名),让不同的租户执行不同的表;或者就是类似你想的,添加一个注释在最前面,然后让 proxy 去解析,解析完成之后进行处理。 然后,我们尝试了很多方式当下均无法实现,比如你说的使用 `ContextHook`,但是 `ContextHook` 中的 SQL 并不是最终执行的 SQL,它仅仅只是 `query` 的一个复制而已。我们也尝试包装了一个新的 `Dialect` 去替换已有的 mysql 的 `Dialect`,并且添加自定义的 `Filters` 方法来返回过滤器来过滤 SQL,这个方法可以解析并改写 SQL,但问题是,Filter 的 接口是 `Do(sql string) string` 无法获取到 context 也就是说无法获取到具体的用户信息(租户id),也就无法对它传递信息。 所以,现在我们的解决方案是,修改源码中的 Filter 接口,对于 `Do(sql string) string` 添加 context 参数,将当前 session 的 context 传递进来,获取对应信息进行改写。不过,我们并不确定这个方案是否完美覆盖到所有场景,至少现在测试下来没有问题,SQL 可以被成功改写。 @ssfyn 对于你的问题,或许,可能不需要像我们一样改写源码,只需要通过 Filter 识别到所需要查询主库的对应 SQL 加注释就可以了。 @lunny 你觉得对于 `Filter` 的 `Do` 接口添加 context 是否为一种比较好的解决方案,如果可行,我可以提交一个 PR。或者说让 ContextHook 中的 sql 替换最终执行的 sql 更加友好呢?
Owner

Filter 可以支持 context

Filter 可以支持 context
Sign in to join this conversation.
No Milestone
No Assignees
3 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: xorm/xorm#2200
No description provided.