user testuser

# Public should have SELECT on virtual tables by default.
statement ok
SELECT * FROM crdb_internal.tables

statement ok

query B
SELECT has_table_privilege('testuser', 'crdb_internal.tables', 'select');
----
true

user root

statement ok
REVOKE SELECT ON crdb_internal.tables FROM public

query TTTT
SELECT username, path, privileges, grant_options FROM system.privileges
----
public  /vtable/crdb_internal/tables  {}  {}

# Note that after granting SELECT to public, there should be no row
# since this is the default case, public with SELECT is represented as no row.
statement ok
GRANT SELECT ON crdb_internal.tables TO public

query TTTT
SELECT username, path, privileges, grant_options FROM system.privileges
----

user testuser

statement ok
SELECT * FROM crdb_internal.tables

user root

statement ok
REVOKE SELECT ON TABLE crdb_internal.tables FROM public

query B
SELECT has_table_privilege('testuser', 'crdb_internal.tables', 'select');
----
false

user testuser

statement error pq: user testuser does not have SELECT privilege on relation tables
SHOW TABLES

user root

statement ok
GRANT SELECT ON TABLE crdb_internal.tables TO public

query B
SELECT has_table_privilege('testuser', 'crdb_internal.tables', 'select');
----
true

statement ok
REVOKE SELECT ON TABLE crdb_internal.tables FROM public

user testuser

statement error pq: user testuser does not have SELECT privilege on relation tables
SELECT * FROM crdb_internal.tables

user root

statement ok
GRANT SELECT ON TABLE crdb_internal.tables TO public

user testuser

statement ok
SELECT * FROM crdb_internal.tables

user root

# Test that we can specify the database name.
statement ok
CREATE DATABASE test2

# Weak isolation levels emit extra notices, so skip them.
skipif config weak-iso-level-configs
query T noticetrace
GRANT SELECT ON TABLE test2.information_schema.columns TO testuser
----
NOTICE: virtual table privileges are not database specific

onlyif config weak-iso-level-configs
statement ok
GRANT SELECT ON TABLE test2.information_schema.columns TO testuser

query TTTT
SELECT username, path, privileges, grant_options FROM system.privileges
----
testuser  /vtable/information_schema/columns  {SELECT}  {}

user testuser

statement ok
SELECT * FROM test2.information_schema.columns

# We're in database test, this is okay.
statement ok
SELECT * FROM crdb_internal.cluster_sessions

user root

statement ok
use test2

# virtual table privileges are not database specific so qualifying it should
# do nothing.

query B
select has_table_privilege('testuser', 'test2.crdb_internal.tables', 'select');
----
true

statement ok
use test

query B
select has_table_privilege('testuser', 'test.crdb_internal.tables', 'select');
----
true

# Second select tests the cache. Rudimentary test to ensure the cache works.
statement ok
SELECT * FROM crdb_internal.tables

statement error pq: invalid privilege type USAGE for virtual_table
GRANT USAGE ON TABLE crdb_internal.tables TO testuser

statement error pq: invalid privilege type ZONECONFIG for virtual_table
GRANT ZONECONFIG ON TABLE crdb_internal.tables TO testuser

statement error pq: invalid privilege type CREATE for virtual_table
GRANT CREATE ON TABLE information_schema.tables TO testuser
