Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: panic when accept a nil where stmt #2147

Merged
merged 4 commits into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 39 additions & 18 deletions sqle/driver/mysql/advisor.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ import (
const (
MAX_INDEX_COLUMN string = "composite_index_max_column"
MAX_INDEX_COLUMN_DEFAULT_VALUE int = 5
threeStarIndexAdviceFormat string = "索引建议 | 根据三星索引设计规范,建议对表%s添加复合索引:【%s】"
prefixIndexAdviceFormat string = "索引建议 | SQL使用了前缀模式匹配,数据量大时,可建立翻转函数索引"
extremalIndexAdviceFormat string = "索引建议 | SQL使用了最值函数,可以利用索引有序的性质快速找到最值,建议对表%s添加单列索引,参考列:%s"
functionIndexAdviceFormatV80 string = "索引建议 | SQL使用了函数作为查询条件,在MySQL8.0.13以上的版本,可以创建函数索引,建议对表%s添加函数索引,参考列:%s"
functionIndexAdviceFormatV57 string = "索引建议 | SQL使用了函数作为查询条件,在MySQL5.7以上的版本,可以在虚拟列上创建索引,建议对表%s添加虚拟列索引,参考列:%s"
functionIndexAdviceFormatAll string = "索引建议 | SQL使用了函数作为查询条件,在MySQL5.7以上的版本,可以在虚拟列上创建索引,在MySQL8.0.13以上的版本,可以创建函数索引,建议根据MySQL版本对表%s添加合适的索引,参考列:%s"
joinIndexAdviceFormat string = "索引建议 | SQL中字段%s为被驱动表%s上的关联字段,建议对表%s添加单列索引,参考列:%s"
)

type OptimizeResult struct {
Expand Down Expand Up @@ -345,10 +352,12 @@ func (a *threeStarIndexAdvisor) GiveAdvices() []*OptimizeResult {
if util.IsIndex(a.adviceColumns.columnMap, a.drivingTableCreateStmt.Constraints) {
return nil
}
tableName := util.GetTableNameFromTableSource(a.drivingTableSource)
indexColumns := a.adviceColumns.stringSlice()
return []*OptimizeResult{{
TableName: util.GetTableNameFromTableSource(a.drivingTableSource),
IndexedColumns: a.adviceColumns.stringSlice(),
Reason: fmt.Sprintf("索引建议 | SQL:%s 中,根据三星索引设计规范", restore(a.originNode)),
TableName: tableName,
IndexedColumns: indexColumns,
Reason: fmt.Sprintf(threeStarIndexAdviceFormat, tableName, strings.Join(indexColumns, ",")),
}}
}

Expand Down Expand Up @@ -680,6 +689,9 @@ func newJoinIndexAdvisor(ctx *session.Context, log *logrus.Entry, originNode ast
}

func (a *joinIndexAdvisor) GiveAdvices() []*OptimizeResult {
if a.originNode == nil {
return nil
}
err := a.loadEssentials()
if err != nil {
a.log.Logger.Warnf("when join index advisor load essentials failed, err:%v", err)
Expand Down Expand Up @@ -780,7 +792,7 @@ func (a *joinIndexAdvisor) giveAdvice() {
a.advices = append(a.advices, &OptimizeResult{
TableName: drivenTableName,
IndexedColumns: indexColumn,
Reason: fmt.Sprintf("索引建议 | SQL:%s 中,字段 %s 为被驱动表 %s 上的关联字段", restore(a.currentNode), strings.Join(indexColumn, ","), drivenTableName),
Reason: fmt.Sprintf(joinIndexAdviceFormat, strings.Join(indexColumn, ","), drivenTableName, drivenTableName, strings.Join(indexColumn, ",")),
})
}

Expand Down Expand Up @@ -841,15 +853,18 @@ func newFunctionIndexAdvisor(ctx *session.Context, log *logrus.Entry, originNode
}

func (a *functionIndexAdvisor) GiveAdvices() []*OptimizeResult {
node, ok := a.originNode.(*ast.SelectStmt)
if !ok {
return nil
}
if node.Where == nil {
return nil
}
err := a.loadEssentials()
if err != nil {
a.log.Logger.Warnf("when function index advisor load essentials failed, err:%v", err)
return nil
}
node, ok := a.originNode.(*ast.SelectStmt)
if !ok {
return nil
}
node.Where.Accept(a)
return a.advices
}
Expand Down Expand Up @@ -917,23 +932,23 @@ func (a *functionIndexAdvisor) giveAdvice() {
a.advices = append(a.advices, &OptimizeResult{
TableName: tableName,
IndexedColumns: columns,
Reason: fmt.Sprintf("索引建议 | SQL:%s 中,使用了函数作为查询条件,在MySQL5.7以上的版本,可以在虚拟列上创建索引", restore(a.currentNode.L)),
Reason: fmt.Sprintf(functionIndexAdviceFormatV57, tableName, strings.Join(columns, ",")),
})
return
}
if curVersion != nil && curVersion.GreaterThan(semver.MustParse("8.0.12")) {
a.advices = append(a.advices, &OptimizeResult{
TableName: tableName,
IndexedColumns: columns,
Reason: fmt.Sprintf("索引建议 | SQL:%s 中,使用了函数作为查询条件,在MySQL8.0.13以上的版本,可以创建函数索引", restore(a.currentNode.L)),
Reason: fmt.Sprintf(functionIndexAdviceFormatV80, tableName, strings.Join(columns, ",")),
})
return
}
// 某些版本解析会出错,例如"8.0.35-0<system_name>0.22.04.1"
a.advices = append(a.advices, &OptimizeResult{
TableName: tableName,
IndexedColumns: columns,
Reason: fmt.Sprintf("索引建议 | SQL:%s 中,使用了函数作为查询条件,在MySQL5.7以上的版本,可以在虚拟列上创建索引,在MySQL8.0.13以上的版本,可以创建函数索引", restore(a.currentNode.L)),
Reason: fmt.Sprintf(functionIndexAdviceFormatAll, tableName, strings.Join(columns, ",")),
})
}

Expand Down Expand Up @@ -966,6 +981,9 @@ func newExtremalIndexAdvisor(ctx *session.Context, log *logrus.Entry, originNode
}

func (a *extremalIndexAdvisor) GiveAdvices() []*OptimizeResult {
if a.originNode == nil {
return nil
}
err := a.loadEssentials()
if err != nil {
a.log.Logger.Warnf("when extremal index advisor load essentials failed, err:%v", err)
Expand Down Expand Up @@ -1027,7 +1045,7 @@ func (a *extremalIndexAdvisor) giveAdvice() {
a.advices = append(a.advices, &OptimizeResult{
TableName: tableName,
IndexedColumns: []string{indexColumn},
Reason: fmt.Sprintf("索引建议 | SQL:%s 中,使用了最值函数,可以利用索引有序的性质快速找到最值", restore(a.currentNode)),
Reason: fmt.Sprintf(extremalIndexAdviceFormat, tableName, indexColumn),
})
}

Expand Down Expand Up @@ -1056,15 +1074,18 @@ func newPrefixIndexAdvisor(ctx *session.Context, log *logrus.Entry, originNode a
}

func (a *prefixIndexAdvisor) GiveAdvices() []*OptimizeResult {
node, ok := a.originNode.(*ast.SelectStmt)
if !ok {
return nil
}
if node.Where == nil {
return nil
}
err := a.loadEssentials()
if err != nil {
a.log.Logger.Warnf("when prefix index advisor load essentials failed, err:%v", err)
return nil
}
node, ok := a.originNode.(*ast.SelectStmt)
if !ok {
return nil
}
node.Where.Accept(a)
return a.advices
}
Expand Down Expand Up @@ -1100,7 +1121,7 @@ func (v *prefixIndexAdvisor) Leave(in ast.Node) (out ast.Node, ok bool) {
}

func (a *prefixIndexAdvisor) giveAdvice() {
if !util.CheckWhereFuzzySearch(a.currentNode) {
if !util.CheckWhereLeftFuzzySearch(a.currentNode) {
return
}
column, ok := a.currentNode.Expr.(*ast.ColumnNameExpr)
Expand All @@ -1116,6 +1137,6 @@ func (a *prefixIndexAdvisor) giveAdvice() {
a.advices = append(a.advices, &OptimizeResult{
TableName: tableName,
IndexedColumns: []string{column.Name.Name.L},
Reason: fmt.Sprintf("索引建议 | SQL:%s 中,使用了前缀模式匹配,在数据量大的时候,可以建立翻转函数索引", restore(a.currentNode)),
Reason: prefixIndexAdviceFormat,
})
}
Loading
Loading