From a583e9d86d37860189d79fc4610f5b09d66183bc Mon Sep 17 00:00:00 2001 From: Leon Zhang Date: Wed, 26 Dec 2018 13:43:19 +0800 Subject: [PATCH] fix explain empty struct problem, null able column --- database/explain.go | 45 ++++++++++++++++++++++++++++-------------- database/mysql.go | 8 ++++++++ database/mysql_test.go | 14 +++++++++++++ 3 files changed, 52 insertions(+), 15 deletions(-) diff --git a/database/explain.go b/database/explain.go index 51349af..1ca0b7f 100644 --- a/database/explain.go +++ b/database/explain.go @@ -948,23 +948,31 @@ func ParseExplainResult(res QueryResult, formatType int) (exp *ExplainInfo, err return exp, err } + /* + +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+ + | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | + +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+ + | 1 | SIMPLE | film | NULL | ALL | NULL | NULL | NULL | NULL | 1000 | 100.00 | NULL | + +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+ + */ + // Different MySQL version has different columns define - var possibleKeys string + var selectType, table, partitions, accessType, possibleKeys, key, keyLen, ref, extra []byte expRow := &ExplainRow{} explainFields := make([]interface{}, 0) fields := map[string]interface{}{ - "id": expRow.ID, - "select_type": expRow.SelectType, - "table": expRow.TableName, - "partitions": expRow.Partitions, - "type": expRow.AccessType, + "id": &expRow.ID, + "select_type": &selectType, + "table": &table, + "partitions": &partitions, + "type": &accessType, "possible_keys": &possibleKeys, - "key": expRow.Key, - "key_len": expRow.KeyLen, - "ref": expRow.Ref, - "rows": expRow.Rows, - "filtered": expRow.Filtered, - "extra": expRow.Extra, + "key": &key, + "key_len": &keyLen, + "ref": &ref, + "rows": &expRow.Rows, + "filtered": &expRow.Filtered, + "Extra": &extra, } cols, err := res.Rows.Columns() common.LogIfError(err, "") @@ -980,13 +988,20 @@ func ParseExplainResult(res QueryResult, formatType int) (exp *ExplainInfo, err // 补全 ExplainRows var explainRows []*ExplainRow - for res.Rows.Next() { err := res.Rows.Scan(explainFields...) if err != nil { - common.Log.Debug(err.Error()) + common.Log.Warn(err.Error()) } - expRow.PossibleKeys = strings.Split(possibleKeys, ",") + expRow.SelectType = NullString(selectType) + expRow.TableName = NullString(table) + expRow.Partitions = NullString(partitions) + expRow.AccessType = NullString(accessType) + expRow.PossibleKeys = strings.Split(NullString(possibleKeys), ",") + expRow.Key = NullString(key) + expRow.KeyLen = NullString(keyLen) + expRow.Ref = strings.Split(NullString(ref), ",") + expRow.Extra = NullString(extra) // MySQL bug: https://bugs.mysql.com/bug.php?id=34124 if expRow.Filtered > 100.00 { diff --git a/database/mysql.go b/database/mysql.go index a9ff958..050c12a 100644 --- a/database/mysql.go +++ b/database/mysql.go @@ -311,3 +311,11 @@ func TimeString(t time.Time) string { } return t.Format(TimeFormat) } + +// NullString null able string +func NullString(buf []byte) string { + if buf == nil { + return "NULL" + } + return string(buf) +} diff --git a/database/mysql_test.go b/database/mysql_test.go index fdd73b9..d85949d 100644 --- a/database/mysql_test.go +++ b/database/mysql_test.go @@ -184,3 +184,17 @@ func TestIsView(t *testing.T) { connTest.Database = originalDatabase common.Log.Debug("Exiting function: %s", common.GetFunctionName()) } + +func TestNullString(t *testing.T) { + common.Log.Debug("Entering function: %s", common.GetFunctionName()) + cases := [][]byte{ + nil, + []byte("NULL"), + } + for _, buf := range cases { + if NullString(buf) != "NULL" { + t.Errorf("%s want NULL", string(buf)) + } + } + common.Log.Debug("Exiting function: %s", common.GetFunctionName()) +} -- GitLab