statement error pq: crdb_internal.show_create_all_tables: database "d" does not exist
SELECT crdb_internal.show_create_all_tables('d')

statement ok
CREATE DATABASE d;
REVOKE CONNECT ON DATABASE d FROM public

query T
SELECT crdb_internal.show_create_all_tables('d')
----

statement ok
CREATE TABLE d.parent (
    x INT,
    y INT,
    z INT,
    UNIQUE (x, y, z),
    FAMILY f1 (x, y, z),
    UNIQUE (x)
);

statement ok
CREATE TABLE d.full_test (
    x INT,
    y INT,
    z INT,
    FOREIGN KEY (x, y, z) REFERENCES d.parent (x, y, z) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
    FAMILY f1 (x, y, z),
    UNIQUE (x)
  );

statement ok
ALTER TABLE d.full_test ADD CONSTRAINT test_fk FOREIGN KEY (x) REFERENCES d.parent (x) ON DELETE CASCADE

statement ok
CREATE VIEW d.vx AS SELECT 1

statement ok
CREATE SEQUENCE d.s

# parent should come before full_test due to dependency ordering.
# if dependency's aren't considered, full_test will appear first due to
# lexicographical ordering.
query T nosort
SELECT crdb_internal.show_create_all_tables('d')
----
CREATE TABLE public.parent (
    x INT8 NULL,
    y INT8 NULL,
    z INT8 NULL,
    rowid INT8 NOT VISIBLE NOT NULL DEFAULT unique_rowid(),
    CONSTRAINT parent_pkey PRIMARY KEY (rowid ASC),
    UNIQUE INDEX parent_x_y_z_key (x ASC, y ASC, z ASC),
    UNIQUE INDEX parent_x_key (x ASC),
    FAMILY f1 (x, y, z, rowid)
);
CREATE TABLE public.full_test (
    x INT8 NULL,
    y INT8 NULL,
    z INT8 NULL,
    rowid INT8 NOT VISIBLE NOT NULL DEFAULT unique_rowid(),
    CONSTRAINT full_test_pkey PRIMARY KEY (rowid ASC),
    UNIQUE INDEX full_test_x_key (x ASC),
    FAMILY f1 (x, y, z, rowid)
);
CREATE VIEW public.vx (
                                                                                                                                                                          "?column?"
) AS SELECT 1;
CREATE SEQUENCE public.s MINVALUE 1 MAXVALUE 9223372036854775807 INCREMENT 1 START 1;
ALTER TABLE public.full_test ADD CONSTRAINT full_test_x_y_z_fkey FOREIGN KEY (x, y, z) REFERENCES public.parent(x, y, z) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE public.full_test ADD CONSTRAINT test_fk FOREIGN KEY (x) REFERENCES public.parent(x) ON DELETE CASCADE;
-- Validate foreign key constraints. These can fail if there was unvalidated data during the SHOW CREATE ALL TABLES
ALTER TABLE public.full_test VALIDATE CONSTRAINT full_test_x_y_z_fkey;
ALTER TABLE public.full_test VALIDATE CONSTRAINT test_fk;

# testuser does not have CONNECT on database d and cannot see any tables.
user testuser

query T
SELECT crdb_internal.show_create_all_tables('d')
----

user root

statement ok
GRANT CREATE on DATABASE d TO testuser

# testuser should be able to see the descriptors with
# CREATE privilege on the database.
# TODO(richardjcai): Replace this with CONNECT and
# add CONNECT privilege required on the builtin description once #59676 is in.
query T nosort
SELECT crdb_internal.show_create_all_tables('d')
----
CREATE TABLE public.parent (
    x INT8 NULL,
    y INT8 NULL,
    z INT8 NULL,
    rowid INT8 NOT VISIBLE NOT NULL DEFAULT unique_rowid(),
    CONSTRAINT parent_pkey PRIMARY KEY (rowid ASC),
    UNIQUE INDEX parent_x_y_z_key (x ASC, y ASC, z ASC),
    UNIQUE INDEX parent_x_key (x ASC),
    FAMILY f1 (x, y, z, rowid)
);
CREATE TABLE public.full_test (
    x INT8 NULL,
    y INT8 NULL,
    z INT8 NULL,
    rowid INT8 NOT VISIBLE NOT NULL DEFAULT unique_rowid(),
    CONSTRAINT full_test_pkey PRIMARY KEY (rowid ASC),
    UNIQUE INDEX full_test_x_key (x ASC),
    FAMILY f1 (x, y, z, rowid)
);
CREATE VIEW public.vx (
                                                                                                                                                                          "?column?"
) AS SELECT 1;
CREATE SEQUENCE public.s MINVALUE 1 MAXVALUE 9223372036854775807 INCREMENT 1 START 1;
ALTER TABLE public.full_test ADD CONSTRAINT full_test_x_y_z_fkey FOREIGN KEY (x, y, z) REFERENCES public.parent(x, y, z) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE public.full_test ADD CONSTRAINT test_fk FOREIGN KEY (x) REFERENCES public.parent(x) ON DELETE CASCADE;
-- Validate foreign key constraints. These can fail if there was unvalidated data during the SHOW CREATE ALL TABLES
ALTER TABLE public.full_test VALIDATE CONSTRAINT full_test_x_y_z_fkey;
ALTER TABLE public.full_test VALIDATE CONSTRAINT test_fk;

user root

# Make sure temp tables don't show up in crdb_internal.show_create_all_tables.
statement ok
CREATE DATABASE temp_test

statement ok
USE temp_test

statement ok
SET experimental_enable_temp_tables = 'on'

statement ok
CREATE TEMPORARY TABLE t()

query T
SELECT crdb_internal.show_create_all_tables('temp_test')
----

# Test that a database with foreign keys has the right order.
statement ok
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
CREATE DATABASE test_fk_order;
USE test_fk_order;
-- B -> A
CREATE TABLE b (i int PRIMARY KEY);
CREATE TABLE a (i int REFERENCES b);
INSERT INTO b VALUES (1);
INSERT INTO a VALUES (1);
-- Test multiple tables to make sure transitive deps are sorted correctly.
-- E -> D -> C
-- G -> F -> D -> C
CREATE TABLE g (i int PRIMARY KEY);
CREATE TABLE f (i int PRIMARY KEY, g int REFERENCES g, FAMILY f1 (i, g));
CREATE TABLE e (i int PRIMARY KEY);
CREATE TABLE d (i int PRIMARY KEY, e int REFERENCES e, f int REFERENCES f, FAMILY f1 (i, e, f));
CREATE TABLE c (i int REFERENCES d);
-- Test a table that uses a sequence to make sure the sequence is dumped first.
CREATE SEQUENCE s;
CREATE TABLE s_tbl (id INT PRIMARY KEY DEFAULT nextval('s'), v INT,  FAMILY f1 (id, v));
COMMIT;

# Table order should be B, A, E, G, F, D, C, sequence s, s_tbl.
query T nosort
SELECT crdb_internal.show_create_all_tables('test_fk_order')
----
CREATE TABLE public.b (
    i INT8 NOT NULL,
    CONSTRAINT b_pkey PRIMARY KEY (i ASC)
);
CREATE TABLE public.a (
    i INT8 NULL,
    rowid INT8 NOT VISIBLE NOT NULL DEFAULT unique_rowid(),
    CONSTRAINT a_pkey PRIMARY KEY (rowid ASC)
);
CREATE TABLE public.g (
    i INT8 NOT NULL,
    CONSTRAINT g_pkey PRIMARY KEY (i ASC)
);
CREATE TABLE public.f (
    i INT8 NOT NULL,
    g INT8 NULL,
    CONSTRAINT f_pkey PRIMARY KEY (i ASC),
    FAMILY f1 (i, g)
);
CREATE TABLE public.e (
    i INT8 NOT NULL,
    CONSTRAINT e_pkey PRIMARY KEY (i ASC)
);
CREATE TABLE public.d (
    i INT8 NOT NULL,
    e INT8 NULL,
    f INT8 NULL,
    CONSTRAINT d_pkey PRIMARY KEY (i ASC),
    FAMILY f1 (i, e, f)
);
CREATE TABLE public.c (
                                                                                       i INT8 NULL,
                                                                                       rowid INT8 NOT VISIBLE NOT NULL DEFAULT unique_rowid(),
                                                                                       CONSTRAINT c_pkey PRIMARY KEY (rowid ASC)
);
CREATE SEQUENCE public.s MINVALUE 1 MAXVALUE 9223372036854775807 INCREMENT 1 START 1;
CREATE TABLE public.s_tbl (
                                                                                                                     id INT8 NOT NULL DEFAULT nextval('public.s'::REGCLASS),
                                                                                                                     v INT8 NULL,
                                                                                                                     CONSTRAINT s_tbl_pkey PRIMARY KEY (id ASC),
                                                                                                                     FAMILY f1 (id, v)
);
ALTER TABLE public.a ADD CONSTRAINT a_i_fkey FOREIGN KEY (i) REFERENCES public.b(i);
ALTER TABLE public.f ADD CONSTRAINT f_g_fkey FOREIGN KEY (g) REFERENCES public.g(i);
ALTER TABLE public.d ADD CONSTRAINT d_e_fkey FOREIGN KEY (e) REFERENCES public.e(i);
ALTER TABLE public.d ADD CONSTRAINT d_f_fkey FOREIGN KEY (f) REFERENCES public.f(i);
ALTER TABLE public.c ADD CONSTRAINT c_i_fkey FOREIGN KEY (i) REFERENCES public.d(i);
-- Validate foreign key constraints. These can fail if there was unvalidated data during the SHOW CREATE ALL TABLES
ALTER TABLE public.a VALIDATE CONSTRAINT a_i_fkey;
ALTER TABLE public.f VALIDATE CONSTRAINT f_g_fkey;
ALTER TABLE public.d VALIDATE CONSTRAINT d_e_fkey;
ALTER TABLE public.d VALIDATE CONSTRAINT d_f_fkey;
ALTER TABLE public.c VALIDATE CONSTRAINT c_i_fkey;

# Test that a cycle between two tables is handled correctly.
statement ok
CREATE DATABASE test_cycle;

statement ok
USE test_cycle;

statement ok
CREATE TABLE loop_a (
  id INT PRIMARY KEY,
  b_id INT,
  INDEX(b_id),
  FAMILY f1 (id, b_id)
);

statement ok
CREATE TABLE loop_b (
  id INT PRIMARY KEY,
  a_id INT REFERENCES loop_a ON DELETE CASCADE,
  FAMILY f1 (id, a_id)
);

statement ok
ALTER TABLE loop_a ADD CONSTRAINT b_id_delete_constraint
FOREIGN KEY (b_id) REFERENCES loop_b (id) ON DELETE CASCADE;

query T nosort
SELECT crdb_internal.show_create_all_tables('test_cycle')
----
CREATE TABLE public.loop_b (
    id INT8 NOT NULL,
    a_id INT8 NULL,
    CONSTRAINT loop_b_pkey PRIMARY KEY (id ASC),
    FAMILY f1 (id, a_id)
);
CREATE TABLE public.loop_a (
                                                                                                                                    id INT8 NOT NULL,
                                                                                                                                    b_id INT8 NULL,
                                                                                                                                    CONSTRAINT loop_a_pkey PRIMARY KEY (id ASC),
                                                                                                                                    INDEX loop_a_b_id_idx (b_id ASC),
                                                                                                                                    FAMILY f1 (id, b_id)
);
ALTER TABLE public.loop_b ADD CONSTRAINT loop_b_a_id_fkey FOREIGN KEY (a_id) REFERENCES public.loop_a(id) ON DELETE CASCADE;
ALTER TABLE public.loop_a ADD CONSTRAINT b_id_delete_constraint FOREIGN KEY (b_id) REFERENCES public.loop_b(id) ON DELETE CASCADE;
-- Validate foreign key constraints. These can fail if there was unvalidated data during the SHOW CREATE ALL TABLES
ALTER TABLE public.loop_b VALIDATE CONSTRAINT loop_b_a_id_fkey;
ALTER TABLE public.loop_a VALIDATE CONSTRAINT b_id_delete_constraint;

# Test that a primary key with a non-default name works.
statement ok
CREATE DATABASE test_primary_key;

statement ok
CREATE TABLE test_primary_key.t (
	i int,
	CONSTRAINT pk_name PRIMARY KEY (i)
);

query T
SELECT crdb_internal.show_create_all_tables('test_primary_key')
----
CREATE TABLE public.t (
    i INT8 NOT NULL,
    CONSTRAINT pk_name PRIMARY KEY (i ASC)
);

# Test that computed columns are shown correctly.
statement ok
CREATE DATABASE test_computed_column;
CREATE TABLE test_computed_column.t (
	a INT PRIMARY KEY,
	b INT AS (a + 1) STORED,
	FAMILY f1 (a, b)
);

query T
SELECT crdb_internal.show_create_all_tables('test_computed_column')
----
CREATE TABLE public.t (
    a INT8 NOT NULL,
    b INT8 NULL AS (a + 1:::INT8) STORED,
    CONSTRAINT t_pkey PRIMARY KEY (a ASC),
    FAMILY f1 (a, b)
);

# Test showing a table with a semicolon in the table, index, and
# column names properly escapes.
statement ok
CREATE DATABASE test_escaping;
CREATE TABLE test_escaping.";" (";" int, index (";"));
INSERT INTO test_escaping.";" VALUES (1);

query T
SELECT crdb_internal.show_create_all_tables('test_escaping')
----
CREATE TABLE public.";" (
    ";" INT8 NULL,
    rowid INT8 NOT VISIBLE NOT NULL DEFAULT unique_rowid(),
    CONSTRAINT ";_pkey" PRIMARY KEY (rowid ASC),
    INDEX ";_;_idx" (";" ASC)
);

# Ensure quotes in comments are properly escaped, also that the object names
# are properly escaped in the output of the COMMENT statements.
statement ok
CREATE DATABASE test_comment;
CREATE TABLE test_comment."t   t" ("x'" INT PRIMARY KEY);
COMMENT ON TABLE test_comment."t   t" IS 'has '' quotes';
COMMENT ON INDEX test_comment."t   t"@"t   t_pkey" IS 'has '' more '' quotes';
COMMENT ON COLUMN test_comment."t   t"."x'" IS 'i '' just '' love '' quotes';

query T
SELECT crdb_internal.show_create_all_tables('test_comment')
----
CREATE TABLE public."t   t" (
  "x'" INT8 NOT NULL,
  CONSTRAINT "t   t_pkey" PRIMARY KEY ("x'" ASC)
);
COMMENT ON TABLE public."t   t" IS e'has \' quotes';
COMMENT ON COLUMN public."t   t"."x'" IS e'i \' just \' love \' quotes';
COMMENT ON INDEX public."t   t"@"t   t_pkey" IS e'has \' more \' quotes';

# Ensure schemas are shown correctly.
statement ok
CREATE DATABASE test_schema;
USE test_schema;
CREATE SCHEMA sc1;
CREATE SCHEMA sc2;
CREATE TABLE sc1.t (x int);
CREATE TABLE sc2.t (x int);

query T nosort
SELECT crdb_internal.show_create_all_tables('test_schema')
----
CREATE TABLE sc1.t (
    x INT8 NULL,
    rowid INT8 NOT VISIBLE NOT NULL DEFAULT unique_rowid(),
    CONSTRAINT t_pkey PRIMARY KEY (rowid ASC)
);
CREATE TABLE sc2.t (
    x INT8 NULL,
    rowid INT8 NOT VISIBLE NOT NULL DEFAULT unique_rowid(),
    CONSTRAINT t_pkey PRIMARY KEY (rowid ASC)
);

# Ensure sequences are shown correctly.
statement ok
CREATE DATABASE test_sequence;
USE test_sequence;
CREATE SEQUENCE s1 INCREMENT 123;

query T
SELECT crdb_internal.show_create_all_tables('test_sequence')
----
CREATE SEQUENCE public.s1 MINVALUE 1 MAXVALUE 9223372036854775807 INCREMENT 123 START 1;

# Ensure that the builtin can be run in unused and used transactions.

statement ok
USE test_schema;

query T nosort
BEGIN;
SELECT crdb_internal.show_create_all_tables('test_schema');
COMMIT;
----
CREATE TABLE sc1.t (
    x INT8 NULL,
    rowid INT8 NOT VISIBLE NOT NULL DEFAULT unique_rowid(),
    CONSTRAINT t_pkey PRIMARY KEY (rowid ASC)
);
CREATE TABLE sc2.t (
    x INT8 NULL,
    rowid INT8 NOT VISIBLE NOT NULL DEFAULT unique_rowid(),
    CONSTRAINT t_pkey PRIMARY KEY (rowid ASC)
);

query T nosort
BEGIN;
SELECT * FROM sc1.t;
SELECT crdb_internal.show_create_all_tables('test_schema');
COMMIT;
----
CREATE TABLE sc1.t (
    x INT8 NULL,
    rowid INT8 NOT VISIBLE NOT NULL DEFAULT unique_rowid(),
    CONSTRAINT t_pkey PRIMARY KEY (rowid ASC)
);
CREATE TABLE sc2.t (
    x INT8 NULL,
    rowid INT8 NOT VISIBLE NOT NULL DEFAULT unique_rowid(),
    CONSTRAINT t_pkey PRIMARY KEY (rowid ASC)
);

# Regression test for not closing the ValueGenerators when they are recreated
# multiple times (#85418).
statement ok
CREATE DATABASE db_85418_1;
USE db_85418_1;
CREATE TABLE t_85418_1();
CREATE TABLE t_85418_2();
CREATE DATABASE db_85418_2;
USE db_85418_2;
CREATE TABLE t_85418_1();
CREATE TABLE t_85418_2();
CREATE TABLE dbs_85418(db STRING);
INSERT INTO dbs_85418 VALUES ('db_85418_1'), ('db_85418_2');
SELECT crdb_internal.show_create_all_tables(db) FROM dbs_85418;

# Make sure database names with hyphens work well.
statement ok
CREATE DATABASE "d-d";
USE "d-d";
CREATE TABLE t();
SELECT crdb_internal.show_create_all_tables('d-d');

# Make sure database names with quotes work well.
statement ok
CREATE DATABASE "a""bc";
USE "a""bc";
CREATE TABLE t();
SELECT crdb_internal.show_create_all_tables('a"bc');
