Skip to content

Commit 8e8cbcc

Browse files
authored
Merge pull request #3231 from actiontech/fix-rule/quotation
fix: incorrect triggering of rule : Chinese full-width quotes are not recommended in DDL
2 parents 7b17e50 + ee7164d commit 8e8cbcc

2 files changed

Lines changed: 62 additions & 11 deletions

File tree

sqle/driver/mysql/audit_test.go

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5342,18 +5342,66 @@ func TestDMLCheckSpacesAroundTheString(t *testing.T) {
53425342
}
53435343

53445344
func TestDDLCheckFullWidthQuotationMarks(t *testing.T) {
5345-
for _, sql := range []string{
5346-
`alter table exist_tb_1 add column a int comment '”a“'`,
5347-
`create table t (id int comment '”aaa“')`,
5348-
//TODO `alter table exist_tb_1 add column a int comment '‘'`,
5349-
//TODO `create table t (id int comment '’')`,
5345+
// 全角双引号 “ ”(Unicode U+201C / U+201D)。下面 SQL 用反引号引用标识符,无法用反引号包裹整段 Go raw string,故用变量 + fmt.Sprintf 拼接。
5346+
lq, rq := "“", "”"
5347+
rule := rulepkg.RuleHandlerMap[rulepkg.DDLCheckFullWidthQuotationMarks].Rule
5348+
expectViolation := newTestResult().addResult(rulepkg.DDLCheckFullWidthQuotationMarks)
5349+
expectClean := newTestResult()
5350+
5351+
// Should trigger: full-width quotation marks appear in identifier names
5352+
for _, tc := range []struct {
5353+
name string
5354+
sql string
5355+
}{
5356+
{"trigger_create_table_table_name", fmt.Sprintf("CREATE TABLE `%st1%s` (id int)", lq, rq)},
5357+
{"trigger_create_table_column_name", fmt.Sprintf("CREATE TABLE t (`%scol1%s` int)", lq, rq)},
5358+
{"trigger_create_table_column_name_mid", fmt.Sprintf("CREATE TABLE t (`col%smid%sx` int)", lq, rq)},
5359+
{"trigger_create_table_table_name_mid", fmt.Sprintf("CREATE TABLE `t%smid%ssuf` (id int)", lq, rq)},
5360+
{"trigger_create_table_inline_index_name", fmt.Sprintf("CREATE TABLE t (id int, INDEX `%sidx1%s` (id))", lq, rq)},
5361+
{"trigger_alter_add_column_name", fmt.Sprintf("ALTER TABLE exist_tb_1 ADD COLUMN `%scol1%s` int", lq, rq)},
5362+
{"trigger_alter_add_column_name_mid", fmt.Sprintf("ALTER TABLE exist_tb_1 ADD COLUMN `a%sb%s` int", lq, rq)},
5363+
{"trigger_alter_change_column_rename", fmt.Sprintf("ALTER TABLE exist_tb_1 CHANGE COLUMN v1 `%sv1_new%s` varchar(255)", lq, rq)},
5364+
{"trigger_alter_rename_table", fmt.Sprintf("ALTER TABLE exist_tb_1 RENAME TO `%st2%s`", lq, rq)},
5365+
{"trigger_alter_add_index_name", fmt.Sprintf("ALTER TABLE exist_tb_1 ADD INDEX `%sidx_new%s` (v1)", lq, rq)},
5366+
{"trigger_create_index_name", fmt.Sprintf("CREATE INDEX `%sidx1%s` ON exist_tb_1 (v1)", lq, rq)},
53505367
} {
5351-
runSingleRuleInspectCase(rulepkg.RuleHandlerMap[rulepkg.DDLCheckFullWidthQuotationMarks].Rule, t, "", DefaultMysqlInspect(), sql, newTestResult().addResult(rulepkg.DDLCheckFullWidthQuotationMarks))
5368+
tc := tc
5369+
t.Run(tc.name, func(t *testing.T) {
5370+
runSingleRuleInspectCase(rule, t, tc.name, DefaultMysqlInspect(), tc.sql, expectViolation)
5371+
})
53525372
}
53535373

5354-
runSingleRuleInspectCase(rulepkg.RuleHandlerMap[rulepkg.DDLCheckFullWidthQuotationMarks].Rule, t, "success", DefaultMysqlInspect(),
5355-
`select "1"`,
5356-
newTestResult())
5374+
// Should NOT trigger: identifiers are normal; full-width marks appear only in COMMENT values (if at all).
5375+
// This group directly verifies the reported false-positive bug: COMMENT content must be ignored.
5376+
// MySQL accepts both single-quoted ('') and double-quoted ("") string literals for COMMENT values,
5377+
// so we test both forms.
5378+
for _, tc := range []struct {
5379+
name string
5380+
sql string
5381+
}{
5382+
{"no_trigger_alter_column_comment_single_quote", fmt.Sprintf("alter table exist_tb_1 add column a int comment '%sa%s'", lq, rq)},
5383+
{"no_trigger_create_column_comment_single_quote", fmt.Sprintf("create table t (id int comment '%saaa%s')", lq, rq)},
5384+
{"no_trigger_create_table_comment_single_quote", fmt.Sprintf("create table t (id int) comment '%stable comment%s'", lq, rq)},
5385+
{"no_trigger_create_index_comment_single_quote", fmt.Sprintf("create index idx1 on exist_tb_1 (v1) comment '%sidx comment%s'", lq, rq)},
5386+
{"no_trigger_alter_column_comment_double_quote", fmt.Sprintf(`alter table exist_tb_1 add column a int comment "%sa%s"`, lq, rq)},
5387+
{"no_trigger_create_column_comment_double_quote", fmt.Sprintf(`create table t (id int comment "%saaa%s")`, lq, rq)},
5388+
{"no_trigger_create_table_comment_double_quote", fmt.Sprintf(`create table t (id int) comment "%stable comment%s"`, lq, rq)},
5389+
{"no_trigger_create_index_comment_double_quote", fmt.Sprintf(`create index idx1 on exist_tb_1 (v1) comment "%sidx comment%s"`, lq, rq)},
5390+
{"no_trigger_create_table_ascii_comment", `create table t (id int comment 'normal comment')`},
5391+
{"no_trigger_alter_ascii_comment", `alter table exist_tb_1 add column a int comment 'some normal comment'`},
5392+
{"no_trigger_create_table_no_comment", `create table t (id int)`},
5393+
} {
5394+
tc := tc
5395+
t.Run(tc.name, func(t *testing.T) {
5396+
runSingleRuleInspectCase(rule, t, tc.name, DefaultMysqlInspect(), tc.sql, expectClean)
5397+
})
5398+
}
5399+
5400+
t.Run("no_trigger_select_non_ddl", func(t *testing.T) {
5401+
runSingleRuleInspectCase(rule, t, "no_trigger_select_non_ddl", DefaultMysqlInspect(),
5402+
`select "1"`,
5403+
expectClean)
5404+
})
53575405
}
53585406

53595407
func TestDMLNotRecommendOrderByRand(t *testing.T) {

sqle/driver/mysql/rule/rule.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3734,8 +3734,11 @@ func (g *checkSpacesAroundTheStringVisitor) Leave(n ast.Node) (node ast.Node, ok
37343734
func checkFullWidthQuotationMarks(input *RuleHandlerInput) error {
37353735
switch input.Node.(type) {
37363736
case ast.DDLNode:
3737-
if strings.Contains(input.Node.Text(), "“") {
3738-
addResult(input.Res, input.Rule, input.Rule.Name)
3737+
for _, name := range getObjectNames(input.Node) {
3738+
if strings.ContainsAny(name, `“”`) { // “” are the full-width double quotation marks (U+201C and U+201D)
3739+
addResult(input.Res, input.Rule, input.Rule.Name)
3740+
return nil
3741+
}
37393742
}
37403743
}
37413744
return nil

0 commit comments

Comments
 (0)