mirror of
https://github.com/dolthub/dolt.git
synced 2026-01-06 08:50:04 -06:00
Add engine tests for nonlocal tables
This commit is contained in:
@@ -1635,6 +1635,16 @@ func TestDiffSystemTablePrepared(t *testing.T) {
|
||||
RunDoltDiffSystemTableTestsPrepared(t, h)
|
||||
}
|
||||
|
||||
func TestNonlocalTable(t *testing.T) {
|
||||
h := newDoltEnginetestHarness(t)
|
||||
RunNonlocalTableTests(t, h)
|
||||
}
|
||||
|
||||
func TestNonlocalTablePrepared(t *testing.T) {
|
||||
h := newDoltEnginetestHarness(t)
|
||||
RunNonlocalTableTestsPrepared(t, h)
|
||||
}
|
||||
|
||||
func TestSchemaDiffTableFunction(t *testing.T) {
|
||||
harness := newDoltEnginetestHarness(t)
|
||||
RunSchemaDiffTableFunctionTests(t, harness)
|
||||
|
||||
@@ -1421,6 +1421,36 @@ func RunDoltDiffSystemTableTestsPrepared(t *testing.T, h DoltEnginetestHarness)
|
||||
}
|
||||
}
|
||||
|
||||
func RunNonlocalTableTests(t *testing.T, h DoltEnginetestHarness) {
|
||||
if !types.IsFormat_DOLT(types.Format_Default) {
|
||||
t.Skip("only new format support system table indexing")
|
||||
}
|
||||
|
||||
for _, test := range NonlocalScripts {
|
||||
t.Run(test.Name, func(t *testing.T) {
|
||||
h = h.NewHarness(t)
|
||||
defer h.Close()
|
||||
h.Setup(setup.MydbData)
|
||||
enginetest.TestScript(t, h, test)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func RunNonlocalTableTestsPrepared(t *testing.T, h DoltEnginetestHarness) {
|
||||
if !types.IsFormat_DOLT(types.Format_Default) {
|
||||
t.Skip("only new format support system table indexing")
|
||||
}
|
||||
|
||||
for _, test := range NonlocalScripts {
|
||||
t.Run(test.Name, func(t *testing.T) {
|
||||
h = h.NewHarness(t)
|
||||
defer h.Close()
|
||||
h.Setup(setup.MydbData)
|
||||
enginetest.TestScriptPrepared(t, h, test)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func RunSchemaDiffTableFunctionTests(t *testing.T, harness DoltEnginetestHarness) {
|
||||
for _, test := range SchemaDiffTableFunctionScriptTests {
|
||||
t.Run(test.Name, func(t *testing.T) {
|
||||
|
||||
186
go/libraries/doltcore/sqle/enginetest/dolt_queries_nonlocal.go
Normal file
186
go/libraries/doltcore/sqle/enginetest/dolt_queries_nonlocal.go
Normal file
@@ -0,0 +1,186 @@
|
||||
// Copyright 2022 Dolthub, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package enginetest
|
||||
|
||||
import (
|
||||
"github.com/dolthub/go-mysql-server/enginetest"
|
||||
"github.com/dolthub/go-mysql-server/enginetest/queries"
|
||||
"github.com/dolthub/go-mysql-server/sql"
|
||||
)
|
||||
|
||||
var _ enginetest.CustomValueValidator = &doltCommitValidator{}
|
||||
|
||||
var NonlocalScripts = []queries.ScriptTest{
|
||||
{
|
||||
Name: "basic nonlocal tables use case",
|
||||
SetUpScript: []string{
|
||||
"CALL DOLT_BRANCH('other')",
|
||||
"CREATE TABLE aliased_table (pk char(8) PRIMARY KEY);",
|
||||
"INSERT INTO aliased_table VALUES ('amzmapqt');",
|
||||
"CALL dolt_checkout('other');",
|
||||
`INSERT INTO dolt_nonlocal_tables(table_name, target_ref, ref_table, options) VALUES
|
||||
('nonlocal_table', 'main', 'aliased_table', 'immediate')`,
|
||||
`INSERT INTO nonlocal_table VALUES ('eesekkgo');`,
|
||||
`CREATE TABLE local_table (pk char(8) PRIMARY KEY, FOREIGN KEY (pk) REFERENCES nonlocal_table(pk));`,
|
||||
},
|
||||
Assertions: []queries.ScriptTestAssertion{
|
||||
{
|
||||
Query: "select * from nonlocal_table;",
|
||||
Expected: []sql.Row{{"amzmapqt"}, {"eesekkgo"}},
|
||||
},
|
||||
{
|
||||
Query: "select * from `mydb/main`.aliased_table;",
|
||||
Expected: []sql.Row{{"amzmapqt"}, {"eesekkgo"}},
|
||||
},
|
||||
{
|
||||
Query: "show create table nonlocal_table;",
|
||||
Expected: []sql.Row{{"aliased_table", "CREATE TABLE `aliased_table` (\n `pk` char(8) NOT NULL,\n PRIMARY KEY (`pk`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}},
|
||||
},
|
||||
{
|
||||
Query: "show create table local_table;",
|
||||
Expected: []sql.Row{{"local_table", "CREATE TABLE `local_table` (\n `pk` char(8) NOT NULL,\n PRIMARY KEY (`pk`),\n CONSTRAINT `local_table_ibfk_1` FOREIGN KEY (`pk`) REFERENCES `nonlocal_table` (`pk`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}},
|
||||
},
|
||||
{
|
||||
Query: `INSERT INTO local_table VALUES ("amzmapqt");`,
|
||||
ExpectedErr: nil,
|
||||
},
|
||||
{
|
||||
Query: `INSERT INTO local_table VALUES ("fdnfjfjf");`,
|
||||
ExpectedErrStr: "cannot add or update a child row - Foreign key violation on fk: `local_table_ibfk_1`, table: `local_table`, referenced table: `nonlocal_table`, key: `[fdnfjfjf]`",
|
||||
},
|
||||
{
|
||||
Query: `CALL DOLT_VERIFY_CONSTRAINTS('--all');`,
|
||||
Expected: []sql.Row{{0}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "detect foreign key invalidation is detected when rows are removed",
|
||||
SetUpScript: []string{
|
||||
"CALL DOLT_BRANCH('other')",
|
||||
"CREATE TABLE aliased_table (pk char(8) PRIMARY KEY);",
|
||||
"INSERT INTO aliased_table VALUES ('amzmapqt');",
|
||||
"CALL dolt_checkout('other');",
|
||||
`INSERT INTO dolt_nonlocal_tables(table_name, target_ref, ref_table, options) VALUES
|
||||
('nonlocal_table', 'main', 'aliased_table', 'immediate')`,
|
||||
`CREATE TABLE local_table (pk char(8) PRIMARY KEY, FOREIGN KEY (pk) REFERENCES nonlocal_table(pk));`,
|
||||
"INSERT INTO local_table VALUES ('amzmapqt');",
|
||||
"DELETE FROM `mydb/main`.aliased_table;",
|
||||
"set @@dolt_force_transaction_commit=1",
|
||||
},
|
||||
Assertions: []queries.ScriptTestAssertion{
|
||||
{
|
||||
Query: "CALL DOLT_VERIFY_CONSTRAINTS('--all');",
|
||||
Expected: []sql.Row{{1}},
|
||||
},
|
||||
{
|
||||
Query: "SELECT violation_type FROM dolt_constraint_violations_local_table",
|
||||
Expected: []sql.Row{{"foreign key"}},
|
||||
},
|
||||
{
|
||||
// Check that neither command removed the FK relation (this can happen if it thinks the child table was dropped)
|
||||
Query: "SHOW CREATE TABLE local_table;",
|
||||
Expected: []sql.Row{{"local_table", "CREATE TABLE `local_table` (\n `pk` char(8) NOT NULL,\n PRIMARY KEY (`pk`),\n CONSTRAINT `local_table_ibfk_1` FOREIGN KEY (`pk`) REFERENCES `nonlocal_table` (`pk`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "detect foreign key invalidation is detected when the nonlocal table is dropped",
|
||||
// DOLT_VERIFY_CONSTRAINTS detects constraint violations by attempting a merge against HEAD.
|
||||
// The current behavior for merges is to delete FK constraints if a table doesn't exist after the merge.
|
||||
// This is a bug with DOLT_VERIFY_CONSTRAINTS, not with nonlocal_tables. As a workaround,
|
||||
// the `dolt constraints verify` CLI command can detect these violations, which we confirm via nonlocal.bats
|
||||
Skip: true,
|
||||
SetUpScript: []string{
|
||||
"CREATE DATABASE IF NOT EXISTS mydb",
|
||||
"USE mydb",
|
||||
"CALL DOLT_BRANCH('other')",
|
||||
"CREATE TABLE aliased_table (pk char(8) PRIMARY KEY);",
|
||||
"INSERT INTO aliased_table VALUES ('amzmapqt');",
|
||||
"CALL dolt_checkout('other');",
|
||||
`INSERT INTO dolt_nonlocal_tables(table_name, target_ref, ref_table, options) VALUES
|
||||
('nonlocal_table', 'main', 'aliased_table', 'immediate')`,
|
||||
`CREATE TABLE local_table (pk char(8) PRIMARY KEY, FOREIGN KEY (pk) REFERENCES nonlocal_table(pk));`,
|
||||
"INSERT INTO local_table VALUES ('amzmapqt');",
|
||||
"DROP TABLE `mydb/main`.aliased_table;",
|
||||
"set @@dolt_force_transaction_commit=1",
|
||||
},
|
||||
Assertions: []queries.ScriptTestAssertion{
|
||||
{
|
||||
Query: "CALL DOLT_VERIFY_CONSTRAINTS('--all');",
|
||||
Expected: []sql.Row{{1}},
|
||||
},
|
||||
{
|
||||
Query: "SELECT violation_type FROM dolt_constraint_violations_local_table",
|
||||
Expected: []sql.Row{{"foreign key"}},
|
||||
},
|
||||
{
|
||||
// Check that neither command removed the FK relation (this can happen if it thinks the child table was dropped)
|
||||
Query: "SHOW CREATE TABLE local_table;",
|
||||
Expected: []sql.Row{{"local_table", "CREATE TABLE `local_table` (\n `pk` char(8) NOT NULL,\n PRIMARY KEY (`pk`),\n CONSTRAINT `local_table_ibfk_1` FOREIGN KEY (`pk`) REFERENCES `nonlocal_table` (`pk`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "creating a table matching a nonlocal table rule results in an error",
|
||||
SetUpScript: []string{
|
||||
"CALL DOLT_BRANCH('other')",
|
||||
`INSERT INTO dolt_nonlocal_tables(table_name, target_ref, options) VALUES
|
||||
("nonlocal_table", "main", "immediate")`,
|
||||
},
|
||||
Assertions: []queries.ScriptTestAssertion{
|
||||
{
|
||||
Query: "CREATE TABLE nonlocal_table (pk char(8) PRIMARY KEY);",
|
||||
ExpectedErrStr: "Cannot create table name nonlocal_table because it matches a name present in dolt_nonlocal_tables.",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "nonlocal tables appear in 'show tables'",
|
||||
SetUpScript: []string{
|
||||
"CALL DOLT_BRANCH('other')",
|
||||
"CREATE TABLE aliased_table (pk char(8) PRIMARY KEY);",
|
||||
"CREATE TABLE table_alias_1 (pk char(8) PRIMARY KEY);",
|
||||
"CREATE TABLE table_alias_wild_3 (pk char(8) PRIMARY KEY);",
|
||||
"INSERT INTO aliased_table VALUES ('amzmapqt');",
|
||||
"CALL dolt_checkout('other');",
|
||||
`INSERT INTO dolt_nonlocal_tables(table_name, target_ref, ref_table, options) VALUES
|
||||
("table_alias_1", "main", "", "immediate"),
|
||||
("table_alias_2", "main", "aliased_table", "immediate"),
|
||||
("table_alias_wild_*", "main", "", "immediate"),
|
||||
("table_alias_missing", "main", "", "immediate");`,
|
||||
},
|
||||
Assertions: []queries.ScriptTestAssertion{
|
||||
{
|
||||
Query: "show tables",
|
||||
Expected: []sql.Row{{"table_alias_1"}, {"table_alias_2"}, {"table_alias_wild_3"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "detect invalid options",
|
||||
SetUpScript: []string{
|
||||
"CALL dolt_checkout('-b', 'other');",
|
||||
`INSERT INTO dolt_nonlocal_tables(table_name, target_ref, options) VALUES
|
||||
("nonlocal_table", "main", "invalid");`,
|
||||
},
|
||||
Assertions: []queries.ScriptTestAssertion{
|
||||
{
|
||||
Query: "select * from nonlocal_table;",
|
||||
ExpectedErrStr: "Invalid nonlocal table options invalid: only valid value is 'immediate'.",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -10,28 +10,6 @@ teardown() {
|
||||
teardown_common
|
||||
}
|
||||
|
||||
@test "nonlocal: basic case" {
|
||||
dolt checkout -b other
|
||||
dolt sql <<SQL
|
||||
CALL dolt_checkout('main');
|
||||
CREATE TABLE aliased_table (pk char(8) PRIMARY KEY);
|
||||
INSERT INTO aliased_table VALUES ("amzmapqt");
|
||||
|
||||
CALL dolt_checkout('other');
|
||||
INSERT INTO dolt_nonlocal_tables(table_name, target_ref, ref_table, options) VALUES
|
||||
("table_alias_branch", "main", "aliased_table", "immediate");
|
||||
SQL
|
||||
|
||||
run dolt sql -q "select * from table_alias_branch;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "amzmapqt" ]] || false
|
||||
|
||||
# Nonlocal tables appear in "show create", but the output matches the aliased table.
|
||||
run dolt sql -q "show create table table_alias_branch"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "aliased_table" ]] || false
|
||||
}
|
||||
|
||||
@test "nonlocal: branch name reflects the working set of the referenced branch" {
|
||||
dolt checkout -b other
|
||||
dolt sql <<SQL
|
||||
@@ -261,16 +239,38 @@ SQL
|
||||
[[ "$output" =~ 'dolt_constraint_violations_local_table' ]] || false
|
||||
[[ "$output" =~ '| foreign key | eesekkgo | {"Index": "", "Table": "local_table", "Columns": ["pk"], "OnDelete": "RESTRICT", "OnUpdate": "RESTRICT", "ForeignKey": "local_table_ibfk_1", "ReferencedIndex": "", "ReferencedTable": "nonlocal_table", "ReferencedColumns": ["pk"]} |' ]] || false
|
||||
|
||||
run dolt sql -q "CALL DOLT_VERIFY_CONSTRAINTS('--all');"
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" =~ 'ForeignKey: local_table_ibfk_1' ]] || false
|
||||
|
||||
# Check that neither command removed the FK relation (this can happen if it thinks the child table was dropped)
|
||||
# Check that verifying didn't remove the FK relation (this can happen if it thinks the child table was dropped)
|
||||
run dolt sql -q 'SHOW CREATE TABLE local_table;'
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ 'local_table_ibfk_1' ]] || false
|
||||
}
|
||||
|
||||
@test "nonlocal: detect foreign key violations when rows are deleted from the nonlocal table" {
|
||||
dolt checkout -b other
|
||||
dolt sql <<SQL
|
||||
CALL DOLT_CHECKOUT('main');
|
||||
CREATE TABLE aliased_table (pk char(8) PRIMARY KEY);
|
||||
SQL
|
||||
|
||||
dolt sql <<SQL
|
||||
INSERT INTO dolt_nonlocal_tables(table_name, target_ref, ref_table, options) VALUES
|
||||
("nonlocal_table", "main", "aliased_table", "immediate");
|
||||
INSERT INTO nonlocal_table VALUES ("eesekkgo");
|
||||
CREATE TABLE local_table (pk char(8) PRIMARY KEY, FOREIGN KEY (pk) REFERENCES nonlocal_table(pk));
|
||||
SQL
|
||||
|
||||
dolt sql -q 'INSERT INTO local_table VALUES ("eesekkgo");'
|
||||
|
||||
run dolt sql -q 'INSERT INTO local_table VALUES ("fdnfjfjf");'
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" =~ 'Foreign key violation on fk: `local_table_ibfk_1`, table: `local_table`, referenced table: `nonlocal_table`, key: `[fdnfjfjf]`' ]] || false
|
||||
|
||||
# The current foreign keys hold, so they should validate
|
||||
dolt constraints verify
|
||||
|
||||
# It's possible for foreign keys on nonlocal tables to become invalidated due to changes on the nonlocal
|
||||
# branch, but this can be detected with dolt constraints verify
|
||||
|
||||
# Now try deleting the parent table and confirm that verifies correctly too.
|
||||
dolt sql -q 'CALL DOLT_CHECKOUT("main"); DROP TABLE aliased_table;'
|
||||
|
||||
# dolt sql -q "CALL DOLT_VERIFY_CONSTRAINTS('--all')"
|
||||
@@ -279,11 +279,6 @@ SQL
|
||||
echo "$output"
|
||||
[[ "$output" =~ 'table not found' ]] || false
|
||||
|
||||
run dolt sql -q "CALL DOLT_VERIFY_CONSTRAINTS('--all');"
|
||||
[ "$status" -eq 1 ]
|
||||
echo "$output"
|
||||
[[ "$output" =~ 'ForeignKey: local_table_ibfk_1' ]] || false
|
||||
|
||||
# Check that neither command removed the FK relation (this can happen if it thinks the child table was dropped)
|
||||
run dolt sql -q 'SHOW CREATE TABLE local_table;'
|
||||
[ "$status" -eq 0 ]
|
||||
@@ -357,58 +352,6 @@ SQL
|
||||
[[ "$output" =~ "nonlocal_table | true" ]] || false
|
||||
}
|
||||
|
||||
@test "nonlocal: invalid options detected" {
|
||||
dolt sql <<SQL
|
||||
INSERT INTO dolt_nonlocal_tables(table_name, target_ref, options) VALUES
|
||||
("nonlocal_table", "main", "invalid");
|
||||
SQL
|
||||
|
||||
run dolt sql -q "select * from nonlocal_table;"
|
||||
[ "$status" -eq 1 ]
|
||||
echo "$output"
|
||||
[[ "$output" =~ "Invalid nonlocal table options" ]] || false
|
||||
}
|
||||
|
||||
# The below tests are convenience features but not necessary for the MVP
|
||||
|
||||
@test "nonlocal: nonlocal tables appear in show_tables" {
|
||||
dolt checkout -b other
|
||||
dolt sql <<SQL
|
||||
CALL dolt_checkout('main');
|
||||
CREATE TABLE aliased_table (pk char(8) PRIMARY KEY);
|
||||
CREATE TABLE table_alias_1 (pk char(8) PRIMARY KEY);
|
||||
CREATE TABLE table_alias_wild_3 (pk char(8) PRIMARY KEY);
|
||||
INSERT INTO aliased_table VALUES ("amzmapqt");
|
||||
|
||||
CALL dolt_checkout('other');
|
||||
INSERT INTO dolt_nonlocal_tables(table_name, target_ref, ref_table, options) VALUES
|
||||
("table_alias_1", "main", "", "immediate"),
|
||||
("table_alias_2", "main", "aliased_table", "immediate"),
|
||||
("table_alias_wild_*", "main", "", "immediate"),
|
||||
("table_alias_missing", "main", "", "immediate");
|
||||
SQL
|
||||
|
||||
# Nonlocal tables should appear in "show tables"
|
||||
run dolt sql -q "show tables"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "table_alias_1" ]] || false
|
||||
[[ "$output" =~ "table_alias_2" ]] || false
|
||||
[[ "$output" =~ "table_alias_wild_3" ]] || false
|
||||
! [[ "$output" =~ "table_alias_missing" ]] || false
|
||||
}
|
||||
|
||||
@test "nonlocal: creating a table matching a nonlocal table rule results in an error" {
|
||||
dolt checkout -b other
|
||||
dolt sql <<SQL
|
||||
INSERT INTO dolt_nonlocal_tables(table_name, target_ref, options) VALUES
|
||||
("nonlocal_table", "main", "immediate");
|
||||
SQL
|
||||
|
||||
run dolt sql -q "CREATE TABLE nonlocal_table (pk char(8) PRIMARY KEY);"
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" =~ "Cannot create table name nonlocal_table because it matches a name present in dolt_nonlocal_tables." ]] || false
|
||||
}
|
||||
|
||||
@test "nonlocal: adding an existing table to nonlocal tables errors" {
|
||||
skip
|
||||
dolt checkout -b other
|
||||
@@ -417,6 +360,6 @@ SQL
|
||||
INSERT INTO dolt_nonlocal_tables(table_name, target_ref, options) VALUES
|
||||
("nonlocal_table", "main", "immediate");
|
||||
SQL
|
||||
[ "$status" -eq 0 ]
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" =~ "cannot make nonlocal table nonlocal_table, table already exists on branch other" ]] || false
|
||||
}
|
||||
Reference in New Issue
Block a user