Adding a new type for check constraint violation metadata

This commit is contained in:
Jason Fulghum
2023-05-22 10:11:26 -07:00
parent 5b64b0026b
commit ba3183cf90
3 changed files with 57 additions and 30 deletions

View File

@@ -500,20 +500,16 @@ func (cv checkValidator) validateDiff(ctx context.Context, diff tree.ThreeWayDif
// TODO: Add a test case for CHECK(NULL = NULL) something that will always return NULL
continue
} else if result == false {
// check failed!
conflictCount++
// TODO: This type is specific for Unique constraint violations; we need to create our own
foo := UniqCVMeta{
Columns: []string{"myColumns?"},
Name: checkName,
}
err = cv.insertArtifact(ctx, diff.Key, newTuple, foo)
meta, err := newCheckCVMeta(cv.sch, checkName)
if err != nil {
return 0, err
}
if err = cv.insertArtifact(ctx, diff.Key, newTuple, meta); err != nil {
return conflictCount, err
}
} else {
// TODO: Can result be anything else besides true false or nil?
//
return 0, fmt.Errorf("unexpected result from check constraint expression: %v", result)
}
}
@@ -522,7 +518,7 @@ func (cv checkValidator) validateDiff(ctx context.Context, diff tree.ThreeWayDif
// insertArtifact records a check constraint violation, as described by |meta|, for the row with the specified
// |key| and |value|.
func (cv checkValidator) insertArtifact(ctx context.Context, key, value val.Tuple, meta UniqCVMeta) error {
func (cv checkValidator) insertArtifact(ctx context.Context, key, value val.Tuple, meta CheckCVMeta) error {
vinfo, err := json.Marshal(meta)
if err != nil {
return err

View File

@@ -387,6 +387,8 @@ type FkCVMeta struct {
Table string `json:"Table"`
}
var _ types.JSONValue = FkCVMeta{}
func (m FkCVMeta) Unmarshall(ctx *sql.Context) (val types.JSONDocument, err error) {
return types.JSONDocument{Val: m}, nil
}

View File

@@ -104,25 +104,6 @@ func replaceUniqueKeyViolation(ctx context.Context, edt *prolly.ArtifactsEditor,
return nil
}
func replaceUniqueKeyViolationWithValue(ctx context.Context, edt *prolly.ArtifactsEditor, k, value val.Tuple, kd val.TupleDesc, theirRootIsh doltdb.Rootish, vInfo []byte, tblName string) error {
meta := prolly.ConstraintViolationMeta{
VInfo: vInfo,
Value: value,
}
theirsHash, err := theirRootIsh.HashOf()
if err != nil {
return err
}
err = edt.ReplaceConstraintViolation(ctx, k, theirsHash, prolly.ArtifactTypeUniqueKeyViol, meta)
if err != nil {
return err
}
return nil
}
func getPKFromSecondaryKey(pKB *val.TupleBuilder, pool pool.BuffPool, pkMapping val.OrdinalMapping, k val.Tuple) val.Tuple {
for to := range pkMapping {
from := pkMapping.MapOrdinal(to)
@@ -179,4 +160,52 @@ func (m NullViolationMeta) ToString(ctx *sql.Context) (string, error) {
return fmt.Sprintf("{Columns: [%s]}", strings.Join(m.Columns, ",")), nil
}
var _ types.JSONValue = FkCVMeta{}
// CheckCVMeta holds metadata describing a check constraint violation.
type CheckCVMeta struct {
Name string `json:"Name"`
Expression string `jason:"Expression"`
}
var _ types.JSONValue = CheckCVMeta{}
// newCheckCVMeta creates a new CheckCVMeta from a schema |sch| and a check constraint name |checkName|. If the
// check constraint is not found in the specified schema, an error is returned.
func newCheckCVMeta(sch schema.Schema, checkName string) (CheckCVMeta, error) {
found := false
var check schema.Check
for _, check = range sch.Checks().AllChecks() {
if check.Name() == checkName {
found = true
break
}
}
if !found {
return CheckCVMeta{}, fmt.Errorf("check constraint '%s' not found in schema", checkName)
}
return CheckCVMeta{
Name: check.Name(),
Expression: check.Expression(),
}, nil
}
// Unmarshall implements types.JSONValue
func (m CheckCVMeta) Unmarshall(_ *sql.Context) (val types.JSONDocument, err error) {
return types.JSONDocument{Val: m}, nil
}
// Compare implements types.JSONValue
func (m CheckCVMeta) Compare(ctx *sql.Context, v types.JSONValue) (cmp int, err error) {
ours := types.JSONDocument{Val: m}
return ours.Compare(ctx, v)
}
// ToString implements types.JSONValue
func (m CheckCVMeta) ToString(_ *sql.Context) (string, error) {
jsonStr := fmt.Sprintf(`{`+
`"Name": "%s", `+
`"Expression": "%s"}`,
m.Name,
m.Expression)
return jsonStr, nil
}