Skip to content

Commit

Permalink
cdctest: fix fingerprint validator primary key cols check
Browse files Browse the repository at this point in the history
Previously, fingerprint validator could fail with sql smith due to precision
loss from JSON encoding & decoding of large numbers. We previously fixed the
validator regarding its values check. This patch fixes the primary key columns
check accordingly.

Part of: #124146
Release note: none
  • Loading branch information
wenyihu6 committed Jan 28, 2025
1 parent a89d274 commit c76b06d
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 48 deletions.
4 changes: 0 additions & 4 deletions pkg/ccl/changefeedccl/cdctest/nemeses.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,10 +240,6 @@ type NemesesOption struct {
var NemesesOptions = []NemesesOption{
{
EnableFpValidator: true,
EnableSQLSmith: false,
},
{
EnableFpValidator: false,
EnableSQLSmith: true,
},
}
Expand Down
53 changes: 9 additions & 44 deletions pkg/ccl/changefeedccl/cdctest/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -804,32 +804,16 @@ func (v *FingerprintValidator) applyRowUpdate(row validatorRow) (_err error) {
stmtBuf.WriteString(`)`)

// Also verify that the key matches the value.
type wrapper struct {
After map[string]interface{} `json:"after"`
}
var value wrapper
if err := gojson.Unmarshal([]byte(row.value), &value); err != nil {
return err
}
primaryKeyDatums := make([]interface{}, len(v.primaryKeyCols))
for idx, primaryKeyCol := range v.primaryKeyCols {
primaryKeyDatums[idx] = value.After[primaryKeyCol]
}
primaryKeyJSON, err := gojson.Marshal(primaryKeyDatums)
if err != nil {
return err
}

rowKey := row.key
if len(primaryKeyDatums) > 1 {
// format the key using the Go marshaller; otherwise, differences
// in formatting could lead to the comparison below failing
rowKey = asGoJSON(row.key)
}
if string(primaryKeyJSON) != rowKey {
v.failures = append(v.failures,
fmt.Sprintf(`key %s did not match expected key %s for value %s`,
rowKey, primaryKeyJSON, row.value))
valueJSON, err := afterJSON.FetchValKey(primaryKeyCol)
if err != nil {
return err
}
if rowKeyValue := keyJSONAsArray[idx]; valueJSON != rowKeyValue {
v.failures = append(v.failures,
fmt.Sprintf(`key %s did not match expected key %s for value %s`,
primaryKeyCol, rowKeyValue, valueJSON))
}
}
} else {
// DELETE
Expand Down Expand Up @@ -1096,22 +1080,3 @@ func fetchPrimaryKeyCols(sqlDB *gosql.DB, tableStr string) ([]string, error) {
}
return primaryKeyCols, nil
}

// asGoJSON tries to unmarshal the given string as JSON; if
// successful, the struct is marshalled back to JSON. This is to
// enforce the default formatting of the standard library marshaller,
// allowing comparisons of JSON strings when we don't control the
// formatting of the strings.
func asGoJSON(s string) string {
var obj interface{}
if err := gojson.Unmarshal([]byte(s), &obj); err != nil {
return s
}

blob, err := gojson.Marshal(obj)
if err != nil {
return s
}

return string(blob)
}

0 comments on commit c76b06d

Please sign in to comment.