token_test.go 8.2 KB
Newer Older
martianzhang's avatar
martianzhang 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
/*
 * Copyright 2018 Xiaomi, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package ast

import (
	"fmt"
	"testing"

	"github.com/XiaoMi/soar/common"

	"github.com/kr/pretty"
)

martianzhang's avatar
martianzhang 已提交
28
func TestTokenize(t *testing.T) {
martianzhang's avatar
martianzhang 已提交
29
	common.Log.Debug("Entering function: %s", common.GetFunctionName())
martianzhang's avatar
martianzhang 已提交
30 31 32 33 34 35 36 37 38
	err := common.GoldenDiff(func() {
		for _, sql := range common.TestSQLs {
			fmt.Println(sql)
			fmt.Println(Tokenize(sql))
		}
	}, t.Name(), update)
	if nil != err {
		t.Fatal(err)
	}
martianzhang's avatar
martianzhang 已提交
39
	common.Log.Debug("Exiting function: %s", common.GetFunctionName())
martianzhang's avatar
martianzhang 已提交
40 41 42
}

func TestTokenizer(t *testing.T) {
martianzhang's avatar
martianzhang 已提交
43
	common.Log.Debug("Entering function: %s", common.GetFunctionName())
martianzhang's avatar
martianzhang 已提交
44 45 46 47 48 49 50 51 52 53
	sqls := []string{
		"select c1,c2,c3 from t1,t2 join t3 on t1.c1=t2.c1 and t1.c3=t3.c1 where id>1000",
		"select sourcetable, if(f.lastcontent = ?, f.lastupdate, f.lastcontent) as lastactivity, f.totalcount as activity, type.class as type, (f.nodeoptions & ?) as nounsubscribe from node as f inner join contenttype as type on type.contenttypeid = f.contenttypeid inner join subscribed as sd on sd.did = f.nodeid and sd.userid = ? union all select f.name as title, f.userid as keyval, ? as sourcetable, ifnull(f.lastpost, f.joindate) as lastactivity, f.posts as activity, ? as type, ? as nounsubscribe from user as f inner join userlist as ul on ul.relationid = f.userid and ul.userid = ? where ul.type = ? and ul.aq = ? order by title limit ?",
		"select c1 from t1 where id>=1000", // test ">="
		"select SQL_CALC_FOUND_ROWS col from tbl where id>1000",
		"SELECT * FROM tb WHERE id=?;",
		"SELECT * FROM tb WHERE id is null;",
		"SELECT * FROM tb WHERE id is not null;",
		"SELECT * FROM tb WHERE id between 1 and 3;",
		"alter table inventory add index idx_store_film` (`store_id`,`film_id`);",
54
		`UPDATE xxx SET c1=' LOGGER.error(""); }' WHERE id = 2 ;`,
martianzhang's avatar
martianzhang 已提交
55
		`update tb set status = 1 where id = 1;`, // SQL 中包含 non-broken-space
martianzhang's avatar
martianzhang 已提交
56
	}
martianzhang's avatar
martianzhang 已提交
57 58 59 60 61 62 63
	err := common.GoldenDiff(func() {
		for _, sql := range sqls {
			pretty.Println(Tokenizer(sql))
		}
	}, t.Name(), update)
	if nil != err {
		t.Fatal(err)
martianzhang's avatar
martianzhang 已提交
64
	}
martianzhang's avatar
martianzhang 已提交
65
	common.Log.Debug("Exiting function: %s", common.GetFunctionName())
martianzhang's avatar
martianzhang 已提交
66 67 68
}

func TestGetQuotedString(t *testing.T) {
martianzhang's avatar
martianzhang 已提交
69
	common.Log.Debug("Entering function: %s", common.GetFunctionName())
martianzhang's avatar
martianzhang 已提交
70 71 72 73 74 75 76 77 78 79 80 81 82
	var str = []string{
		`"hello world"`,
		"`hello world`",
		`'hello world'`,
		"hello world",
		`'hello \'world'`,
		`"hello \"wor\"ld"`,
		`"hello \"world"`,
		`""`,
		`''`,
		"``",
		`'hello 'world'`,
		`"hello "world"`,
83
		`' LOGGER.error(""); }'`,
martianzhang's avatar
martianzhang 已提交
84
	}
martianzhang's avatar
martianzhang 已提交
85 86 87 88 89 90 91
	err := common.GoldenDiff(func() {
		for _, s := range str {
			fmt.Printf("orignal: %s\nquoted: %s\n", s, getQuotedString(s))
		}
	}, t.Name(), update)
	if nil != err {
		t.Fatal(err)
martianzhang's avatar
martianzhang 已提交
92
	}
martianzhang's avatar
martianzhang 已提交
93
	common.Log.Debug("Exiting function: %s", common.GetFunctionName())
martianzhang's avatar
martianzhang 已提交
94 95 96
}

func TestCompress(t *testing.T) {
martianzhang's avatar
martianzhang 已提交
97
	common.Log.Debug("Entering function: %s", common.GetFunctionName())
martianzhang's avatar
martianzhang 已提交
98 99 100 101 102 103 104 105
	err := common.GoldenDiff(func() {
		for _, sql := range common.TestSQLs {
			fmt.Println(sql)
			fmt.Println(Compress(sql))
		}
	}, t.Name(), update)
	if nil != err {
		t.Fatal(err)
martianzhang's avatar
martianzhang 已提交
106
	}
martianzhang's avatar
martianzhang 已提交
107
	common.Log.Debug("Exiting function: %s", common.GetFunctionName())
martianzhang's avatar
martianzhang 已提交
108 109 110
}

func TestFormat(t *testing.T) {
martianzhang's avatar
martianzhang 已提交
111
	common.Log.Debug("Entering function: %s", common.GetFunctionName())
martianzhang's avatar
martianzhang 已提交
112 113 114 115 116 117 118 119
	err := common.GoldenDiff(func() {
		for _, sql := range common.TestSQLs {
			fmt.Println(sql)
			fmt.Println(format(sql))
		}
	}, t.Name(), update)
	if nil != err {
		t.Fatal(err)
martianzhang's avatar
martianzhang 已提交
120
	}
martianzhang's avatar
martianzhang 已提交
121
	common.Log.Debug("Exiting function: %s", common.GetFunctionName())
martianzhang's avatar
martianzhang 已提交
122 123 124
}

func TestSplitStatement(t *testing.T) {
martianzhang's avatar
martianzhang 已提交
125
	common.Log.Debug("Entering function: %s", common.GetFunctionName())
martianzhang's avatar
martianzhang 已提交
126
	bufs := [][]byte{
127 128 129 130 131 132
		[]byte("select * from test;hello"),              // 0
		[]byte("select 'asd;fas', col from test;hello"), // 1
		[]byte("-- select * from test;hello"),           // 2
		[]byte("#select * from test;hello"),             // 3
		[]byte("select * /*comment*/from test;hello"),   // 4
		[]byte("select * /*comment;*/from test;hello"),  // 5
martianzhang's avatar
martianzhang 已提交
133
		[]byte(`select * /*comment
martianzhang's avatar
martianzhang 已提交
134
		;*/
135 136
		from test;hello`), // 6
		[]byte(`select * from test`), // 7
martianzhang's avatar
martianzhang 已提交
137
		// https://github.com/XiaoMi/soar/issues/66
138 139 140 141 142
		[]byte(`/*comment*/`),  // 8
		[]byte(`/*comment*/;`), // 9
		[]byte(`--`),           // 10
		[]byte(`-- comment`),   // 11
		[]byte(`# comment`),    // 12
martianzhang's avatar
martianzhang 已提交
143
		// https://github.com/XiaoMi/soar/issues/116
martianzhang's avatar
martianzhang 已提交
144 145 146 147
		[]byte(`select
*
-- comment
from tb
148
where col = 1`), // 13
martianzhang's avatar
martianzhang 已提交
149 150 151
		[]byte(`select
* --
from tb
152
where col = 1`), // 14
martianzhang's avatar
martianzhang 已提交
153 154 155
		[]byte(`select
* #
from tb
156
where col = 1`), // 15
martianzhang's avatar
martianzhang 已提交
157 158 159 160
		[]byte(`select
*
--
from tb
161
where col = 1`), // 16
martianzhang's avatar
martianzhang 已提交
162 163 164
		[]byte(`select * from
-- comment
tb;
165
select col from tb where col = 1;`), // 17
martianzhang's avatar
martianzhang 已提交
166 167 168 169 170
		// https://github.com/XiaoMi/soar/issues/120
		[]byte(`
-- comment
select col from tb;
select col from tb;
171 172 173 174
`), // 18
		[]byte(`INSERT /*+ SET_VAR(foreign_key_checks=OFF) */ INTO t2 VALUES(2);`), // 19
		[]byte(`select /*!50000 1,*/ 1;`),                                          // 20
		[]byte(`UPDATE xxx SET c1=' LOGGER.error(""); }' WHERE id = 2 ;`),          // 21
martianzhang's avatar
martianzhang 已提交
175
		[]byte("UPDATE `xxx` SET aaa='a;' WHERE `id` = 15;"),                       // 22
176 177
		[]byte("UPDATE `xxx` SET aaa='a -- b' WHERE `id` = 15; UPDATE `xxx` SET aaa='c -- d' WHERE `id` = 16;"), // 23
		// []byte(`/* comment here */ SET MAX_JOIN_SIZE=#`),                        // 24
martianzhang's avatar
martianzhang 已提交
178
	}
179
	// \G 分隔符
martianzhang's avatar
martianzhang 已提交
180
	buf2s := [][]byte{
181 182 183 184 185 186
		[]byte("select * from test\\Ghello"),                    // 0
		[]byte("select 'hello\\Gworld', col from test\\Ghello"), // 1
		[]byte("-- select * from test\\Ghello"),                 // 2
		[]byte("#select * from test\\Ghello"),                   // 3
		[]byte("select * /*comment*/from test\\Ghello"),         // 4
		[]byte("select * /*comment;*/from test\\Ghello"),        // 5
martianzhang's avatar
martianzhang 已提交
187 188
		[]byte(`select * /*comment
        \\G*/
189
        from test\\Ghello`), // 6
martianzhang's avatar
martianzhang 已提交
190
	}
191 192 193 194
	//// single sql test
	//b, t1, t2 := SplitStatement(bufs[23], []byte(";"))
	//fmt.Println("buf: ", b, "sql: ", t1, "left: ", string(t2))
	//return
martianzhang's avatar
martianzhang 已提交
195 196
	err := common.GoldenDiff(func() {
		for i, buf := range bufs {
197
			sql, _, _ := SplitStatement(buf, []byte(";"))
martianzhang's avatar
martianzhang 已提交
198 199
			fmt.Println(i, sql)
		}
200

martianzhang's avatar
martianzhang 已提交
201
		for i, buf := range buf2s {
202
			sql, _, _ := SplitStatement(buf, []byte("\\G"))
martianzhang's avatar
martianzhang 已提交
203 204 205 206 207
			fmt.Println(i, sql)
		}
	}, t.Name(), update)
	if nil != err {
		t.Fatal(err)
martianzhang's avatar
martianzhang 已提交
208
	}
martianzhang's avatar
martianzhang 已提交
209
	common.Log.Debug("Exiting function: %s", common.GetFunctionName())
martianzhang's avatar
martianzhang 已提交
210 211 212
}

func TestLeftNewLines(t *testing.T) {
martianzhang's avatar
martianzhang 已提交
213
	common.Log.Debug("Entering function: %s", common.GetFunctionName())
martianzhang's avatar
martianzhang 已提交
214 215 216 217 218 219 220 221
	bufs := [][]byte{
		[]byte(`
		select * from test;hello`),
		[]byte(`select * /*comment
        ;*/
        from test;hello`),
		[]byte(`select * from test`),
	}
martianzhang's avatar
martianzhang 已提交
222 223 224 225 226 227 228
	err := common.GoldenDiff(func() {
		for _, buf := range bufs {
			fmt.Println(LeftNewLines(buf))
		}
	}, t.Name(), update)
	if nil != err {
		t.Fatal(err)
martianzhang's avatar
martianzhang 已提交
229
	}
martianzhang's avatar
martianzhang 已提交
230
	common.Log.Debug("Exiting function: %s", common.GetFunctionName())
martianzhang's avatar
martianzhang 已提交
231 232 233
}

func TestNewLines(t *testing.T) {
martianzhang's avatar
martianzhang 已提交
234
	common.Log.Debug("Entering function: %s", common.GetFunctionName())
martianzhang's avatar
martianzhang 已提交
235 236 237 238 239 240 241 242
	bufs := [][]byte{
		[]byte(`
		select * from test;hello`),
		[]byte(`select * /*comment
        ;*/
        from test;hello`),
		[]byte(`select * from test`),
	}
martianzhang's avatar
martianzhang 已提交
243 244 245 246 247 248 249
	err := common.GoldenDiff(func() {
		for _, buf := range bufs {
			fmt.Println(NewLines(buf))
		}
	}, t.Name(), update)
	if nil != err {
		t.Fatal(err)
martianzhang's avatar
martianzhang 已提交
250
	}
martianzhang's avatar
martianzhang 已提交
251
	common.Log.Debug("Exiting function: %s", common.GetFunctionName())
martianzhang's avatar
martianzhang 已提交
252
}
martianzhang's avatar
martianzhang 已提交
253 254 255 256

func TestQueryType(t *testing.T) {
	common.Log.Debug("Entering function: %s", common.GetFunctionName())
	var testSQLs = []string{
257
		` select 1`,
martianzhang's avatar
martianzhang 已提交
258
		`/*comment*/ select 1`,
martianzhang's avatar
martianzhang 已提交
259
		`(select 1)`,
martianzhang's avatar
martianzhang 已提交
260 261
		`grant select on *.* to user@'localhost'`,
		`REVOKE INSERT ON *.* FROM 'jeffrey'@'localhost';`,
martianzhang's avatar
martianzhang 已提交
262
	}
martianzhang's avatar
martianzhang 已提交
263 264 265
	// fmt.Println(testSQLs[len(testSQLs)-1])
	// fmt.Println(QueryType(testSQLs[len(testSQLs)-1]))
	// return
martianzhang's avatar
martianzhang 已提交
266 267 268 269 270 271 272 273 274 275
	err := common.GoldenDiff(func() {
		for _, buf := range append(testSQLs, common.TestSQLs...) {
			fmt.Println(QueryType(buf))
		}
	}, t.Name(), update)
	if nil != err {
		t.Fatal(err)
	}
	common.Log.Debug("Exiting function: %s", common.GetFunctionName())
}