# backup-dropped-descriptors tests backup and restore interaction with database, schema
# and type descriptors in the DROP state.
subtest dropped-database-descriptors

new-cluster name=s1
----

exec-sql
SET use_declarative_schema_changer = 'off';
----

exec-sql
SET CLUSTER SETTING jobs.debug.pausepoints = 'schemachanger.before.exec';
----

exec-sql
CREATE DATABASE d;
CREATE TABLE d.foo (id INT);
----

let $d_id
SELECT id FROM system.namespace WHERE name = 'd' AND "parentID" = 0;
----

schema-change expect-pausepoint
DROP DATABASE d CASCADE;
----
job paused at pausepoint

# At this point, we have a descriptor entry for `d` in a DROP state.
query-sql
WITH tbls AS (
	SELECT id, crdb_internal.pb_to_json('cockroach.sql.sqlbase.Descriptor', descriptor) AS orig FROM system.descriptor
)
SELECT orig->'database'->'name', orig->'database'->'state' FROM tbls WHERE id = $d_id;
----
"d" "DROP"

# A database backup should fail since we are explicitly targeting a dropped
# object.
exec-sql
BACKUP DATABASE d INTO 'nodelocal://1/dropped-database';
----
pq: failed to resolve targets specified in the BACKUP stmt: database "d" does not exist, or invalid RESTORE timestamp: supplied backups do not cover requested time

# A cluster backup should succeed but should ignore the dropped database
# and table descriptors.
exec-sql
BACKUP INTO 'nodelocal://1/cluster/dropped-database';
----

query-sql
SELECT count(*) FROM [SHOW BACKUP LATEST IN 'nodelocal://1/cluster/dropped-database'] WHERE object_name = 'd' OR object_name = 'foo';
----
0

# Now create another descriptor entry with the same name in a PUBLIC state.
exec-sql
CREATE DATABASE d;
CREATE TABLE d.bar (id INT);
----

# A database backup should succeed since we have a public database descriptor that matches the
# target.
exec-sql
BACKUP DATABASE d INTO 'nodelocal://1/dropped-database';
----

# A cluster backup should succeed and include the public database descriptor and
# its table.
exec-sql
BACKUP INTO 'nodelocal://1/cluster/dropped-database';
----

# Restore from the database backup to ensure it is valid.
# Sanity check that we did not backup the table 'foo' that belonged to the
# dropped database 'd'.
exec-sql
RESTORE DATABASE d FROM LATEST IN 'nodelocal://1/dropped-database' WITH new_db_name = 'd1';
----

exec-sql
USE d1;
----

query-sql
SELECT schema_name,table_name FROM [SHOW TABLES];
----
public bar

# Restore from the cluster backup to ensure it is valid.
# Sanity check that we did not backup the table 'foo' that belonged to the
# dropped database 'd'.
exec-sql
RESTORE DATABASE d FROM LATEST IN 'nodelocal://1/cluster/dropped-database' WITH new_db_name = 'd2';
----

exec-sql
USE d2;
----

query-sql
SELECT schema_name,table_name FROM [SHOW TABLES];
----
public bar

subtest end

# Test backup/restore interaction with dropped schema and type in a database.
subtest dropped-schema-descriptors

new-cluster name=s2
----

exec-sql
CREATE DATABASE d2;
----

exec-sql
CREATE TABLE d2.t2 (id INT);
----

exec-sql
CREATE TYPE d2.typ AS ENUM ('hello');
CREATE SCHEMA d2.s;
CREATE TABLE d2.s.t (id INT);
----

let $d2_id
SELECT id FROM system.namespace WHERE name = 'd2' AND "parentID" = 0;
----

let $s_id
SELECT id FROM system.namespace WHERE name = 's' AND "parentID" = $d2_id;
----

let $typ_id
SELECT id FROM system.namespace WHERE name = 'typ' AND "parentID" = $d2_id;
----

let $typArray_id
SELECT id FROM system.namespace WHERE name = '_typ' AND "parentID" = $d2_id;
----

exec-sql
SET use_declarative_schema_changer = 'off';
----

exec-sql
SET CLUSTER SETTING jobs.debug.pausepoints = 'schemachanger.before.exec';
----

schema-change expect-pausepoint
DROP SCHEMA d2.s CASCADE;
----
job paused at pausepoint

exec-sql
SET CLUSTER SETTING jobs.debug.pausepoints = 'typeschemachanger.before.exec';
----

schema-change expect-pausepoint
DROP TYPE d2.typ;
----
job paused at pausepoint

query-sql
WITH tbls AS (
	SELECT id, crdb_internal.pb_to_json('cockroach.sql.sqlbase.Descriptor', descriptor) AS orig FROM system.descriptor
)
SELECT orig->'schema'->'name', orig->'schema'->'state' FROM tbls WHERE id = $s_id;
----
"s" "DROP"


query-sql
WITH tbls AS (
	SELECT id, crdb_internal.pb_to_json('cockroach.sql.sqlbase.Descriptor', descriptor) AS orig FROM system.descriptor
)
SELECT orig->'type'->'name', orig->'type'->'state' FROM tbls WHERE id = $typ_id OR id = $typArray_id;
----
"typ" "DROP"
"_typ" "DROP"

# A database backup should succeed but should not include the dropped schema,
# type, and table.
exec-sql
BACKUP DATABASE d2 INTO 'nodelocal://1/dropped-schema-in-database';
----

query-sql
SELECT count(*) FROM [SHOW BACKUP LATEST IN 'nodelocal://1/dropped-schema-in-database'] WHERE
object_name = 's' OR object_name = 'typ';
----
0


# A cluster backup should succeed but should not include the dropped schema,
# type, and table.
exec-sql
BACKUP INTO 'nodelocal://1/cluster/dropped-schema-in-database';
----

query-sql
SELECT count(*) FROM [SHOW BACKUP LATEST IN 'nodelocal://1/cluster/dropped-schema-in-database']
WHERE object_name = 's' OR object_name = 'typ';
----
0

# Restore the backups to check they are valid.
exec-sql
RESTORE DATABASE d2 FROM LATEST IN 'nodelocal://1/dropped-schema-in-database' WITH new_db_name = 'd3';
----

exec-sql
USE d3;
----

# We don't expect to see the dropped schema 's'.
query-sql
SELECT schema_name FROM [SHOW SCHEMAS] ORDER BY 1;
----
crdb_internal
information_schema
pg_catalog
pg_extension
public

query-sql
SELECT schema_name, table_name FROM [SHOW TABLES];
----
public t2


exec-sql
RESTORE DATABASE d2 FROM LATEST IN 'nodelocal://1/cluster/dropped-schema-in-database' WITH new_db_name ='d4';
----

exec-sql
USE d4;
----

query-sql
SELECT schema_name FROM [SHOW SCHEMAS] ORDER BY 1;
----
crdb_internal
information_schema
pg_catalog
pg_extension
public

query-sql
SELECT schema_name, table_name FROM [SHOW TABLES];
----
public t2

subtest end
