提交 14c19f4d 编写于 作者: martianzhang's avatar martianzhang

fix tokenize bug with multi type of quote

  UPDATE xxx SET c1=' LOGGER.error(""); }' WHERE id = 2 ;
上级 b3333067
...@@ -22,3 +22,5 @@ orignal: 'hello 'world' ...@@ -22,3 +22,5 @@ orignal: 'hello 'world'
quoted: 'hello ' quoted: 'hello '
orignal: "hello "world" orignal: "hello "world"
quoted: "hello " quoted: "hello "
orignal: ' LOGGER.error(""); }'
quoted: ' LOGGER.error(""); }'
...@@ -38,12 +38,13 @@ tb; ...@@ -38,12 +38,13 @@ tb;
-- comment -- comment
19 INSERT /*+ SET_VAR(foreign_key_checks=OFF) */ INTO t2 VALUES(2); 19 INSERT /*+ SET_VAR(foreign_key_checks=OFF) */ INTO t2 VALUES(2);
20 select /*!50000 1,*/ 1; 20 select /*!50000 1,*/ 1;
0 select * from test\Ghello 21 UPDATE xxx SET c1=' LOGGER.error(""); }' WHERE id = 2 ;
1 select 'hello\Gworld', col from test\Ghello 0 select * from test\G
1 select 'hello\Gworld', col from test\G
2 -- select * from test\Ghello 2 -- select * from test\Ghello
3 #select * from test\Ghello 3 #select * from test\Ghello
4 select * /*comment*/from test\Ghello 4 select * /*comment*/from test\G
5 select * /*comment;*/from test\Ghello 5 select * /*comment;*/from test\G
6 select * /*comment 6 select * /*comment
\\G*/ \\G*/
from test\\Ghello from test\\G
...@@ -210,7 +210,7 @@ ...@@ -210,7 +210,7 @@
} }
[]ast.Token{ []ast.Token{
{Type:57348, Val:"select", i:0}, {Type:57348, Val:"select", i:0},
{Type:57590, Val:"sql_calc_found_rows", i:0}, {Type:57592, Val:"sql_calc_found_rows", i:0},
{Type:57396, Val:"col", i:0}, {Type:57396, Val:"col", i:0},
{Type:57353, Val:"from", i:0}, {Type:57353, Val:"from", i:0},
{Type:57396, Val:"tbl", i:0}, {Type:57396, Val:"tbl", i:0},
...@@ -279,3 +279,16 @@ ...@@ -279,3 +279,16 @@
{Type:57396, Val:"film_id", i:0}, {Type:57396, Val:"film_id", i:0},
{Type:57346, Val:");", i:0}, {Type:57346, Val:");", i:0},
} }
[]ast.Token{
{Type:57351, Val:"update", i:0},
{Type:57396, Val:"xxx", i:0},
{Type:57372, Val:"set", i:0},
{Type:57396, Val:"c1", i:0},
{Type:61, Val:"=", i:0},
{Type:57398, Val:" LOGGER.error(\"\"); }", i:0},
{Type:57354, Val:"where", i:0},
{Type:57396, Val:"id", i:0},
{Type:61, Val:"=", i:0},
{Type:57399, Val:"2", i:0},
{Type:59, Val:";", i:0},
}
...@@ -928,13 +928,18 @@ func SplitStatement(buf []byte, delimiter []byte) (string, string, []byte) { ...@@ -928,13 +928,18 @@ func SplitStatement(buf []byte, delimiter []byte) (string, string, []byte) {
} }
// quoted string // quoted string
if b == '`' || b == '\'' || b == '"' { switch b {
case '`', '\'', '"':
if i > 1 && buf[i-1] != '\\' { if i > 1 && buf[i-1] != '\\' {
if quoted && b == quoteRune { if quoted && b == quoteRune {
quoted = false quoted = false
quoteRune = '0'
} else { } else {
quoted = true // check if first time found quote
quoteRune = b if quoteRune == 0 {
quoted = true
quoteRune = b
}
} }
} }
} }
......
...@@ -51,6 +51,7 @@ func TestTokenizer(t *testing.T) { ...@@ -51,6 +51,7 @@ func TestTokenizer(t *testing.T) {
"SELECT * FROM tb WHERE id is not null;", "SELECT * FROM tb WHERE id is not null;",
"SELECT * FROM tb WHERE id between 1 and 3;", "SELECT * FROM tb WHERE id between 1 and 3;",
"alter table inventory add index idx_store_film` (`store_id`,`film_id`);", "alter table inventory add index idx_store_film` (`store_id`,`film_id`);",
`UPDATE xxx SET c1=' LOGGER.error(""); }' WHERE id = 2 ;`,
} }
err := common.GoldenDiff(func() { err := common.GoldenDiff(func() {
for _, sql := range sqls { for _, sql := range sqls {
...@@ -78,6 +79,7 @@ func TestGetQuotedString(t *testing.T) { ...@@ -78,6 +79,7 @@ func TestGetQuotedString(t *testing.T) {
"``", "``",
`'hello 'world'`, `'hello 'world'`,
`"hello "world"`, `"hello "world"`,
`' LOGGER.error(""); }'`,
} }
err := common.GoldenDiff(func() { err := common.GoldenDiff(func() {
for _, s := range str { for _, s := range str {
...@@ -121,72 +123,75 @@ func TestFormat(t *testing.T) { ...@@ -121,72 +123,75 @@ func TestFormat(t *testing.T) {
func TestSplitStatement(t *testing.T) { func TestSplitStatement(t *testing.T) {
common.Log.Debug("Entering function: %s", common.GetFunctionName()) common.Log.Debug("Entering function: %s", common.GetFunctionName())
bufs := [][]byte{ bufs := [][]byte{
[]byte("select * from test;hello"), []byte("select * from test;hello"), // 0
[]byte("select 'asd;fas', col from test;hello"), []byte("select 'asd;fas', col from test;hello"), // 1
[]byte("-- select * from test;hello"), []byte("-- select * from test;hello"), // 2
[]byte("#select * from test;hello"), []byte("#select * from test;hello"), // 3
[]byte("select * /*comment*/from test;hello"), []byte("select * /*comment*/from test;hello"), // 4
[]byte("select * /*comment;*/from test;hello"), []byte("select * /*comment;*/from test;hello"), // 5
[]byte(`select * /*comment []byte(`select * /*comment
;*/ ;*/
from test;hello`), from test;hello`), // 6
[]byte(`select * from test`), []byte(`select * from test`), // 7
// https://github.com/XiaoMi/soar/issues/66 // https://github.com/XiaoMi/soar/issues/66
[]byte(`/*comment*/`), []byte(`/*comment*/`), // 8
[]byte(`/*comment*/;`), []byte(`/*comment*/;`), // 9
[]byte(`--`), []byte(`--`), // 10
[]byte(`-- comment`), []byte(`-- comment`), // 11
[]byte(`# comment`), []byte(`# comment`), // 12
// https://github.com/XiaoMi/soar/issues/116 // https://github.com/XiaoMi/soar/issues/116
[]byte(`select []byte(`select
* *
-- comment -- comment
from tb from tb
where col = 1`), where col = 1`), // 13
[]byte(`select []byte(`select
* -- * --
from tb from tb
where col = 1`), where col = 1`), // 14
[]byte(`select []byte(`select
* # * #
from tb from tb
where col = 1`), where col = 1`), // 15
[]byte(`select []byte(`select
* *
-- --
from tb from tb
where col = 1`), where col = 1`), // 16
[]byte(`select * from []byte(`select * from
-- comment -- comment
tb; tb;
select col from tb where col = 1;`), select col from tb where col = 1;`), // 17
// https://github.com/XiaoMi/soar/issues/120 // https://github.com/XiaoMi/soar/issues/120
[]byte(` []byte(`
-- comment -- comment
select col from tb; select col from tb;
select col from tb; select col from tb;
`), `), // 18
[]byte(`INSERT /*+ SET_VAR(foreign_key_checks=OFF) */ INTO t2 VALUES(2);`), []byte(`INSERT /*+ SET_VAR(foreign_key_checks=OFF) */ INTO t2 VALUES(2);`), // 19
[]byte(`select /*!50000 1,*/ 1;`), []byte(`select /*!50000 1,*/ 1;`), // 20
[]byte(`UPDATE xxx SET c1=' LOGGER.error(""); }' WHERE id = 2 ;`), // 21
} }
// \G 分隔符
buf2s := [][]byte{ buf2s := [][]byte{
[]byte("select * from test\\Ghello"), []byte("select * from test\\Ghello"), // 0
[]byte("select 'hello\\Gworld', col from test\\Ghello"), []byte("select 'hello\\Gworld', col from test\\Ghello"), // 1
[]byte("-- select * from test\\Ghello"), []byte("-- select * from test\\Ghello"), // 2
[]byte("#select * from test\\Ghello"), []byte("#select * from test\\Ghello"), // 3
[]byte("select * /*comment*/from test\\Ghello"), []byte("select * /*comment*/from test\\Ghello"), // 4
[]byte("select * /*comment;*/from test\\Ghello"), []byte("select * /*comment;*/from test\\Ghello"), // 5
[]byte(`select * /*comment []byte(`select * /*comment
\\G*/ \\G*/
from test\\Ghello`), from test\\Ghello`), // 6
} }
err := common.GoldenDiff(func() { err := common.GoldenDiff(func() {
for i, buf := range bufs { for i, buf := range bufs {
sql, _, _ := SplitStatement(buf, []byte(common.Config.Delimiter)) sql, _, _ := SplitStatement(buf, []byte(";"))
fmt.Println(i, sql) fmt.Println(i, sql)
} }
for i, buf := range buf2s { for i, buf := range buf2s {
sql, _, _ := SplitStatement(buf, []byte(common.Config.Delimiter)) sql, _, _ := SplitStatement(buf, []byte("\\G"))
fmt.Println(i, sql) fmt.Println(i, sql)
} }
}, t.Name(), update) }, t.Name(), update)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册