Skip to content

Commit

Permalink
sql: fix JSON deserialization for sql stats lastExecAt field
Browse files Browse the repository at this point in the history
Previsouly, lastExecAt field for roachpb.CollectedStatementStatistics
was not properly updated. This caused the status API to return
empty data for that field.
This commit fixes the deserialization and extended the randomize
testing framework to also test time.Time type.

Partially Resolves #69675

Release Justification: Bug fixes and low-risk updates to new
functionality

Release note (bug fix): Last Execution Timestamp is now properly
updating.
  • Loading branch information
Azhng committed Sep 15, 2021
1 parent 30c199a commit 4d0c386
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ go_library(
"//pkg/sql/sem/tree",
"//pkg/util/encoding",
"//pkg/util/json",
"//pkg/util/timeutil",
"@com_github_cockroachdb_apd_v2//:apd",
"@com_github_cockroachdb_errors//:errors",
"@com_github_stretchr_testify//require",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func TestSQLStatsJsonEncoding(t *testing.T) {
"cnt": {{.Int64}},
"firstAttemptCnt": {{.Int64}},
"maxRetries": {{.Int64}},
"lastExecAt": "0001-01-01T00:00:00Z",
"lastExecAt": "{{stringifyTime .Time}}",
"numRows": {
"mean": {{.Float}},
"sqDiff": {{.Float}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ func (t *jsonTime) decodeJSON(js json.JSON) error {
return err
}

tm := (time.Time)(*t)
tm := (*time.Time)(t)
if err := tm.UnmarshalText([]byte(s)); err != nil {
return err
}
Expand Down
36 changes: 26 additions & 10 deletions pkg/sql/sqlstats/persistedsqlstats/sqlstatsutil/testutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ import (
"strconv"
"strings"
"testing"
"time"

"github.com/cockroachdb/cockroach/pkg/roachpb"
"github.com/cockroachdb/cockroach/pkg/util/timeutil"
"github.com/stretchr/testify/require"
)

Expand All @@ -42,6 +44,7 @@ type randomData struct {
Int64 int64
Float float64
IntArray []int64
Time time.Time
}

var alphabet = []rune("abcdefghijklmkopqrstuvwxyz")
Expand All @@ -67,6 +70,7 @@ func genRandomData() randomData {
r.IntArray[i] = rand.Int63()
}

r.Time = timeutil.Now()
return r
}

Expand All @@ -78,10 +82,16 @@ func fillTemplate(t *testing.T, tmplStr string, data randomData) string {
}
return strings.Join(strArr, ",")
}
stringifyTime := func(tm time.Time) string {
s, err := tm.MarshalText()
require.NoError(t, err)
return string(s)
}
tmpl, err := template.
New("").
Funcs(template.FuncMap{
"joinInts": joinInts,
"joinInts": joinInts,
"stringifyTime": stringifyTime,
}).
Parse(tmplStr)
require.NoError(t, err)
Expand All @@ -101,7 +111,6 @@ var fieldBlacklist = map[string]struct{}{
"SensitiveInfo": {},
"LegacyLastErr": {},
"LegacyLastErrRedacted": {},
"LastExecTimestamp": {},
"StatementFingerprintIDs": {},
"AggregatedTs": {},
}
Expand Down Expand Up @@ -130,15 +139,22 @@ func fillObject(t *testing.T, val reflect.Value, data *randomData) {
val.Set(reflect.Append(val, reflect.ValueOf(randInt)))
}
case reflect.Struct:
numFields := val.NumField()
for i := 0; i < numFields; i++ {
fieldName := val.Type().Field(i).Name
fieldAddr := val.Field(i).Addr()
if _, ok := fieldBlacklist[fieldName]; ok {
continue
switch val.Type().Name() {
// Special handling time.Time.
case "Time":
val.Set(reflect.ValueOf(data.Time))
return
default:
numFields := val.NumField()
for i := 0; i < numFields; i++ {
fieldName := val.Type().Field(i).Name
fieldAddr := val.Field(i).Addr()
if _, ok := fieldBlacklist[fieldName]; ok {
continue
}

fillObject(t, fieldAddr, data)
}

fillObject(t, fieldAddr, data)
}
default:
t.Fatalf("unsupported type: %s", val.Kind().String())
Expand Down

0 comments on commit 4d0c386

Please sign in to comment.