Skip to content

Commit 8210369

Browse files
committed
fix(rule): fix charset consistency check for table and columns
1 parent d513df5 commit 8210369

File tree

1 file changed

+54
-13
lines changed

1 file changed

+54
-13
lines changed

sqle/driver/mysql/rule/ai/rule_00075.go

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package ai
22

33
import (
4+
"strings"
5+
46
rulepkg "github.com/actiontech/sqle/sqle/driver/mysql/rule"
57
util "github.com/actiontech/sqle/sqle/driver/mysql/rule/ai/util"
68
driverV2 "github.com/actiontech/sqle/sqle/driver/v2"
@@ -41,40 +43,79 @@ func init() {
4143

4244
/*
4345
==== Prompt start ====
44-
In MySQL, you should check if the SQL violate the rule(SQLE00075): "In table definition, setting column-level specified charset or collation is prohibited".
46+
In MySQL, you should check if the SQL violate the rule(SQLE00075): "Compare whether the character set of the specified table and columns in the statement are consistent".
4547
You should follow the following logic:
4648
47-
1. For "create table ..." statement, check every column, if it has no charset setting and no collation setting, otherwise, add the column name to violation-list
48-
2. For "alter table ... add column ..." statement, check the column, if it has no charset setting and no collation setting, otherwise, add the column name to violation-list
49-
3. For "alter table ... modify column ..." statement, check the modified column definition, if it has no charset setting and no collation setting, otherwise, add the column name to violation-list
50-
4. For "alter table ... change column ..." statement, check the new column's definition, if it has no charset setting and no collation setting, otherwise, add the column name to violation-list
49+
1. For "create table ..." statement, check if the table's charset is consistent with each column's charset. If a column has specified charset and it's different from table's charset, add the column name to violation-list
50+
2. For "alter table ... add column ..." statement, check if the table's charset is consistent with the new column's charset. If the column has specified charset and it's different from table's charset, add the column name to violation-list
51+
3. For "alter table ... modify column ..." statement, check if the table's charset is consistent with the modified column's charset. If the column has specified charset and it's different from table's charset, add the column name to violation-list
52+
4. For "alter table ... change column ..." statement, check if the table's charset is consistent with the new column's charset. If the column has specified charset and it's different from table's charset, add the column name to violation-list
5153
5. Generate a violation message as the checking result, including column names which violate the rule, if there is any violations
5254
==== Prompt end ====
5355
*/
5456

5557
// ==== Rule code start ====
5658
func RuleSQLE00075(input *rulepkg.RuleHandlerInput) error {
5759
violateColumns := []*ast.ColumnDef{}
60+
var tableCharset string
61+
var err error
62+
5863
switch stmt := input.Node.(type) {
5964
case *ast.CreateTableStmt:
60-
//"create table ..."
65+
// Get table charset from CREATE TABLE statement
66+
if charsetOption := util.GetTableOption(stmt.Options, ast.TableOptionCharset); charsetOption != nil {
67+
tableCharset = charsetOption.StrValue
68+
} else {
69+
// If no table charset specified, get from schema default
70+
tableCharset, err = input.Ctx.GetSchemaCharacter(stmt.Table, "")
71+
if err != nil {
72+
return err
73+
}
74+
}
75+
76+
// Check each column's charset against table charset
6177
for _, col := range stmt.Cols {
62-
//if the column has "CHARSET" or "COLLATE" specified, it is violate the rule
63-
if util.IsColumnHasSpecifiedCharset(col) || util.IsColumnHasOption(col, ast.ColumnOptionCollate) {
64-
violateColumns = append(violateColumns, col)
78+
if util.IsColumnHasSpecifiedCharset(col) {
79+
columnCharset := col.Tp.Charset
80+
if !strings.EqualFold(columnCharset, tableCharset) {
81+
violateColumns = append(violateColumns, col)
82+
}
6583
}
6684
}
85+
6786
case *ast.AlterTableStmt:
87+
// Get table charset from ALTER TABLE statement
88+
tableCharset, err = input.Ctx.GetSchemaCharacter(stmt.Table, "")
89+
if err != nil {
90+
return err
91+
}
92+
93+
// Check if table charset is being changed in this ALTER statement
94+
for _, spec := range stmt.Specs {
95+
// Use the last defined table character set
96+
if spec.Tp == ast.AlterTableOption {
97+
for _, option := range spec.Options {
98+
if option.Tp == ast.TableOptionCharset {
99+
tableCharset = option.StrValue
100+
break
101+
}
102+
}
103+
}
104+
}
105+
106+
// Check columns in ALTER TABLE commands
68107
for _, spec := range util.GetAlterTableCommandsByTypes(stmt, ast.AlterTableAddColumns, ast.AlterTableChangeColumn, ast.AlterTableModifyColumn) {
69-
// "alter table ... add column ..." or "alter table ... modify column ..." or "alter table ... change column ..."
70108
for _, col := range spec.NewColumns {
71-
//if the column has "CHARSET" or "COLLATE" specified, it is violate the rule
72-
if util.IsColumnHasSpecifiedCharset(col) || util.IsColumnHasOption(col, ast.ColumnOptionCollate) {
73-
violateColumns = append(violateColumns, col)
109+
if util.IsColumnHasSpecifiedCharset(col) {
110+
columnCharset := col.Tp.Charset
111+
if !strings.EqualFold(columnCharset, tableCharset) {
112+
violateColumns = append(violateColumns, col)
113+
}
74114
}
75115
}
76116
}
77117
}
118+
78119
if len(violateColumns) > 0 {
79120
rulepkg.AddResult(input.Res, input.Rule, SQLE00075, util.JoinColumnNames(violateColumns))
80121
}

0 commit comments

Comments
 (0)