diff --git a/server/ast/alter_database.go b/server/ast/alter_database.go index ed7b63aa7f..7a6d2907ce 100644 --- a/server/ast/alter_database.go +++ b/server/ast/alter_database.go @@ -28,7 +28,7 @@ func nodeAlterDatabase(ctx *Context, node *tree.AlterDatabase) (vitess.Statement // We can handle the common ALTER DATABASE .. TO OWNER case since it's a no-op if node.Owner != "" { - return NewNoOp([]string{"owners are unsupported"}), nil + return NewNoOp([]string{"owners are not yet supported"}), nil } return NotYetSupportedError("ALTER DATABASE is not yet supported") diff --git a/server/ast/alter_function.go b/server/ast/alter_function.go index b310a10d34..c99a2aa90b 100644 --- a/server/ast/alter_function.go +++ b/server/ast/alter_function.go @@ -29,7 +29,7 @@ func nodeAlterFunction(ctx *Context, node *tree.AlterFunction) (vitess.Statement // We can handle the common ALTER FUNCTION .. TO OWNER case since it's a no-op if node.Owner != "" { - return NewNoOp([]string{"owners are unsupported"}), nil + return NewNoOp([]string{"owners are not yet supported"}), nil } return NotYetSupportedError("ALTER FUNCTION statement is not yet supported") diff --git a/server/ast/alter_schema.go b/server/ast/alter_schema.go index 147c9ddeb1..2f636d5e80 100644 --- a/server/ast/alter_schema.go +++ b/server/ast/alter_schema.go @@ -28,7 +28,7 @@ func nodeAlterSchema(ctx *Context, node *tree.AlterSchema) (vitess.Statement, er // We can handle the common ALTER SCHEMA .. TO OWNER case since it's a no-op if _, ok := node.Cmd.(*tree.AlterSchemaOwner); ok { - return NewNoOp([]string{"owners are unsupported"}), nil + return NewNoOp([]string{"owners are not yet supported"}), nil } return NotYetSupportedError("ALTER SCHEMA is not yet supported") diff --git a/server/ast/alter_sequence.go b/server/ast/alter_sequence.go index d1db7fc440..6cafc63e53 100644 --- a/server/ast/alter_sequence.go +++ b/server/ast/alter_sequence.go @@ -28,7 +28,7 @@ func nodeAlterSequence(ctx *Context, node *tree.AlterSequence) (vitess.Statement // We can handle the common ALTER SEQUENCE .. TO OWNER case since it's a no-op if node.Owner != "" { - return NewNoOp([]string{"owners are unsupported"}), nil + return NewNoOp([]string{"owners are not yet supported"}), nil } return NotYetSupportedError("ALTER SEQUENCE is not yet supported") diff --git a/server/ast/alter_table.go b/server/ast/alter_table.go index 4add20f8ba..45eec52501 100644 --- a/server/ast/alter_table.go +++ b/server/ast/alter_table.go @@ -161,7 +161,7 @@ func nodeAlterTableCmds( case *tree.AlterTableComputed: return nil, nil, errors.New("This command does not currently support multiple actions in one statement") default: - return nil, nil, errors.Errorf("ALTER TABLE with unsupported command type %T", cmd) + return nil, nil, errors.Errorf("ALTER TABLE with command type %T is not yet supported", cmd) } } diff --git a/server/ast/alter_type.go b/server/ast/alter_type.go index 254de5d1f4..4c949d7470 100644 --- a/server/ast/alter_type.go +++ b/server/ast/alter_type.go @@ -28,7 +28,7 @@ func nodeAlterType(ctx *Context, node *tree.AlterType) (vitess.Statement, error) // We can handle the common ALTER TYPE .. TO OWNER case since it's a no-op if _, ok := node.Cmd.(*tree.AlterTypeOwner); ok { - return NewNoOp([]string{"owners are unsupported"}), nil + return NewNoOp([]string{"owners are not yet supported"}), nil } return NotYetSupportedError("ALTER TYPE is not yet supported") diff --git a/server/ast/alter_view.go b/server/ast/alter_view.go index 7f522ae0b6..e6d6595e07 100755 --- a/server/ast/alter_view.go +++ b/server/ast/alter_view.go @@ -28,7 +28,7 @@ func nodeAlterView(ctx *Context, stmt *tree.AlterView) (sqlparser.Statement, err // We can handle the common ALTER VIEW .. TO OWNER case since it's a no-op if _, ok := stmt.Cmd.(*tree.AlterViewOwnerTo); ok { - return NewNoOp([]string{"owners are unsupported"}), nil + return NewNoOp([]string{"owners are not yet supported"}), nil } return NotYetSupportedError("ALTER VIEW is not yet supported") diff --git a/server/ast/analyze.go b/server/ast/analyze.go index 0be17a38b2..4d987f8da4 100644 --- a/server/ast/analyze.go +++ b/server/ast/analyze.go @@ -36,7 +36,7 @@ func nodeAnalyze(ctx *Context, node *tree.Analyze) (vitess.Statement, error) { objectName, ok := node.Table.(*tree.UnresolvedObjectName) if !ok { - return nil, errors.Errorf("unsupported table type in Analyze node: %T", node.Table) + return nil, errors.Errorf("table type in Analyze node: %T is not yet supported", node.Table) } return &vitess.Analyze{Tables: []vitess.TableName{ diff --git a/server/ast/constraint_table_def.go b/server/ast/constraint_table_def.go index d840908080..39e4a4831f 100644 --- a/server/ast/constraint_table_def.go +++ b/server/ast/constraint_table_def.go @@ -33,7 +33,7 @@ func nodeCheckConstraintTableDef( ifExists bool) (*vitess.DDL, error) { if node.NoInherit { - return nil, errors.Errorf("NO INHERIT is not yet supported for check constraints") + return nil, errors.Errorf("NO INHERIT for check constraints is not yet supported") } expr, err := nodeExpr(ctx, node.Expr) @@ -71,7 +71,7 @@ func nodeAlterTableDropConstraint( ifExists bool) (*vitess.DDL, error) { if node.DropBehavior == tree.DropCascade { - return nil, errors.Errorf("CASCADE is not yet supported for drop constraint") + return nil, errors.Errorf("CASCADE for drop constraint is not yet supported") } return &vitess.DDL{ @@ -99,7 +99,7 @@ func nodeUniqueConstraintTableDef( ifExists bool) (*vitess.DDL, error) { if len(node.IndexParams.StorageParams) > 0 { - return nil, errors.Errorf("STORAGE parameters not yet supported for indexes") + return nil, errors.Errorf("STORAGE parameters for indexes are not yet supported") } if node.IndexParams.Tablespace != "" { diff --git a/server/ast/create_sequence.go b/server/ast/create_sequence.go index 4e8b9aabb4..2c6d340a55 100644 --- a/server/ast/create_sequence.go +++ b/server/ast/create_sequence.go @@ -43,7 +43,7 @@ func nodeCreateSequence(ctx *Context, node *tree.CreateSequence) (vitess.Stateme return nil, err } if len(name.DbQualifier.String()) > 0 { - return nil, errors.Errorf("CREATE SEQUENCE is currently only supported for the current database") + return nil, errors.Errorf("CREATE SEQUENCE for the non-current database is not yet supported") } // Read all options and check whether they've been set (if not, we'll use the defaults) minValueLimit := int64(math.MinInt64) diff --git a/server/ast/create_trigger.go b/server/ast/create_trigger.go index f143a7c8e7..1cac55c9ff 100644 --- a/server/ast/create_trigger.go +++ b/server/ast/create_trigger.go @@ -38,16 +38,16 @@ func nodeCreateTrigger(ctx *Context, node *tree.CreateTrigger) (_ vitess.Stateme return NotYetSupportedError("CREATE CONSTRAINT TRIGGER is not yet supported") } if !node.RefTable.IsEmpty() { - return NotYetSupportedError("FROM is not yet supported for CREATE TRIGGER") + return NotYetSupportedError("FROM for CREATE TRIGGER is not yet supported") } if node.Deferrable != tree.TriggerNotDeferrable { - return NotYetSupportedError("DEFERRABLE is not yet supported for CREATE TRIGGER") + return NotYetSupportedError("DEFERRABLE for CREATE TRIGGER is not yet supported") } if len(node.Relations) > 0 { - return NotYetSupportedError("REFERENCING is not yet supported for CREATE TRIGGER") + return NotYetSupportedError("REFERENCING for CREATE TRIGGER is not yet supported") } if !node.ForEachRow { - return NotYetSupportedError("FOR EACH STATEMENT is not yet supported for CREATE TRIGGER") + return NotYetSupportedError("FOR EACH STATEMENT for CREATE TRIGGER is not yet supported") } funcName := node.FuncName.ToTableName() var timing triggers.TriggerTiming @@ -57,7 +57,7 @@ func nodeCreateTrigger(ctx *Context, node *tree.CreateTrigger) (_ vitess.Stateme case tree.TriggerTimeAfter: timing = triggers.TriggerTiming_After case tree.TriggerTimeInsteadOf: - return NotYetSupportedError("INSTEAD OF is not yet supported for CREATE TRIGGER") + return NotYetSupportedError("INSTEAD OF for CREATE TRIGGER is not yet supported") } var events []triggers.TriggerEvent for _, event := range node.Events { @@ -68,7 +68,7 @@ func nodeCreateTrigger(ctx *Context, node *tree.CreateTrigger) (_ vitess.Stateme }) case tree.TriggerEventUpdate: if len(event.Cols) > 0 { - return NotYetSupportedError("UPDATE specific columns are not yet supported for CREATE TRIGGER") + return NotYetSupportedError("UPDATE specific columns for CREATE TRIGGER are not yet supported") } events = append(events, triggers.TriggerEvent{ Type: triggers.TriggerEventType_Update, @@ -79,9 +79,9 @@ func nodeCreateTrigger(ctx *Context, node *tree.CreateTrigger) (_ vitess.Stateme Type: triggers.TriggerEventType_Delete, }) case tree.TriggerEventTruncate: - return NotYetSupportedError("TRUNCATE is not yet supported for CREATE TRIGGER") + return NotYetSupportedError("TRUNCATE for CREATE TRIGGER is not yet supported") default: - return NotYetSupportedError("UNKNOWN EVENT TYPE is not yet supported for CREATE TRIGGER") + return NotYetSupportedError("UNKNOWN EVENT TYPE for CREATE TRIGGER is not yet supported") } } // WHEN expressions seem to behave identically to interpreted functions, so we'll parse them as interpreted functions. diff --git a/server/ast/discard.go b/server/ast/discard.go index e2302136e7..dc1fa15c2a 100644 --- a/server/ast/discard.go +++ b/server/ast/discard.go @@ -29,7 +29,7 @@ func nodeDiscard(ctx *Context, discard *tree.Discard) (vitess.Statement, error) return nil, nil } if discard.Mode != tree.DiscardModeAll { - return nil, errors.Errorf("unhandled DISCARD mode: %v", discard.Mode) + return nil, errors.Errorf("DISCARD mode: %v is not yet supported", discard.Mode) } return vitess.InjectedStatement{ diff --git a/server/ast/drop_function.go b/server/ast/drop_function.go index c85772ab2e..91fcf27941 100644 --- a/server/ast/drop_function.go +++ b/server/ast/drop_function.go @@ -30,7 +30,7 @@ func nodeDropFunction(_ *Context, node *tree.DropFunction) (vitess.Statement, er } if node.DropBehavior == tree.DropCascade { - return nil, fmt.Errorf("DROP FUNCTION with CASCADE is not supported yet") + return nil, fmt.Errorf("DROP FUNCTION with CASCADE is not yet supported") } if len(node.Functions) == 0 { diff --git a/server/ast/drop_index.go b/server/ast/drop_index.go index 9f31904c27..cfdf5f28ae 100644 --- a/server/ast/drop_index.go +++ b/server/ast/drop_index.go @@ -49,7 +49,7 @@ func nodeDropIndex(ctx *Context, node *tree.DropIndex) (*vitess.AlterTable, erro return nil, err } if !tableName.Name.IsEmpty() && tableName.String() != newTableName.String() { - return nil, errors.Errorf("only dropping indexes from the same table is currently supported") + return nil, errors.Errorf("dropping indexes from different tables is not yet supported") } tableName = newTableName ddls[i] = &vitess.DDL{ diff --git a/server/ast/drop_sequence.go b/server/ast/drop_sequence.go index 11e01b2913..1c635bf91d 100644 --- a/server/ast/drop_sequence.go +++ b/server/ast/drop_sequence.go @@ -36,7 +36,7 @@ func nodeDropSequence(ctx *Context, node *tree.DropSequence) (vitess.Statement, return nil, err } if len(name.DbQualifier.String()) > 0 { - return nil, errors.Errorf("DROP SEQUENCE is currently only supported for the current database") + return nil, errors.Errorf("DROP SEQUENCE for the non-current database is not yet supported") } return vitess.InjectedStatement{ Statement: pgnodes.NewDropSequence(node.IfExists, name.SchemaQualifier.String(), name.Name.String(), diff --git a/server/ast/expr.go b/server/ast/expr.go index 8b2c95a1af..69e21b0ff3 100644 --- a/server/ast/expr.go +++ b/server/ast/expr.go @@ -90,7 +90,7 @@ func nodeVarName(ctx *Context, node tree.VarName) (vitess.Expr, error) { func nodeExpr(ctx *Context, node tree.Expr) (vitess.Expr, error) { switch node := node.(type) { case *tree.AllColumnsSelector: - return nil, errors.Errorf("table.* syntax is not yet supported in this context") + return nil, errors.Errorf("table.* syntax in this context is not yet supported") case *tree.AndExpr: left, err := nodeExpr(ctx, node.Left) if err != nil { @@ -838,10 +838,10 @@ func nodeExpr(ctx *Context, node tree.Expr) (vitess.Expr, error) { Children: vitess.Exprs{expr}, }, nil case tree.UnqualifiedStar: - return nil, errors.Errorf("* syntax is not yet supported in this context") + return nil, errors.Errorf("* syntax in this context is not yet supported") case *tree.UnresolvedName: if node.Star { - return nil, errors.Errorf("* syntax is not yet supported in this context") + return nil, errors.Errorf("* syntax in this context is not yet supported") } return unresolvedNameToColName(node) case nil: diff --git a/server/ast/limit.go b/server/ast/limit.go index b4f9c69e51..69ff270191 100644 --- a/server/ast/limit.go +++ b/server/ast/limit.go @@ -94,7 +94,7 @@ func int64ValueForLimit(l any) (int64, error) { case float32: limitValue = int64(l) default: - return 0, errors.Errorf("unsupported limit/offset value type %T", l) + return 0, errors.Errorf("limit/offset value type %T is not yet supported", l) } return limitValue, nil } diff --git a/server/ast/order_by.go b/server/ast/order_by.go index d17bed3487..91abbc3383 100644 --- a/server/ast/order_by.go +++ b/server/ast/order_by.go @@ -52,11 +52,11 @@ func nodeOrderBy(ctx *Context, node tree.OrderBy) (vitess.OrderBy, error) { // If the NULL order is explicitly declared, then we want to error rather than return incorrect results. case tree.NullsFirst: if direction != vitess.AscScr { - return nil, errors.Errorf("this NULL ordering is not yet supported for this ORDER BY direction") + return nil, errors.Errorf("this NULL ordering for this ORDER BY direction is not yet supported") } case tree.NullsLast: if direction != vitess.DescScr { - return nil, errors.Errorf("this NULL ordering is not yet supported for this ORDER BY direction") + return nil, errors.Errorf("this NULL ordering for this ORDER BY direction is not yet supported") } default: return nil, errors.Errorf("unknown NULL ordering in ORDER BY") diff --git a/server/ast/vacuum.go b/server/ast/vacuum.go index 9b0998b998..b2cea18d49 100755 --- a/server/ast/vacuum.go +++ b/server/ast/vacuum.go @@ -22,5 +22,5 @@ import ( // nodeVacuum handles *tree.Vacuum nodes, returning a NoOp statement that issues an unimplemented warning func nodeVacuum(_ *Context, _ *tree.Vacuum) (vitess.Statement, error) { - return NewNoOp([]string{"VACUUM is not supported"}), nil + return NewNoOp([]string{"VACUUM is not yet supported"}), nil } diff --git a/server/ast/where.go b/server/ast/where.go index 3811b43e1e..18c4dcfe9a 100644 --- a/server/ast/where.go +++ b/server/ast/where.go @@ -38,7 +38,7 @@ func nodeWhere(ctx *Context, node *tree.Where) (*vitess.Where, error) { case tree.AstHaving: whereType = vitess.HavingStr default: - return nil, errors.Errorf("WHERE-type statement not yet supported: `%s`", node.Type) + return nil, errors.Errorf("WHERE statement with type '%s' is not yet supported", node.Type) } return &vitess.Where{ Type: whereType, diff --git a/server/ast/with.go b/server/ast/with.go index a4289680b2..f1deb41675 100644 --- a/server/ast/with.go +++ b/server/ast/with.go @@ -36,7 +36,7 @@ func nodeCTE(ctx *Context, node *tree.CTE) (*vitess.CommonTableExpr, error) { subSelect, ok := node.Stmt.(*tree.Select) if !ok { - return nil, errors.Errorf("unsupported CTE statement type: %T", node.Stmt) + return nil, errors.Errorf("CTE statement type '%T' is not yet supported", node.Stmt) } selectStmt, err := nodeSelect(ctx, subSelect) diff --git a/testing/go/alter_test.go b/testing/go/alter_test.go index 5db0043c38..64522ef14d 100755 --- a/testing/go/alter_test.go +++ b/testing/go/alter_test.go @@ -28,7 +28,7 @@ func TestAlterStatements(t *testing.T) { ExpectedNotices: []ExpectedNotice{ { Severity: "WARNING", - Message: "owners are unsupported", + Message: "owners are not yet supported", }, }, }, @@ -45,7 +45,7 @@ func TestAlterStatements(t *testing.T) { ExpectedNotices: []ExpectedNotice{ { Severity: "WARNING", - Message: "owners are unsupported", + Message: "owners are not yet supported", }, }, }, @@ -62,7 +62,7 @@ func TestAlterStatements(t *testing.T) { ExpectedNotices: []ExpectedNotice{ { Severity: "WARNING", - Message: "owners are unsupported", + Message: "owners are not yet supported", }, }, }, @@ -79,7 +79,7 @@ func TestAlterStatements(t *testing.T) { ExpectedNotices: []ExpectedNotice{ { Severity: "WARNING", - Message: "owners are unsupported", + Message: "owners are not yet supported", }, }, }, @@ -96,7 +96,7 @@ func TestAlterStatements(t *testing.T) { ExpectedNotices: []ExpectedNotice{ { Severity: "WARNING", - Message: "owners are unsupported", + Message: "owners are not yet supported", }, }, }, @@ -113,7 +113,7 @@ func TestAlterStatements(t *testing.T) { ExpectedNotices: []ExpectedNotice{ { Severity: "WARNING", - Message: "owners are unsupported", + Message: "owners are not yet supported", }, }, }, diff --git a/testing/go/regression/tool/main.go b/testing/go/regression/tool/main.go index 4429b188c9..b1f56bdb53 100644 --- a/testing/go/regression/tool/main.go +++ b/testing/go/regression/tool/main.go @@ -56,30 +56,41 @@ func main() { fromSuccess := uint32(0) fromPartial := uint32(0) fromFail := uint32(0) + fromFailedToParse := uint32(0) + fromUnsupported := uint32(0) for _, tracker := range trackersFrom { fromTotal += tracker.Success fromTotal += tracker.Failed fromSuccess += tracker.Success fromPartial += tracker.PartialSuccess fromFail += tracker.Failed + fromFailedToParse += tracker.FailedToParse + fromUnsupported += tracker.Unsupported } toTotal := uint32(0) toSuccess := uint32(0) toPartial := uint32(0) toFail := uint32(0) + toFailedToParse := uint32(0) + toUnsupported := uint32(0) for _, tracker := range trackersTo { toTotal += tracker.Success toTotal += tracker.Failed toSuccess += tracker.Success toPartial += tracker.PartialSuccess toFail += tracker.Failed + toFailedToParse += tracker.FailedToParse + toUnsupported += tracker.Unsupported } sb := strings.Builder{} sb.WriteString("| | Main | PR |\n") sb.WriteString("| --- | --- | --- |\n") sb.WriteString(fmt.Sprintf("| Total | %d | %d |\n", fromTotal, toTotal)) sb.WriteString(fmt.Sprintf("| Successful | %d | %d |\n", fromSuccess, toSuccess)) - sb.WriteString(fmt.Sprintf("| Failures | %d | %d |\n", fromFail, toFail)) + sb.WriteString(fmt.Sprintf("| Total Failures | %d | %d |\n", fromFail, toFail)) + sb.WriteString(fmt.Sprintf("| Failed To Parse | %d | %d |\n", fromFailedToParse, toFailedToParse)) + sb.WriteString(fmt.Sprintf("| Unsupported | %d | %d |\n", fromUnsupported, toUnsupported)) + sb.WriteString(fmt.Sprintf("| Supported Failures | %d | %d |\n", fromFail-fromFailedToParse-fromUnsupported, toFail-toFailedToParse-toUnsupported)) sb.WriteString(fmt.Sprintf("| Partial Successes[^1] | %d | %d |\n", fromPartial, toPartial)) sb.WriteString("\n| | Main | PR |\n") sb.WriteString("| --- | --- | --- |\n") @@ -89,6 +100,9 @@ func main() { sb.WriteString(fmt.Sprintf("| Failures | %.4f%% | %.4f%% |\n", (float64(fromFail)/float64(fromTotal))*100.0, (float64(toFail)/float64(toTotal))*100.0)) + sb.WriteString(fmt.Sprintf("| Supported Failures | %.4f%% | %.4f%% |\n", + (float64(fromFail-fromFailedToParse-fromUnsupported)/float64(fromTotal))*100.0, + (float64(toFail-toFailedToParse-toUnsupported)/float64(toTotal))*100.0)) totalRegressions := 0 totalProgressions := 0 if len(trackersFrom) == len(trackersTo) { diff --git a/testing/go/regression/tool/replay.go b/testing/go/regression/tool/replay.go index 456d99b9a6..1378015ff0 100644 --- a/testing/go/regression/tool/replay.go +++ b/testing/go/regression/tool/replay.go @@ -153,6 +153,11 @@ ListenerLoop: } if expectedError == nil { if responseError != nil { + if strings.HasPrefix(responseError.Message, "at or near") { + tracker.FailedToParse++ + } else if strings.HasSuffix(responseError.Message, "not yet supported") { + tracker.Unsupported++ + } tracker.Failed++ tracker.AddFailure(ReplayTrackerItem{ Query: "DESCRIBE", @@ -283,6 +288,11 @@ ListenerLoop: } if expectedError == nil { if responseError != nil { + if strings.HasPrefix(responseError.Message, "at or near") { + tracker.FailedToParse++ + } else if strings.HasSuffix(responseError.Message, "not yet supported") { + tracker.Unsupported++ + } tracker.Failed++ tracker.AddFailure(ReplayTrackerItem{ Query: fmt.Sprintf("Function OID: %d", message.Function), @@ -408,6 +418,11 @@ ListenerLoop: } if expectedError == nil { if responseError != nil { + if strings.HasPrefix(responseError.Message, "at or near") { + tracker.FailedToParse++ + } else if strings.HasSuffix(responseError.Message, "not yet supported") { + tracker.Unsupported++ + } tracker.Failed++ tracker.AddFailure(ReplayTrackerItem{ Query: message.Query, @@ -554,6 +569,11 @@ ListenerLoop: } if expectedError == nil { if responseError != nil { + if strings.HasPrefix(responseError.Message, "at or near") { + tracker.FailedToParse++ + } else if strings.HasSuffix(responseError.Message, "not yet supported") { + tracker.Unsupported++ + } tracker.Failed++ tracker.AddFailure(ReplayTrackerItem{ Query: message.String, diff --git a/testing/go/regression/tool/replay_tracker.go b/testing/go/regression/tool/replay_tracker.go index 2afeee8955..377daf785b 100644 --- a/testing/go/regression/tool/replay_tracker.go +++ b/testing/go/regression/tool/replay_tracker.go @@ -29,6 +29,8 @@ type ReplayTracker struct { File string Success uint32 PartialSuccess uint32 + FailedToParse uint32 + Unsupported uint32 Failed uint32 SuccessItems []ReplayTrackerItem FailPartialItems []ReplayTrackerItem @@ -76,6 +78,8 @@ func SerializeTrackers(trackers ...*ReplayTracker) []byte { writer.String(tracker.File) writer.Uint32(tracker.Success) writer.Uint32(tracker.PartialSuccess) + writer.Uint32(tracker.FailedToParse) + writer.Uint32(tracker.Unsupported) writer.Uint32(tracker.Failed) writer.Uint32(uint32(len(tracker.SuccessItems))) for _, item := range tracker.SuccessItems { @@ -105,6 +109,8 @@ func DeserializeTrackers(data []byte) ([]*ReplayTracker, error) { trackers[trackerIdx].File = reader.String() trackers[trackerIdx].Success = reader.Uint32() trackers[trackerIdx].PartialSuccess = reader.Uint32() + trackers[trackerIdx].FailedToParse = reader.Uint32() + trackers[trackerIdx].Unsupported = reader.Uint32() trackers[trackerIdx].Failed = reader.Uint32() trackers[trackerIdx].SuccessItems = make([]ReplayTrackerItem, reader.Uint32()) for itemIdx := 0; itemIdx < len(trackers[trackerIdx].SuccessItems); itemIdx++ {