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

statistics: fix the error that init stats might got failure when decoding column bucket (#55685) #56024

Merged
Merged
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
36 changes: 32 additions & 4 deletions statistics/handle/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,12 @@
}

func (h *Handle) initStatsBuckets4Chunk(cache *statsCache, iter *chunk.Iterator4Chunk) {
unspecifiedLengthTp := types.NewFieldType(mysql.TypeBlob)
var (
hasErr bool
failedTableID int64
failedHistID int64
)
for row := iter.Begin(); row != iter.End(); row = iter.Next() {
tableID, isIndex, histID := row.GetInt64(0), row.GetInt64(1), row.GetInt64(2)
table, ok := cache.Get(tableID)
Expand Down Expand Up @@ -304,22 +310,44 @@
// TODO: do the correct time zone conversion for timestamp-type columns' upper/lower bounds.
sc := &stmtctx.StatementContext{TimeZone: time.UTC, AllowInvalidDate: true, IgnoreZeroInDate: true}
var err error
lower, err = d.ConvertTo(sc, &column.Info.FieldType)
if column.Info.FieldType.EvalType() == types.ETString && column.Info.FieldType.GetType() != mysql.TypeEnum && column.Info.FieldType.GetType() != mysql.TypeSet {
// For new collation data, when storing the bounds of the histogram, we store the collate key instead of the
// original value.
// But there's additional conversion logic for new collation data, and the collate key might be longer than
// the FieldType.flen.
// If we use the original FieldType here, there might be errors like "Invalid utf8mb4 character string"
// or "Data too long".
// So we change it to TypeBlob to bypass those logics here.
lower, err = d.ConvertTo(sc, unspecifiedLengthTp)

Check warning on line 321 in statistics/handle/bootstrap.go

View check run for this annotation

Codecov / codecov/patch

statistics/handle/bootstrap.go#L314-L321

Added lines #L314 - L321 were not covered by tests
} else {
lower, err = d.ConvertTo(sc, &column.Info.FieldType)
}
if err != nil {
logutil.BgLogger().Debug("decode bucket lower bound failed", zap.Error(err))
hasErr = true
failedTableID = tableID
failedHistID = histID

Check warning on line 328 in statistics/handle/bootstrap.go

View check run for this annotation

Codecov / codecov/patch

statistics/handle/bootstrap.go#L326-L328

Added lines #L326 - L328 were not covered by tests
delete(table.Columns, histID)
continue
}
d = types.NewBytesDatum(row.GetBytes(6))
upper, err = d.ConvertTo(sc, &column.Info.FieldType)
if column.Info.FieldType.EvalType() == types.ETString && column.Info.FieldType.GetType() != mysql.TypeEnum && column.Info.FieldType.GetType() != mysql.TypeSet {
upper, err = d.ConvertTo(sc, unspecifiedLengthTp)

Check warning on line 334 in statistics/handle/bootstrap.go

View check run for this annotation

Codecov / codecov/patch

statistics/handle/bootstrap.go#L334

Added line #L334 was not covered by tests
} else {
upper, err = d.ConvertTo(sc, &column.Info.FieldType)
}
if err != nil {
logutil.BgLogger().Debug("decode bucket upper bound failed", zap.Error(err))
hasErr = true
failedTableID = tableID
failedHistID = histID

Check warning on line 341 in statistics/handle/bootstrap.go

View check run for this annotation

Codecov / codecov/patch

statistics/handle/bootstrap.go#L339-L341

Added lines #L339 - L341 were not covered by tests
delete(table.Columns, histID)
continue
}
}
hist.AppendBucketWithNDV(&lower, &upper, row.GetInt64(3), row.GetInt64(4), row.GetInt64(7))
}
if hasErr {
logutil.BgLogger().Error("failed to convert datum for at least one histogram bucket", zap.Int64("table ID", failedTableID), zap.Int64("column ID", failedHistID))
}

Check warning on line 350 in statistics/handle/bootstrap.go

View check run for this annotation

Codecov / codecov/patch

statistics/handle/bootstrap.go#L349-L350

Added lines #L349 - L350 were not covered by tests
}

func (h *Handle) initStatsBuckets(cache *statsCache) error {
Expand Down
Loading