# Disable declarative schema changer for this test.
statement ok
SET CLUSTER SETTING sql.defaults.use_declarative_schema_changer = 'off';

statement ok;
SET use_declarative_schema_changer = 'off';

# These test verify that a user's job are visible via
# crdb_internal.jobs and SHOW JOBS.

user root

statement ok
GRANT ALL ON DATABASE test TO testuser

statement ok
CREATE TABLE t(x INT);

statement ok
INSERT INTO t(x) VALUES (1);

statement ok
CREATE INDEX ON t(x)

query TTT
SELECT job_type, description, user_name FROM [SHOW JOBS] WHERE user_name = 'root'
AND job_type LIKE 'SCHEMA CHANGE%' ORDER BY 1, 2, 3
----
SCHEMA CHANGE     CREATE INDEX ON test.public.t (x)                  root
SCHEMA CHANGE     updating privileges for database 104               root
SCHEMA CHANGE     updating version for role membership table         root
SCHEMA CHANGE     updating version for role options table            root
SCHEMA CHANGE     updating version for users table                   root
SCHEMA CHANGE GC  GC for temporary index used during index backfill  root

query TTT
SELECT job_type, description, user_name FROM crdb_internal.jobs WHERE user_name = 'root'
AND job_type LIKE 'SCHEMA CHANGE%' ORDER BY 1, 2, 3
----
SCHEMA CHANGE     CREATE INDEX ON test.public.t (x)                  root
SCHEMA CHANGE     updating privileges for database 104               root
SCHEMA CHANGE     updating version for role membership table         root
SCHEMA CHANGE     updating version for role options table            root
SCHEMA CHANGE     updating version for users table                   root
SCHEMA CHANGE GC  GC for temporary index used during index backfill  root

query TTT
SELECT job_type, description, user_name FROM crdb_internal.jobs WHERE user_name = 'node'
AND job_type LIKE 'AUTO SPAN%'
----
AUTO SPAN CONFIG RECONCILIATION  reconciling span configurations                   node

user testuser

# a non-admin user cannot see the admin jobs

query TTT
SELECT job_type, description, user_name FROM [SHOW JOBS]
----

query TTT
SELECT job_type, description, user_name FROM crdb_internal.jobs
----

# However they can see their own jobs.

statement ok
CREATE TABLE u(x INT); INSERT INTO u(x) VALUES (1)

statement ok
CREATE INDEX ON u(x);


query TTT
SELECT job_type, description, user_name FROM [SHOW JOBS] ORDER BY 1, 2, 3
----
SCHEMA CHANGE     CREATE INDEX ON test.public.u (x)                  testuser
SCHEMA CHANGE GC  GC for temporary index used during index backfill  testuser

query TTT
SELECT job_type, description, user_name FROM crdb_internal.jobs ORDER BY 1, 2, 3
----
SCHEMA CHANGE     CREATE INDEX ON test.public.u (x)                  testuser
SCHEMA CHANGE GC  GC for temporary index used during index backfill  testuser

# And root can see both.

user root

query TTT
SELECT job_type, description, user_name FROM [SHOW JOBS] WHERE user_name IN ('root', 'testuser', 'node')
AND job_type LIKE 'SCHEMA CHANGE%' ORDER BY 1, 2, 3
----
SCHEMA CHANGE     CREATE INDEX ON test.public.t (x)                  root
SCHEMA CHANGE     CREATE INDEX ON test.public.u (x)                  testuser
SCHEMA CHANGE     updating privileges for database 104               root
SCHEMA CHANGE     updating version for role membership table         root
SCHEMA CHANGE     updating version for role options table            root
SCHEMA CHANGE     updating version for users table                   root
SCHEMA CHANGE GC  GC for temporary index used during index backfill  root
SCHEMA CHANGE GC  GC for temporary index used during index backfill  testuser

query TTT
SELECT job_type, description, user_name FROM crdb_internal.jobs WHERE user_name IN ('root', 'testuser', 'node')
AND (job_type LIKE 'AUTO SPAN%' OR job_type LIKE 'SCHEMA CHANGE%') ORDER BY 1, 2, 3
----
AUTO SPAN CONFIG RECONCILIATION  reconciling span configurations                    node
SCHEMA CHANGE                    CREATE INDEX ON test.public.t (x)                  root
SCHEMA CHANGE                    CREATE INDEX ON test.public.u (x)                  testuser
SCHEMA CHANGE                    updating privileges for database 104               root
SCHEMA CHANGE                    updating version for role membership table         root
SCHEMA CHANGE                    updating version for role options table            root
SCHEMA CHANGE                    updating version for users table                   root
SCHEMA CHANGE GC                 GC for temporary index used during index backfill  root
SCHEMA CHANGE GC                 GC for temporary index used during index backfill  testuser

statement ok
CREATE USER testuser2

statement ok
GRANT CREATE ON DATABASE test TO testuser2

statement ok
ALTER ROLE testuser CONTROLJOB

user testuser2

statement ok
CREATE TABLE t1(x INT);

statement ok
INSERT INTO t1(x) VALUES (1);

statement ok
CREATE INDEX ON t1(x);

statement ok
DROP TABLE t1

user testuser

# testuser should be able to see all jobs
query TTT
SELECT job_type, description, user_name FROM crdb_internal.jobs WHERE job_type = 'SCHEMA CHANGE GC' ORDER BY 1, 2, 3
----
SCHEMA CHANGE GC  GC for DROP TABLE test.public.t1                   testuser2
SCHEMA CHANGE GC  GC for temporary index used during index backfill  root
SCHEMA CHANGE GC  GC for temporary index used during index backfill  testuser
SCHEMA CHANGE GC  GC for temporary index used during index backfill  testuser2

statement ok
PAUSE JOB (SELECT job_id FROM [SHOW JOBS] WHERE user_name = 'testuser2' AND job_type = 'SCHEMA CHANGE GC' AND description LIKE 'GC for DROP%')

user root

statement ok
CREATE TABLE t2(x INT);
DROP TABLE t2

let $job_id
SELECT job_id FROM [SHOW JOBS] WHERE user_name = 'root' AND job_type = 'SCHEMA CHANGE GC' AND description LIKE 'GC for DROP%'

user testuser

statement error only admins can control jobs owned by other admins
PAUSE JOB (SELECT $job_id)

user root

# Remove CONTROLJOB from testuser
statement ok
ALTER ROLE testuser NOCONTROLJOB

let $job_id
SELECT job_id FROM [SHOW JOBS] WHERE user_name = 'testuser2' AND job_type = 'SCHEMA CHANGE GC' AND description LIKE 'GC for DROP%'

user testuser

# testuser should no longer have the ability to control jobs.
statement error user testuser does not have privileges for job
PAUSE JOB (SELECT $job_id)

statement error user testuser does not have privileges for job
CANCEL JOB (SELECT $job_id)

statement error user testuser does not have privileges for job
RESUME JOB (SELECT $job_id)

user root

statement ok
GRANT SYSTEM VIEWJOB TO testuser

user testuser

# testuser should be able to see all jobs
query TTT
SELECT job_type, description, user_name FROM crdb_internal.jobs WHERE job_type = 'SCHEMA CHANGE GC' ORDER BY 1, 2, 3
----
SCHEMA CHANGE GC  GC for DROP TABLE test.public.t1                   testuser2
SCHEMA CHANGE GC  GC for DROP TABLE test.public.t2                   root
SCHEMA CHANGE GC  GC for temporary index used during index backfill  root
SCHEMA CHANGE GC  GC for temporary index used during index backfill  testuser
SCHEMA CHANGE GC  GC for temporary index used during index backfill  testuser2

user root

statement ok
REVOKE SYSTEM VIEWJOB FROM testuser

user testuser

# testuser can only see their own job
query TTT
SELECT job_type, description, user_name FROM crdb_internal.jobs WHERE job_type = 'SCHEMA CHANGE GC' ORDER BY 1, 2, 3
----
SCHEMA CHANGE GC  GC for temporary index used during index backfill  testuser

user root

statement ok
CREATE ROLE jobviewer

statement ok
GRANT SYSTEM VIEWJOB TO jobviewer

statement ok
GRANT jobviewer TO testuser

user testuser

# testuser should be able to see all jobs
query TTT
SELECT job_type, description, user_name FROM crdb_internal.jobs WHERE job_type = 'SCHEMA CHANGE GC' ORDER BY 1, 2, 3
----
SCHEMA CHANGE GC  GC for DROP TABLE test.public.t1                   testuser2
SCHEMA CHANGE GC  GC for DROP TABLE test.public.t2                   root
SCHEMA CHANGE GC  GC for temporary index used during index backfill  root
SCHEMA CHANGE GC  GC for temporary index used during index backfill  testuser
SCHEMA CHANGE GC  GC for temporary index used during index backfill  testuser2

user root
statement ok
REVOKE jobviewer FROM testuser

user testuser

# testuser can only see their own job
query TTT
SELECT job_type, description, user_name FROM crdb_internal.jobs WHERE job_type = 'SCHEMA CHANGE GC' ORDER BY 1, 2, 3
----
SCHEMA CHANGE GC  GC for temporary index used during index backfill  testuser

user root

# Validate that the schema_change_successful metric
query T
SELECT feature_name FROM crdb_internal.feature_usage
WHERE feature_name in ('job.schema_change.successful') AND
usage_count > 0
ORDER BY feature_name DESC
----
job.schema_change.successful

# Ensure one POLL JOBS STATS job is running
query I
SELECT count(*) FROM [SHOW AUTOMATIC JOBS] WHERE job_type = 'POLL JOBS STATS' AND status = 'running'
----
1

subtest control_job_priv

user testuser

statement ok
CREATE TABLE t_control_job_priv(x INT)

# Add a row into the table so that the GC job does not complete immediately;
# it must wait for the table data gc.ttl before removing the descriptor.
statement ok
INSERT INTO t_control_job_priv VALUES (1)

statement ok
DROP TABLE t_control_job_priv

let $job_id
SELECT job_id FROM [SHOW JOBS] WHERE user_name = 'testuser' AND job_type = 'SCHEMA CHANGE GC' AND description LIKE 'GC for DROP TABLE test.public.t_control_job_priv'

statement error user testuser does not have privileges for job
PAUSE JOB (SELECT $job_id)

user root

statement ok
GRANT SYSTEM CONTROLJOB TO testuser

user testuser

statement ok
PAUSE JOB (SELECT $job_id)

user root

statement ok
REVOKE SYSTEM CONTROLJOB FROM testuser

subtest end

subtest control_job_priv_inherited

user testuser

statement ok
CREATE TABLE t_control_job_priv_inherited(x INT)

# Add a row into the table so that the GC job does not complete immediately;
# it must wait for the table data gc.ttl before removing the descriptor.
statement ok
INSERT INTO t_control_job_priv_inherited VALUES (1)

statement ok
DROP TABLE t_control_job_priv_inherited

let $job_id
SELECT job_id FROM [SHOW JOBS] WHERE user_name = 'testuser' AND job_type = 'SCHEMA CHANGE GC' AND description LIKE 'GC for DROP TABLE test.public.t_control_job_priv_inherited'

statement error user testuser does not have privileges for job
PAUSE JOB (SELECT $job_id)

user root

statement ok
CREATE ROLE jobcontroller

statement ok
GRANT SYSTEM CONTROLJOB TO jobcontroller

statement ok
GRANT jobcontroller TO testuser

user testuser

statement ok
PAUSE JOB (SELECT $job_id)

user root

statement ok
REVOKE SYSTEM CONTROLJOB FROM jobcontroller

statement ok
REVOKE jobcontroller FROM testuser

statement ok
DROP ROLE jobcontroller

subtest end
