提交 5619dd32 编写于 作者: martianzhang's avatar martianzhang

code format add some test case

上级 5c730e2b
...@@ -32,20 +32,13 @@ var explainRules map[string]Rule ...@@ -32,20 +32,13 @@ var explainRules map[string]Rule
// [table_name]"suggest text" // [table_name]"suggest text"
var tablesSuggests map[string][]string var tablesSuggests map[string][]string
/*
var explainIgnoreTables = []string{
"dual",
"",
}
*/
// explain建议的形式 // explain建议的形式
// Item: EXP.XXX // Item: EXP.XXX
// Severity: L[0-8] // Severity: L[0-8]
// Summary: full table scan, not use index, full index scan... // Summary: full table scan, not use index, full index scan...
// Content: XX TABLE xxx // Content: XX TABLE xxx
// // checkExplainSelectType
func checkExplainSelectType(exp *database.ExplainInfo) { func checkExplainSelectType(exp *database.ExplainInfo) {
// 判断是否跳过不检查 // 判断是否跳过不检查
if len(common.Config.ExplainWarnSelectType) == 1 { if len(common.Config.ExplainWarnSelectType) == 1 {
...@@ -70,7 +63,7 @@ func checkExplainSelectType(exp *database.ExplainInfo) { ...@@ -70,7 +63,7 @@ func checkExplainSelectType(exp *database.ExplainInfo) {
} }
} }
// 用户可以设置AccessType的建议级别,匹配到的查询会给出建议 // checkExplainAccessType 用户可以设置AccessType的建议级别,匹配到的查询会给出建议
func checkExplainAccessType(exp *database.ExplainInfo) { func checkExplainAccessType(exp *database.ExplainInfo) {
// 判断是否跳过不检查 // 判断是否跳过不检查
if len(common.Config.ExplainWarnAccessType) == 1 { if len(common.Config.ExplainWarnAccessType) == 1 {
...@@ -95,43 +88,28 @@ func checkExplainAccessType(exp *database.ExplainInfo) { ...@@ -95,43 +88,28 @@ func checkExplainAccessType(exp *database.ExplainInfo) {
} }
} }
// TODO:
/* /*
// TODO:
func checkExplainPossibleKeys(exp *database.ExplainInfo) { func checkExplainPossibleKeys(exp *database.ExplainInfo) {
// 判断是否跳过不检查
if common.Config.ExplainMinPossibleKeys == 0 {
return
}
rows := exp.ExplainRows
if exp.ExplainFormat == database.JSONFormatExplain {
// JSON形式遍历分析不方便,转成Row格式统一处理
rows = database.ConvertExplainJSON2Row(exp.ExplainJSON)
}
for _, row := range rows {
if len(row.PossibleKeys) < common.Config.ExplainMinPossibleKeys {
tablesSuggests[row.TableName] = append(tablesSuggests[row.TableName], fmt.Sprintf("PossibleKeys:%d < %d",
len(row.PossibleKeys), common.Config.ExplainMinPossibleKeys))
}
}
} }
*/
// TODO:
/*
func checkExplainKeyLen(exp *database.ExplainInfo) { func checkExplainKeyLen(exp *database.ExplainInfo) {
} }
*/
// TODO:
/*
func checkExplainKey(exp *database.ExplainInfo) { func checkExplainKey(exp *database.ExplainInfo) {
// 小于最小使用试用key数量 // 小于最小使用试用key数量
//return intval($explainResult) < intval($userCond); //return intval($explainResult) < intval($userCond);
//explain-min-keys int //explain-min-keys int
} }
func checkExplainExtra(exp *database.ExplainInfo) {
// 包含用户配置的逗号分隔关键词之一则提醒
// return self::contains($explainResult, $userCond);
// explain-warn-extra []string
}
*/ */
// checkExplainRef ...
func checkExplainRef(exp *database.ExplainInfo) { func checkExplainRef(exp *database.ExplainInfo) {
rows := exp.ExplainRows rows := exp.ExplainRows
if exp.ExplainFormat == database.JSONFormatExplain { if exp.ExplainFormat == database.JSONFormatExplain {
...@@ -148,6 +126,7 @@ func checkExplainRef(exp *database.ExplainInfo) { ...@@ -148,6 +126,7 @@ func checkExplainRef(exp *database.ExplainInfo) {
} }
} }
// checkExplainRows ...
func checkExplainRows(exp *database.ExplainInfo) { func checkExplainRows(exp *database.ExplainInfo) {
// 判断是否跳过不检查 // 判断是否跳过不检查
if common.Config.ExplainMaxRows <= 0 { if common.Config.ExplainMaxRows <= 0 {
...@@ -167,15 +146,7 @@ func checkExplainRows(exp *database.ExplainInfo) { ...@@ -167,15 +146,7 @@ func checkExplainRows(exp *database.ExplainInfo) {
} }
} }
// TODO: // checkExplainFiltered ...
/*
func checkExplainExtra(exp *database.ExplainInfo) {
// 包含用户配置的逗号分隔关键词之一则提醒
// return self::contains($explainResult, $userCond);
// explain-warn-extra []string
}
*/
func checkExplainFiltered(exp *database.ExplainInfo) { func checkExplainFiltered(exp *database.ExplainInfo) {
// 判断是否跳过不检查 // 判断是否跳过不检查
if common.Config.ExplainMaxFiltered <= 0.001 { if common.Config.ExplainMaxFiltered <= 0.001 {
...@@ -235,30 +206,7 @@ func ExplainAdvisor(exp *database.ExplainInfo) map[string]Rule { ...@@ -235,30 +206,7 @@ func ExplainAdvisor(exp *database.ExplainInfo) map[string]Rule {
Func: (*Query4Audit).RuleOK, Func: (*Query4Audit).RuleOK,
} }
} }
/* // TODO: 检查explain对应的表是否需要跳过,如dual,空表等
for t, s := range tablesSuggests {
// 检查explain对应的表是否需要跳过,如dual,空表等
ig := false
for _, ti := range explainIgnoreTables {
if ti == t {
ig = true
}
}
if ig {
continue
}
ruleId := fmt.Sprintf("EXP.%03d", explainRuleId+1)
explainRuleId = explainRuleId + 1
explainRules[ruleId] = Rule{
Item: ruleId,
Severity: "L0",
Summary: fmt.Sprintf("表 `%s` 查询效率不高", t),
Content: fmt.Sprint("原因:", strings.Join(s, ",")),
Case: "",
Func: (*Query4Audit).RuleOK,
}
}
*/
return explainRules return explainRules
} }
......
...@@ -665,7 +665,7 @@ func (idxAdv *IndexAdvisor) buildIndex(idxList map[string]map[string][]*common.C ...@@ -665,7 +665,7 @@ func (idxAdv *IndexAdvisor) buildIndex(idxList map[string]map[string][]*common.C
continue continue
} }
idxName := "idx_" + strings.Join(colNames, "_") idxName := common.Config.IdxPrefix + strings.Join(colNames, "_")
// 索引名称最大长度64 // 索引名称最大长度64
if len(idxName) > IndexNameMaxLength { if len(idxName) > IndexNameMaxLength {
...@@ -699,7 +699,7 @@ func (idxAdv *IndexAdvisor) buildIndexWithNoEnv(indexList map[string]map[string] ...@@ -699,7 +699,7 @@ func (idxAdv *IndexAdvisor) buildIndexWithNoEnv(indexList map[string]map[string]
common.Log.Warn("can not get the meta info of column '%s'", col.Name) common.Log.Warn("can not get the meta info of column '%s'", col.Name)
continue continue
} }
idxName := "idx_" + col.Name idxName := common.Config.IdxPrefix + col.Name
// 库、表、列名需要用反撇转义 // 库、表、列名需要用反撇转义
alterSQL := fmt.Sprintf("alter table `%s`.`%s` add index `%s` (`%s`)", idxAdv.vEnv.RealDB(col.DB), col.Table, idxName, col.Name) alterSQL := fmt.Sprintf("alter table `%s`.`%s` add index `%s` (`%s`)", idxAdv.vEnv.RealDB(col.DB), col.Table, idxName, col.Name)
if col.DB == "" { if col.DB == "" {
......
...@@ -48,10 +48,16 @@ func TestListHeuristicRules(t *testing.T) { ...@@ -48,10 +48,16 @@ func TestListHeuristicRules(t *testing.T) {
func TestInBlackList(t *testing.T) { func TestInBlackList(t *testing.T) {
common.Log.Debug("Entering function: %s", common.GetFunctionName()) common.Log.Debug("Entering function: %s", common.GetFunctionName())
sqls := []string{
"select",
"select 1",
}
common.BlackList = []string{"select"} common.BlackList = []string{"select"}
if !InBlackList("select 1") { for _, sql := range sqls {
if !InBlackList(sql) {
t.Error("should be true") t.Error("should be true")
} }
}
common.Log.Debug("Exiting function: %s", common.GetFunctionName()) common.Log.Debug("Exiting function: %s", common.GetFunctionName())
} }
......
...@@ -40,7 +40,10 @@ type Rule struct { ...@@ -40,7 +40,10 @@ type Rule struct {
} }
// RewriteRules SQL重写规则,注意这个规则是有序的,先后顺序不能乱 // RewriteRules SQL重写规则,注意这个规则是有序的,先后顺序不能乱
var RewriteRules = []Rule{ var RewriteRules []Rule
func init() {
RewriteRules = []Rule{
{ {
Name: "dml2select", Name: "dml2select",
Description: "将数据库更新请求转换为只读查询请求,便于执行EXPLAIN", Description: "将数据库更新请求转换为只读查询请求,便于执行EXPLAIN",
...@@ -214,6 +217,7 @@ var RewriteRules = []Rule{ ...@@ -214,6 +217,7 @@ var RewriteRules = []Rule{
}, },
// TODO in to exists // TODO in to exists
// TODO exists to in // TODO exists to in
}
} }
// ListRewriteRules 打印SQL重写规则 // ListRewriteRules 打印SQL重写规则
...@@ -842,7 +846,7 @@ func (rw *Rewrite) RewriteAddOrderByNull() *Rewrite { ...@@ -842,7 +846,7 @@ func (rw *Rewrite) RewriteAddOrderByNull() *Rewrite {
} }
// RewriteOr2Union or2union: 将 OR 查询转写为 UNION ALL TODO: 暂无对应 HeuristicRules // RewriteOr2Union or2union: 将 OR 查询转写为 UNION ALL TODO: 暂无对应 HeuristicRules
// https://sqlperformance.com/2014/09/sql-plan/rewriting-queries-improve-performance // TODO: https://sqlperformance.com/2014/09/sql-plan/rewriting-queries-improve-performance
func (rw *Rewrite) RewriteOr2Union() *Rewrite { func (rw *Rewrite) RewriteOr2Union() *Rewrite {
return rw return rw
} }
......
...@@ -18,6 +18,7 @@ package main ...@@ -18,6 +18,7 @@ package main
import ( import (
"flag" "flag"
"fmt"
"testing" "testing"
"github.com/XiaoMi/soar/common" "github.com/XiaoMi/soar/common"
...@@ -42,32 +43,42 @@ func TestMain(m *testing.M) { ...@@ -42,32 +43,42 @@ func TestMain(m *testing.M) {
} }
func Test_Main(_ *testing.T) { func Test_Main(_ *testing.T) {
common.Log.Debug("Entering function: %s", common.GetFunctionName())
common.Config.OnlineDSN.Disable = true common.Config.OnlineDSN.Disable = true
common.Config.LogLevel = 0 common.Config.LogLevel = 0
common.Config.Query = "select * from film;alter table city add index idx_country_id(country_id);" common.Config.Query = "select * from film;alter table city add index idx_country_id(country_id);"
main() main()
common.Log.Debug("Exiting function: %s", common.GetFunctionName())
} }
func Test_Main_More(_ *testing.T) { func Test_Main_More(_ *testing.T) {
common.Log.Debug("Entering function: %s", common.GetFunctionName())
common.Config.LogLevel = 0 common.Config.LogLevel = 0
common.Config.Profiling = true common.Config.Profiling = true
common.Config.Explain = true common.Config.Explain = true
common.Config.Query = "select * from film where country_id = 1;use sakila;alter table city add index idx_country_id(country_id);" common.Config.Query = "select * from film where country_id = 1;use sakila;alter table city add index idx_country_id(country_id);"
orgRerportType := common.Config.ReportType
for _, typ := range []string{ for _, typ := range []string{
"json", "html", "markdown", "fingerprint", "compress", "pretty", "rewrite", "json", "html", "markdown", "fingerprint", "compress", "pretty", "rewrite",
"ast", "tiast", "ast-json", "tiast-json", "tokenize",
} { } {
common.Config.ReportType = typ common.Config.ReportType = typ
main() main()
} }
common.Config.ReportType = orgRerportType
common.Log.Debug("Exiting function: %s", common.GetFunctionName())
} }
func Test_Main_checkConfig(t *testing.T) { func Test_Main_checkConfig(t *testing.T) {
common.Log.Debug("Entering function: %s", common.GetFunctionName())
if checkConfig() != 0 { if checkConfig() != 0 {
t.Error("checkConfig error") t.Error("checkConfig error")
} }
common.Log.Debug("Exiting function: %s", common.GetFunctionName())
} }
func Test_Main_initQuery(t *testing.T) { func Test_Main_initQuery(t *testing.T) {
common.Log.Debug("Entering function: %s", common.GetFunctionName())
// direct query // direct query
query := initQuery("select 1") query := initQuery("select 1")
if query != "select 1" { if query != "select 1" {
...@@ -79,4 +90,17 @@ func Test_Main_initQuery(t *testing.T) { ...@@ -79,4 +90,17 @@ func Test_Main_initQuery(t *testing.T) {
// TODO: read from stdin // TODO: read from stdin
// initQuery("") // initQuery("")
common.Log.Debug("Exiting function: %s", common.GetFunctionName())
}
func Test_Main_reportTool(t *testing.T) {
common.Log.Debug("Entering function: %s", common.GetFunctionName())
orgRerportType := common.Config.ReportType
types := []string{"html", "md2html", "explain-digest", "chardet", "remove-comment"}
for _, tp := range types {
common.Config.ReportType = tp
fmt.Println(reportTool(tp, []byte{}))
}
common.Config.ReportType = orgRerportType
common.Log.Debug("Exiting function: %s", common.GetFunctionName())
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册