diff --git a/pkg/cmd/roachtest/tests/import.go b/pkg/cmd/roachtest/tests/import.go index 698e25b8585e..e745ed38570e 100644 --- a/pkg/cmd/roachtest/tests/import.go +++ b/pkg/cmd/roachtest/tests/import.go @@ -150,7 +150,7 @@ func registerImportTPCC(r registry.Registry) { } else { defer hc.Done() } - cmd := fmt.Sprintf(workloadStr, 1) + cmd := fmt.Sprintf(workloadStr, warehouses) // Tick once before starting the import, and once after to capture the // total elapsed time. This is used by roachperf to compute and display // the average MB/sec per node. diff --git a/pkg/sql/drop_owned_by.go b/pkg/sql/drop_owned_by.go index c5d99bda19c9..937ea90064af 100644 --- a/pkg/sql/drop_owned_by.go +++ b/pkg/sql/drop_owned_by.go @@ -9,17 +9,10 @@ import ( "context" "github.com/cockroachdb/cockroach/pkg/server/telemetry" - "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" "github.com/cockroachdb/cockroach/pkg/sql/sqltelemetry" "github.com/cockroachdb/cockroach/pkg/util/errorutil/unimplemented" ) -// dropOwnedByNode represents a DROP OWNED BY statement. -type dropOwnedByNode struct { - // TODO(angelaw): Uncomment when implementing - commenting out due to linting error. - //n *tree.DropOwnedBy -} - func (p *planner) DropOwnedBy(ctx context.Context) (planNode, error) { if err := checkSchemaChangeEnabled( ctx, @@ -32,11 +25,3 @@ func (p *planner) DropOwnedBy(ctx context.Context) (planNode, error) { // TODO(angelaw): Implementation. return nil, unimplemented.NewWithIssue(55381, "drop owned by is not yet implemented") } - -func (n *dropOwnedByNode) startExec(params runParams) error { - // TODO(angelaw): Implementation. - return nil -} -func (n *dropOwnedByNode) Next(runParams) (bool, error) { return false, nil } -func (n *dropOwnedByNode) Values() tree.Datums { return tree.Datums{} } -func (n *dropOwnedByNode) Close(context.Context) {} diff --git a/pkg/sql/explain_bundle_test.go b/pkg/sql/explain_bundle_test.go index 0baf88d1d4ba..381c4fec265b 100644 --- a/pkg/sql/explain_bundle_test.go +++ b/pkg/sql/explain_bundle_test.go @@ -276,11 +276,18 @@ CREATE TABLE users(id UUID DEFAULT gen_random_uuid() PRIMARY KEY, promo_id INT R }) t.Run("foreign keys", func(t *testing.T) { + // All tables should be included in the stmt bundle, regardless of which + // one we query because all of them are considered "related" (even + // though we don't specify ON DELETE and ON UPDATE actions). + tableNames := []string{"parent", "child1", "child2", "grandchild1", "grandchild2"} r.Exec(t, "CREATE TABLE parent (pk INT PRIMARY KEY, v INT);") - r.Exec(t, "CREATE TABLE child (pk INT PRIMARY KEY, fk INT REFERENCES parent(pk));") + r.Exec(t, "CREATE TABLE child1 (pk INT PRIMARY KEY, fk INT REFERENCES parent(pk));") + r.Exec(t, "CREATE TABLE child2 (pk INT PRIMARY KEY, fk INT REFERENCES parent(pk));") + r.Exec(t, "CREATE TABLE grandchild1 (pk INT PRIMARY KEY, fk INT REFERENCES child1(pk));") + r.Exec(t, "CREATE TABLE grandchild2 (pk INT PRIMARY KEY, fk INT REFERENCES child2(pk));") contentCheck := func(name, contents string) error { if name == "schema.sql" { - for _, tableName := range []string{"parent", "child"} { + for _, tableName := range tableNames { if regexp.MustCompile("CREATE TABLE defaultdb.public."+tableName).FindString(contents) == "" { return errors.Newf( "could not find 'CREATE TABLE defaultdb.public.%s' in schema.sql:\n%s", tableName, contents) @@ -289,12 +296,12 @@ CREATE TABLE users(id UUID DEFAULT gen_random_uuid() PRIMARY KEY, promo_id INT R } return nil } - for _, tableName := range []string{"parent", "child"} { + for _, tableName := range tableNames { rows := r.QueryStr(t, "EXPLAIN ANALYZE (DEBUG) SELECT * FROM "+tableName) checkBundle( t, fmt.Sprint(rows), "child", contentCheck, false, /* expectErrors */ - base, plans, "stats-defaultdb.public.parent.sql", "stats-defaultdb.public.child.sql", - "distsql.html vec.txt vec-v.txt", + base, plans, "stats-defaultdb.public.parent.sql", "stats-defaultdb.public.child1.sql", "stats-defaultdb.public.child2.sql", + "stats-defaultdb.public.grandchild1.sql", "stats-defaultdb.public.grandchild2.sql", "distsql.html vec.txt vec-v.txt", ) } }) diff --git a/pkg/sql/logictest/testdata/logic_test/txn b/pkg/sql/logictest/testdata/logic_test/txn index b9069f0a6a94..85063ed9feb3 100644 --- a/pkg/sql/logictest/testdata/logic_test/txn +++ b/pkg/sql/logictest/testdata/logic_test/txn @@ -1520,13 +1520,16 @@ SET SESSION AUTHORIZATION DEFAULT statement ok BEGIN -# DECLARE and FETCH CURSOR should work in a read-only txn. +# DECLARE, FETCH, and CLOSE CURSOR should work in a read-only txn. statement ok DECLARE foo CURSOR FOR SELECT 1 statement ok FETCH 1 foo +statement ok +CLOSE foo + statement ok COMMIT diff --git a/pkg/sql/opt/metadata.go b/pkg/sql/opt/metadata.go index d42a4dd5d76b..91863b77aab6 100644 --- a/pkg/sql/opt/metadata.go +++ b/pkg/sql/opt/metadata.go @@ -1007,49 +1007,43 @@ func (md *Metadata) getAllReferenceTables( var tableSet intsets.Fast var tableList []cat.DataSource var addForeignKeyReferencedTables func(tab cat.Table) + var addForeignKeyReferencingTables func(tab cat.Table) + // handleRelatedTables is a helper function that processes the given table + // if it hasn't been handled yet by adding all referenced and referencing + // table of the given one, including via transient (recursive) FK + // relationships. + handleRelatedTables := func(tabID cat.StableID) { + if !tableSet.Contains(int(tabID)) { + tableSet.Add(int(tabID)) + ds, _, err := catalog.ResolveDataSourceByID(ctx, cat.Flags{}, tabID) + if err != nil { + // This is a best-effort attempt to get all the tables, so don't + // error. + return + } + refTab, ok := ds.(cat.Table) + if !ok { + // This is a best-effort attempt to get all the tables, so don't + // error. + return + } + // We want to include all tables that we reference before adding + // ourselves, followed by all tables that reference us. + addForeignKeyReferencedTables(refTab) + tableList = append(tableList, ds) + addForeignKeyReferencingTables(refTab) + } + } addForeignKeyReferencedTables = func(tab cat.Table) { for i := 0; i < tab.OutboundForeignKeyCount(); i++ { tabID := tab.OutboundForeignKey(i).ReferencedTableID() - if !tableSet.Contains(int(tabID)) { - tableSet.Add(int(tabID)) - ds, _, err := catalog.ResolveDataSourceByID(ctx, cat.Flags{}, tabID) - if err != nil { - // This is a best-effort attempt to get all the tables, so don't error. - continue - } - refTab, ok := ds.(cat.Table) - if !ok { - // This is a best-effort attempt to get all the tables, so don't error. - continue - } - // We want to include all tables that we reference before adding - // ourselves. - addForeignKeyReferencedTables(refTab) - tableList = append(tableList, ds) - } + handleRelatedTables(tabID) } } - var addForeignKeyReferencingTables func(tab cat.Table) addForeignKeyReferencingTables = func(tab cat.Table) { for i := 0; i < tab.InboundForeignKeyCount(); i++ { tabID := tab.InboundForeignKey(i).OriginTableID() - if !tableSet.Contains(int(tabID)) { - tableSet.Add(int(tabID)) - ds, _, err := catalog.ResolveDataSourceByID(ctx, cat.Flags{}, tabID) - if err != nil { - // This is a best-effort attempt to get all the tables, so don't error. - continue - } - refTab, ok := ds.(cat.Table) - if !ok { - // This is a best-effort attempt to get all the tables, so don't error. - continue - } - // We want to include ourselves before all tables that reference - // us. - tableList = append(tableList, ds) - addForeignKeyReferencingTables(refTab) - } + handleRelatedTables(tabID) } } for i := range md.tables { diff --git a/pkg/sql/sem/tree/stmt.go b/pkg/sql/sem/tree/stmt.go index a5cdde453f9d..47bed5989f09 100644 --- a/pkg/sql/sem/tree/stmt.go +++ b/pkg/sql/sem/tree/stmt.go @@ -768,7 +768,7 @@ func (*CannedOptPlan) StatementTag() string { return "PREPARE AS OPT PLAN" } func (*CloseCursor) StatementReturnType() StatementReturnType { return Ack } // StatementType implements the Statement interface. -func (*CloseCursor) StatementType() StatementType { return TypeDCL } +func (*CloseCursor) StatementType() StatementType { return TypeDML } // StatementTag returns a short string identifying the type of statement. func (*CloseCursor) StatementTag() string { return "CLOSE" } diff --git a/pkg/sql/walk.go b/pkg/sql/walk.go index c265786768f5..d53afe016026 100644 --- a/pkg/sql/walk.go +++ b/pkg/sql/walk.go @@ -432,7 +432,6 @@ var planNodeNames = map[reflect.Type]string{ reflect.TypeOf(&ordinalityNode{}): "ordinality", reflect.TypeOf(&projectSetNode{}): "project set", reflect.TypeOf(&reassignOwnedByNode{}): "reassign owned by", - reflect.TypeOf(&dropOwnedByNode{}): "drop owned by", reflect.TypeOf(&recursiveCTENode{}): "recursive cte", reflect.TypeOf(&refreshMaterializedViewNode{}): "refresh materialized view", reflect.TypeOf(&relocateNode{}): "relocate",