"Fix table prefix issue in WHERE clause and ensure compatibility" #182
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
What did this pull request do? [english]
This pull request fixes an issue where the sharding plugin fails to handle QualifiedRef (e.g., table aliases) in SQL WHERE clauses.
The problem occurs because the plugin does not properly recognize or replace the original table alias in WHERE conditions after sharding logic is applied.
This PR introduces logic to handle QualifiedRef in conditions, ensuring correct functionality for queries involving table aliases.
Problem Background
Recently, when using GORM's gen framework to generate code, I noticed that the generated queries and code often add table prefixes to fields. While the gen framework claims to be 100% compatible with GORM plugins, in practice, some issues arise.
A previous pull request partially resolved the problem of recognizing sharding keys with table prefixes. However, it did not include specific logic to modify the WHERE clause. This pull request addresses that gap.
Additionally, I came across discussions in the gen framework's issue tracker regarding incompatibilities between generated code and the sharding plugin. However, no concrete or feasible solutions have been proposed so far. This pull request aims to resolve the issue comprehensively.
Code Changes Overview
The changes in the code primarily address the issue where the sharding plugin failed to handle SQL WHERE clauses with table aliases or prefixes. Specifically, the following modifications were made:
Update Table References in WHERE Clauses
Introduced a helper function replaceTablePrefixInWhere to recursively traverse and replace table prefixes in conditions.
Handles different SQL expression types like BinaryExpr, ParenExpr, and QualifiedRef.
Ensures that any references to the original table are updated to the new sharded table name.
这个 pull request 是做什么的?[中文]
此pr修复了分片插件无法处理 SQL WHERE 子句中的 QualifiedRef(例如,表别名)的问题。
出现此问题的原因是,在应用分片逻辑后,插件没有替换 WHERE 条件中的原始表别名。
此 PR 引入了在条件中处理 QualifiedRef 的逻辑,从而确保涉及表别名的查询具有正确的功能。
问题背景
最近,在使用 GORM 的 gen 框架生成代码时,我注意到生成的查询sql会给where条件字段添加表前缀,例如:SELECT * FROM user_tab WHERE user_tab.username = ?。虽然 gen 框架官网提到,gen 和 GORM 插件 100% 兼容,但在分片中还是有一些问题。之前的一个pr解决了识别带有表前缀的分片键的识别问题。但是没有修改resolve的逻辑,也就是没有修改具体的sql改写逻辑。此外,我在 gen 框架的issue中看到了关于生成代码和 sharding 插件之间不兼容的讨论"go-gorm/gen#1015" 。然而,到目前为止还没有看到具体可行的解决方案。此pr正是为了解决此问题。
代码变更概述
代码中的更改主要解决了分片插件无法处理带有表别名或前缀的 SQL WHERE 子句的问题。具体来说,进行了以下修改:
1.在resolve函数处理了更新 WHERE 子句中的表引用的逻辑代码
2.引入了一个辅助函数 replaceTablePrefixInWhere。用于递归遍历和替换条件中的表前缀,处理不同的 SQL 表达式类型,如 BinaryExpr、ParenExpr 和 QualifiedRef。
最终确保对原始表的任何引用都更新为新的分片表名称。
usecase
原sql: SELECT * FROM t_user WHERE
t_user
.username
= ? ANDt_user
.del_flag
= ?"ending sql : SELECT * FROM t_user_7 WHERE
t_user_7
.username
= ? ANDt_user_7
.del_flag
= ?"sharding test 原sharding.go单元测试
一个简略的单元测试 仅检测replace函数对where部分的替换
=== RUN TestReplaceTablePrefixInWhere
--- PASS: TestReplaceTablePrefixInWhere (0.00s)
=== RUN TestReplaceTablePrefixInWhere/Simple_WHERE_condition_with_table_prefix
--- PASS: TestReplaceTablePrefixInWhere/Simple_WHERE_condition_with_table_prefix (0.00s)
=== RUN TestReplaceTablePrefixInWhere/Complex_WHERE_condition_with_multiple_table_prefixes
--- PASS: TestReplaceTablePrefixInWhere/Complex_WHERE_condition_with_multiple_table_prefixes (0.00s)
=== RUN TestReplaceTablePrefixInWhere/WHERE_condition_with_parentheses
--- PASS: TestReplaceTablePrefixInWhere/WHERE_condition_with_parentheses (0.00s)
=== RUN TestReplaceTablePrefixInWhere/No_table_prefix_in_WHERE_condition
--- PASS: TestReplaceTablePrefixInWhere/No_table_prefix_in_WHERE_condition (0.00s)
=== RUN TestReplaceTablePrefixInWhere/Nested_parentheses_with_multiple_table_prefixes
--- PASS: TestReplaceTablePrefixInWhere/Nested_parentheses_with_multiple_table_prefixes (0.00s)
=== RUN TestReplaceTablePrefixInWhere/OR_conditions_without_table_prefix
--- PASS: TestReplaceTablePrefixInWhere/OR_conditions_without_table_prefix (0.00s)
=== RUN TestReplaceTablePrefixInWhere/Field_comparison_between_two_tables
--- PASS: TestReplaceTablePrefixInWhere/Field_comparison_between_two_tables (0.00s)
=== RUN TestReplaceTablePrefixInWhere/IN_clause_with_table_prefix
--- PASS: TestReplaceTablePrefixInWhere/IN_clause_with_table_prefix (0.00s)
PASS
In The End
"I am still a student, and this is my first pull request. If there are any irregularities or mistakes, I kindly ask for your understanding and feedback!"
我还是一位在校学生,这是我的第一次pr,如果有不规范和错误之处还请谅解和提出!