diff --git a/go/go.mod b/go/go.mod index 3234899fbf..aa4646fa35 100644 --- a/go/go.mod +++ b/go/go.mod @@ -18,7 +18,7 @@ require ( github.com/denisbrodbeck/machineid v1.0.1 github.com/dolthub/dolt/go/gen/proto/dolt/services/eventsapi v0.0.0-20201005193433-3ee972b1d078 github.com/dolthub/fslock v0.0.2 - github.com/dolthub/go-mysql-server v0.9.1-0.20210429131117-98b28e801d5e + github.com/dolthub/go-mysql-server v0.9.1-0.20210429162929-c9e737f45c0c github.com/dolthub/ishell v0.0.0-20210205014355-16a4ce758446 github.com/dolthub/mmap-go v1.0.4-0.20201107010347-f9f2a9588a66 github.com/dolthub/sqllogictest/go v0.0.0-20201105013724-5123fc66e12c diff --git a/go/go.sum b/go/go.sum index 1b32714738..6650d21aba 100644 --- a/go/go.sum +++ b/go/go.sum @@ -141,28 +141,14 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dolthub/fslock v0.0.2 h1:8vUh47iKovgrtXNrXVIzsIoWLlspoXg+3nslhUzgKSw= github.com/dolthub/fslock v0.0.2/go.mod h1:0i7bsNkK+XHwFL3dIsSWeXSV7sykVzzVr6+jq8oeEo0= -github.com/dolthub/go-mysql-server v0.9.1-0.20210427170653-4c27cebe7aa4 h1:G7IZ72sHvqp+TVGXOgBIqbUt9/JK2KYTLJYJwhV7W3o= -github.com/dolthub/go-mysql-server v0.9.1-0.20210427170653-4c27cebe7aa4/go.mod h1:lKviZJ3QgD8TB9NrGWR080mHRQya+w+YHlme2JF4y5U= -github.com/dolthub/go-mysql-server v0.9.1-0.20210427205316-55a901baef57 h1:WScama5rl/VsxTsrE5N3JHFA+RCYVrLKXhyMRGGOUD8= -github.com/dolthub/go-mysql-server v0.9.1-0.20210427205316-55a901baef57/go.mod h1:pc7zTsq8iYnNs2TMh6WybMT5SLyBlQkqTggEylUC9d4= -github.com/dolthub/go-mysql-server v0.9.1-0.20210428113713-7a761467da9d h1:k1wyWcw4wG+JqmWZO6mBzLcvsLaKMWf9KSbR4YVcVgQ= -github.com/dolthub/go-mysql-server v0.9.1-0.20210428113713-7a761467da9d/go.mod h1:QvgaFqG0Mbg3BXS9vXhBltNEG2lsBvkMI+gCzOsetxo= -github.com/dolthub/go-mysql-server v0.9.1-0.20210428172146-87a95a1dc3bf h1:+LCmTo9xZvBltnYBIxdCATO/0gf0/9463NJ0h9WWpQw= -github.com/dolthub/go-mysql-server v0.9.1-0.20210428172146-87a95a1dc3bf/go.mod h1:raUDli6MJt8QRP7LrXXJqnPrPA0Cjnt4Y/R/HVMGHGw= -github.com/dolthub/go-mysql-server v0.9.1-0.20210429131117-98b28e801d5e h1:cxOaU28lUDI3IeI2UUsnT1icXll1LIfqcI2jLGb7hiY= -github.com/dolthub/go-mysql-server v0.9.1-0.20210429131117-98b28e801d5e/go.mod h1:raUDli6MJt8QRP7LrXXJqnPrPA0Cjnt4Y/R/HVMGHGw= +github.com/dolthub/go-mysql-server v0.9.1-0.20210429162929-c9e737f45c0c h1:f7PePb8AkQogPBzgPzlS2bzwGbIZnr4ScgSoCsJpRgg= +github.com/dolthub/go-mysql-server v0.9.1-0.20210429162929-c9e737f45c0c/go.mod h1:raUDli6MJt8QRP7LrXXJqnPrPA0Cjnt4Y/R/HVMGHGw= github.com/dolthub/ishell v0.0.0-20210205014355-16a4ce758446 h1:0ol5pj+QlKUKAtqs1LiPM3ZJKs+rHPgLSsMXmhTrCAM= github.com/dolthub/ishell v0.0.0-20210205014355-16a4ce758446/go.mod h1:dhGBqcCEfK5kuFmeO5+WOx3hqc1k3M29c1oS/R7N4ms= github.com/dolthub/mmap-go v1.0.4-0.20201107010347-f9f2a9588a66 h1:WRPDbpJWEnPxPmiuOTndT+lUWUeGjx6eoNOK9O4tQQQ= github.com/dolthub/mmap-go v1.0.4-0.20201107010347-f9f2a9588a66/go.mod h1:N5ZIbMGuDUpTpOFQ7HcsN6WSIpTGQjHP+Mz27AfmAgk= github.com/dolthub/sqllogictest/go v0.0.0-20201105013724-5123fc66e12c h1:ZIo6IOXU3/rJK4lp83QRq1zGhQrjQQtlmE2b7H1Vv/k= github.com/dolthub/sqllogictest/go v0.0.0-20201105013724-5123fc66e12c/go.mod h1:siLfyv2c92W1eN/R4QqG/+RjjX5W2+gCTRjZxBjI3TY= -github.com/dolthub/vitess v0.0.0-20210423125910-e55ee465c2e8 h1:DEFVTB71AdE6vbX1FbtVWRJr+bui8RMfw+U0NnQoGnc= -github.com/dolthub/vitess v0.0.0-20210423125910-e55ee465c2e8/go.mod h1:hUE8oSk2H5JZnvtlLBhJPYC8WZCA5AoSntdLTcBvdBM= -github.com/dolthub/vitess v0.0.0-20210427161911-b5436daa695a h1:W/pWfKFW8vnLf3LYwMt0rmvTC9fK2P9YBJuYD2XxLT4= -github.com/dolthub/vitess v0.0.0-20210427161911-b5436daa695a/go.mod h1:hUE8oSk2H5JZnvtlLBhJPYC8WZCA5AoSntdLTcBvdBM= -github.com/dolthub/vitess v0.0.0-20210428104209-a5f7932c1bc0 h1:o7g8HXUa3A+weA86zj5evLNTyG8WFmXXyE7Vv5OWv7k= -github.com/dolthub/vitess v0.0.0-20210428104209-a5f7932c1bc0/go.mod h1:hUE8oSk2H5JZnvtlLBhJPYC8WZCA5AoSntdLTcBvdBM= github.com/dolthub/vitess v0.0.0-20210428165934-5801b1103b04 h1:yvfUh1EqwPu10H9VpaUxBEWzqKUmKxsW689ufJWNLsg= github.com/dolthub/vitess v0.0.0-20210428165934-5801b1103b04/go.mod h1:hUE8oSk2H5JZnvtlLBhJPYC8WZCA5AoSntdLTcBvdBM= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= diff --git a/go/libraries/doltcore/fkconstrain/checks.go b/go/libraries/doltcore/fkconstrain/checks.go index 3f49c9b881..aa5ede1a07 100644 --- a/go/libraries/doltcore/fkconstrain/checks.go +++ b/go/libraries/doltcore/fkconstrain/checks.go @@ -101,7 +101,7 @@ func (chk check) ColsIntersectChanges(changes map[uint64]bool) bool { } func (chk check) NewErrForKey(key types.Tuple) error { - return &ForeignKeyError{ + return &GenericForeignKeyError{ tableName: chk.fk.TableName, referencedTableName: chk.fk.ReferencedTableName, fkName: chk.fk.Name, diff --git a/go/libraries/doltcore/fkconstrain/errors.go b/go/libraries/doltcore/fkconstrain/errors.go index 831ded7e4d..40232d6761 100644 --- a/go/libraries/doltcore/fkconstrain/errors.go +++ b/go/libraries/doltcore/fkconstrain/errors.go @@ -19,19 +19,20 @@ import ( "fmt" ) -var ErrForeignKeyConstraintViolation = errors.New("foreign key constraint violation") +var ErrGenericForeignKeyConstraintViolation = errors.New("foreign key constraint violation") -type ForeignKeyError struct { +// This represents a commit time violation that is different from the FK errors in go-mysql-server (sql/errors.go) +type GenericForeignKeyError struct { tableName string referencedTableName string fkName string keyStr string } -func (err *ForeignKeyError) Error() string { +func (err *GenericForeignKeyError) Error() string { return fmt.Sprintf("Foreign key violation on fk: `%s`, table: `%s`, referenced table: `%s`, key: `%s`", err.fkName, err.tableName, err.referencedTableName, err.keyStr) } -func (err *ForeignKeyError) Unwrap() error { - return ErrForeignKeyConstraintViolation +func (err *GenericForeignKeyError) Unwrap() error { + return ErrGenericForeignKeyConstraintViolation } diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index 81835c1696..27a5e12517 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -145,6 +145,10 @@ func TestInsertInto(t *testing.T) { enginetest.TestInsertInto(t, newDoltHarness(t)) } +func TestInsertIgnoreInto(t *testing.T) { + enginetest.TestInsertIgnoreInto(t, newDoltHarness(t)) +} + func TestInsertIntoErrors(t *testing.T) { enginetest.TestInsertIntoErrors(t, newDoltHarness(t)) } diff --git a/go/libraries/doltcore/sqle/sqlddl_test.go b/go/libraries/doltcore/sqle/sqlddl_test.go index 52bdbfdfb7..8a4074da1a 100644 --- a/go/libraries/doltcore/sqle/sqlddl_test.go +++ b/go/libraries/doltcore/sqle/sqlddl_test.go @@ -1519,19 +1519,19 @@ INSERT INTO child_non_unq VALUES ('1', 1), ('2', NULL), ('3', 3), ('4', 3), ('5' // insert tests against foreign key _, err = ExecuteSql(dEnv, root, "INSERT INTO child VALUES ('9', 9)") if assert.Error(t, err) { - assert.Contains(t, err.Error(), "foreign key violation") + assert.Contains(t, err.Error(), "Foreign key violation") } _, err = ExecuteSql(dEnv, root, "INSERT INTO child_idx VALUES ('9', 9)") if assert.Error(t, err) { - assert.Contains(t, err.Error(), "foreign key violation") + assert.Contains(t, err.Error(), "Foreign key violation") } _, err = ExecuteSql(dEnv, root, "INSERT INTO child_unq VALUES ('9', 9)") if assert.Error(t, err) { - assert.Contains(t, err.Error(), "foreign key violation") + assert.Contains(t, err.Error(), "Foreign key violation") } _, err = ExecuteSql(dEnv, root, "INSERT INTO child_non_unq VALUES ('9', 9)") if assert.Error(t, err) { - assert.Contains(t, err.Error(), "foreign key violation") + assert.Contains(t, err.Error(), "Foreign key violation") } } diff --git a/go/libraries/doltcore/table/editor/sessioned_table_editor.go b/go/libraries/doltcore/table/editor/sessioned_table_editor.go index 169d224363..69619b44bd 100644 --- a/go/libraries/doltcore/table/editor/sessioned_table_editor.go +++ b/go/libraries/doltcore/table/editor/sessioned_table_editor.go @@ -18,11 +18,12 @@ import ( "context" "fmt" - "github.com/dolthub/dolt/go/store/hash" + "github.com/dolthub/go-mysql-server/sql" "github.com/dolthub/dolt/go/libraries/doltcore/doltdb" "github.com/dolthub/dolt/go/libraries/doltcore/row" "github.com/dolthub/dolt/go/libraries/doltcore/schema" + "github.com/dolthub/dolt/go/store/hash" "github.com/dolthub/dolt/go/store/types" ) @@ -198,8 +199,7 @@ func (ste *sessionedTableEditor) handleReferencingRowsOnDelete(ctx context.Conte } case doltdb.ForeignKeyReferenceOption_DefaultAction, doltdb.ForeignKeyReferenceOption_NoAction, doltdb.ForeignKeyReferenceOption_Restrict: indexKeyStr, _ := types.EncodedValue(ctx, indexKey) - return fmt.Errorf("foreign key constraint violation on `%s`.`%s`: cannot delete rows with value `%s`", - foreignKey.TableName, foreignKey.Name, indexKeyStr) + return sql.ErrForeignKeyChildViolation.New(foreignKey.Name, foreignKey.TableName, foreignKey.ReferencedTableName, indexKeyStr) default: return fmt.Errorf("unknown ON DELETE reference option on `%s`: `%s`", foreignKey.Name, foreignKey.OnDelete.String()) } @@ -305,8 +305,7 @@ func (ste *sessionedTableEditor) handleReferencingRowsOnUpdate(ctx context.Conte } case doltdb.ForeignKeyReferenceOption_DefaultAction, doltdb.ForeignKeyReferenceOption_NoAction, doltdb.ForeignKeyReferenceOption_Restrict: indexKeyStr, _ := types.EncodedValue(ctx, indexKey) - return fmt.Errorf("foreign key constraint violation on `%s`.`%s`: cannot update rows with value `%s`", - foreignKey.TableName, foreignKey.Name, indexKeyStr) + return sql.ErrForeignKeyParentViolation.New(foreignKey.Name, foreignKey.TableName, foreignKey.ReferencedTableName, indexKeyStr) default: return fmt.Errorf("unknown ON UPDATE reference option on `%s`: `%s`", foreignKey.Name, foreignKey.OnUpdate.String()) } @@ -439,7 +438,7 @@ func (ste *sessionedTableEditor) validateForInsert(ctx context.Context, taggedVa } } indexKeyStr, _ := types.EncodedValue(ctx, indexKey) - return fmt.Errorf("foreign key violation on `%s`.`%s`: `%s`", foreignKey.TableName, foreignKey.Name, indexKeyStr) + return sql.ErrForeignKeyChildViolation.New(foreignKey.Name, foreignKey.TableName, foreignKey.ReferencedTableName, indexKeyStr) } } return nil diff --git a/integration-tests/bats/foreign-keys.bats b/integration-tests/bats/foreign-keys.bats index 2bba9fcc7c..57db359b73 100644 --- a/integration-tests/bats/foreign-keys.bats +++ b/integration-tests/bats/foreign-keys.bats @@ -1708,3 +1708,74 @@ SQL [ "$status" -eq "0" ] [[ "$output" =~ 'child2_fk' ]] || false } + +@test "foreign-keys: child violation correctly detected" { + dolt sql <