Skip to content

Commit

Permalink
Merge #34764
Browse files Browse the repository at this point in the history
34764: sql: provide table comments for virtual tables r=knz a=hueypark

Fixes #32964
Fixes #35581

Release note (sql change): CockroachDB now provides usable comments
with optional documentation URLs for the virtual tables in
`pg_catalog`, `information_schema` and `crdb_internal`. Use `SHOW
TABLES [FROM ...] WITH COMMENT` to read. Note that `crdb_internal`
tables remain an experimental feature subject to change without
notice.

Co-authored-by: Jaewan Park <jaewan.huey.park@gmail.com>
  • Loading branch information
craig[bot] and hueypark committed Mar 9, 2019
2 parents 7b2adf8 + 336a9fa commit 5f7de3c
Show file tree
Hide file tree
Showing 24 changed files with 532 additions and 256 deletions.
2 changes: 1 addition & 1 deletion pkg/server/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -1476,7 +1476,7 @@ func (s *adminServer) DataDistribution(
// and deleted tables (as opposed to e.g. information_schema) because we are interested
// in the data for all ranges, not just ranges for visible tables.
userName := s.getUser(req)
tablesQuery := `SELECT name, table_id, database_name, drop_time FROM "".crdb_internal.tables`
tablesQuery := `SELECT name, table_id, database_name, drop_time FROM "".crdb_internal.tables WHERE schema_name = 'public'`
rows1, _ /* cols */, err := s.server.internalExecutor.QueryWithUser(
ctx, "admin-replica-matrix", nil /* txn */, userName, tablesQuery,
)
Expand Down
4 changes: 2 additions & 2 deletions pkg/sql/comment_on_column.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (

type commentOnColumnNode struct {
n *tree.CommentOnColumn
tableDesc *MutableTableDescriptor
tableDesc *ImmutableTableDescriptor
}

// CommentOnColumn add comment on a column.
Expand All @@ -34,7 +34,7 @@ func (p *planner) CommentOnColumn(ctx context.Context, n *tree.CommentOnColumn)
if n.ColumnItem.TableName != nil {
tableName = n.ColumnItem.TableName.ToTableName()
}
tableDesc, err := p.ResolveMutableTableDescriptor(ctx, &tableName, true, requireTableDesc)
tableDesc, err := p.ResolveUncachedTableDescriptor(ctx, &tableName, true, requireTableDesc)
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/sql/comment_on_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ import (

type commentOnTableNode struct {
n *tree.CommentOnTable
tableDesc *MutableTableDescriptor
tableDesc *ImmutableTableDescriptor
}

// CommentOnTable add comment on a table.
// Privileges: CREATE on table.
// notes: postgres requires CREATE on the table.
// mysql requires ALTER, CREATE, INSERT on the table.
func (p *planner) CommentOnTable(ctx context.Context, n *tree.CommentOnTable) (planNode, error) {
tableDesc, err := p.ResolveMutableTableDescriptor(ctx, &n.Table, true, requireTableDesc)
tableDesc, err := p.ResolveUncachedTableDescriptor(ctx, &n.Table, true, requireTableDesc)
if err != nil {
return nil, err
}
Expand Down
146 changes: 121 additions & 25 deletions pkg/sql/crdb_internal.go

Large diffs are not rendered by default.

70 changes: 56 additions & 14 deletions pkg/sql/information_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"sort"
"strconv"

"github.com/cockroachdb/cockroach/pkg/base"
"github.com/cockroachdb/cockroach/pkg/security"
"github.com/cockroachdb/cockroach/pkg/sql/privilege"
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
Expand Down Expand Up @@ -200,6 +201,9 @@ func validateInformationSchemaTable(table *sqlbase.TableDescriptor) error {
}

var informationSchemaAdministrableRoleAuthorizations = virtualSchemaTable{
comment: `roles for which the current user has admin option
` + base.DocsURL("information-schema.html#administrable_role_authorizations") + `
https://www.postgresql.org/docs/9.5/infoschema-administrable-role-authorizations.html`,
schema: vtable.InformationSchemaAdministrableRoleAuthorizations,
populate: func(ctx context.Context, p *planner, _ *DatabaseDescriptor, addRow func(...tree.Datum) error) error {
currentUser := p.SessionData().User
Expand Down Expand Up @@ -229,6 +233,9 @@ var informationSchemaAdministrableRoleAuthorizations = virtualSchemaTable{
}

var informationSchemaApplicableRoles = virtualSchemaTable{
comment: `roles available to the current user
` + base.DocsURL("information-schema.html#applicable_roles") + `
https://www.postgresql.org/docs/9.5/infoschema-applicable-roles.html`,
schema: vtable.InformationSchemaApplicableRoles,
populate: func(ctx context.Context, p *planner, _ *DatabaseDescriptor, addRow func(...tree.Datum) error) error {
currentUser := p.SessionData().User
Expand All @@ -254,6 +261,9 @@ var informationSchemaApplicableRoles = virtualSchemaTable{
}

var informationSchemaColumnPrivileges = virtualSchemaTable{
comment: `column privilege grants (incomplete)
` + base.DocsURL("information-schema.html#column_privileges") + `
https://www.postgresql.org/docs/9.5/infoschema-column-privileges.html`,
schema: vtable.InformationSchemaColumnPrivileges,
populate: func(ctx context.Context, p *planner, dbContext *DatabaseDescriptor, addRow func(...tree.Datum) error) error {
return forEachTableDesc(ctx, p, dbContext, virtualMany, func(db *sqlbase.DatabaseDescriptor, scName string, table *sqlbase.TableDescriptor) error {
Expand Down Expand Up @@ -286,6 +296,9 @@ var informationSchemaColumnPrivileges = virtualSchemaTable{
}

var informationSchemaColumnsTable = virtualSchemaTable{
comment: `table and view columns (incomplete)
` + base.DocsURL("information-schema.html#columns") + `
https://www.postgresql.org/docs/9.5/infoschema-columns.html`,
schema: vtable.InformationSchemaColumns,
populate: func(ctx context.Context, p *planner, dbContext *DatabaseDescriptor, addRow func(...tree.Datum) error) error {
return forEachTableDesc(ctx, p, dbContext, virtualMany, func(db *sqlbase.DatabaseDescriptor, scName string, table *sqlbase.TableDescriptor) error {
Expand Down Expand Up @@ -325,9 +338,10 @@ var informationSchemaColumnsTable = virtualSchemaTable{
},
}

// Postgres: https://www.postgresql.org/docs/9.6/static/infoschema-enabled-roles.html
// MySQL: missing
var informationSchemaEnabledRoles = virtualSchemaTable{
comment: `roles for the current user
` + base.DocsURL("information-schema.html#enabled_roles") + `
https://www.postgresql.org/docs/9.5/infoschema-enabled-roles.html`,
schema: `
CREATE TABLE information_schema.enabled_roles (
ROLE_NAME STRING NOT NULL
Expand Down Expand Up @@ -383,9 +397,9 @@ func datetimePrecision(colType sqlbase.ColumnType) tree.Datum {
return tree.DNull
}

// Postgres: https://www.postgresql.org/docs/9.6/static/infoschema-constraint-column-usage.html
// MySQL: missing
var informationSchemaConstraintColumnUsageTable = virtualSchemaTable{
comment: `columns usage by constraints
https://www.postgresql.org/docs/9.5/infoschema-constraint-column-usage.html`,
schema: `
CREATE TABLE information_schema.constraint_column_usage (
TABLE_CATALOG STRING NOT NULL,
Expand Down Expand Up @@ -441,9 +455,11 @@ CREATE TABLE information_schema.constraint_column_usage (
},
}

// Postgres: https://www.postgresql.org/docs/9.6/static/infoschema-key-column-usage.html
// MySQL: https://dev.mysql.com/doc/refman/5.7/en/key-column-usage-table.html
var informationSchemaKeyColumnUsageTable = virtualSchemaTable{
comment: `column usage by indexes and key constraints
` + base.DocsURL("information-schema.html#key_column_usage") + `
https://www.postgresql.org/docs/9.5/infoschema-key-column-usage.html`,
schema: `
CREATE TABLE information_schema.key_column_usage (
CONSTRAINT_CATALOG STRING NOT NULL,
Expand Down Expand Up @@ -511,6 +527,8 @@ CREATE TABLE information_schema.key_column_usage (
// Postgres: https://www.postgresql.org/docs/9.6/static/infoschema-parameters.html
// MySQL: https://dev.mysql.com/doc/refman/5.7/en/parameters-table.html
var informationSchemaParametersTable = virtualSchemaTable{
comment: `built-in function parameters (empty - introspection not yet supported)
https://www.postgresql.org/docs/9.5/infoschema-parameters.html`,
schema: `
CREATE TABLE information_schema.parameters (
SPECIFIC_CATALOG STRING,
Expand Down Expand Up @@ -585,9 +603,11 @@ func dStringForFKAction(action sqlbase.ForeignKeyReference_Action) tree.Datum {
panic(errors.Errorf("unexpected ForeignKeyReference_Action: %v", action))
}

// Postgres: https://www.postgresql.org/docs/9.6/static/infoschema-referential-constraints.html
// MySQL: https://dev.mysql.com/doc/refman/5.7/en/referential-constraints-table.html
var informationSchemaReferentialConstraintsTable = virtualSchemaTable{
comment: `foreign key constraints
` + base.DocsURL("information-schema.html#referential_constraints") + `
https://www.postgresql.org/docs/9.5/infoschema-referential-constraints.html`,
schema: `
CREATE TABLE information_schema.referential_constraints (
CONSTRAINT_CATALOG STRING NOT NULL,
Expand Down Expand Up @@ -651,6 +671,9 @@ CREATE TABLE information_schema.referential_constraints (
// Postgres: https://www.postgresql.org/docs/9.6/static/infoschema-role-table-grants.html
// MySQL: missing
var informationSchemaRoleTableGrants = virtualSchemaTable{
comment: `privileges granted on table or views (incomplete; see also information_schema.table_privileges; may contain excess users or roles)
` + base.DocsURL("information-schema.html#role_table_grants") + `
https://www.postgresql.org/docs/9.5/infoschema-role-table-grants.html`,
schema: `
CREATE TABLE information_schema.role_table_grants (
GRANTOR STRING,
Expand All @@ -668,9 +691,10 @@ CREATE TABLE information_schema.role_table_grants (
populate: populateTablePrivileges,
}

// Postgres: https://www.postgresql.org/docs/9.6/static/infoschema-routines.html
// MySQL: https://dev.mysql.com/doc/mysql-infoschema-excerpt/5.7/en/routines-table.html
var informationSchemaRoutineTable = virtualSchemaTable{
comment: `built-in functions (empty - introspection not yet supported)
https://www.postgresql.org/docs/9.5/infoschema-routines.html`,
schema: `
CREATE TABLE information_schema.routines (
SPECIFIC_CATALOG STRING,
Expand Down Expand Up @@ -760,9 +784,11 @@ CREATE TABLE information_schema.routines (
},
}

// Postgres: https://www.postgresql.org/docs/9.6/static/infoschema-schemata.html
// MySQL: https://dev.mysql.com/doc/refman/5.7/en/schemata-table.html
var informationSchemaSchemataTable = virtualSchemaTable{
comment: `database schemas (may contain schemata without permission)
` + base.DocsURL("information-schema.html#schemata") + `
https://www.postgresql.org/docs/9.5/infoschema-schemata.html`,
schema: vtable.InformationSchemaSchemata,
populate: func(ctx context.Context, p *planner, dbContext *DatabaseDescriptor, addRow func(...tree.Datum) error) error {
return forEachDatabaseDesc(ctx, p, dbContext, func(db *sqlbase.DatabaseDescriptor) error {
Expand All @@ -778,9 +804,10 @@ var informationSchemaSchemataTable = virtualSchemaTable{
},
}

// Postgres: missing
// MySQL: https://dev.mysql.com/doc/refman/5.7/en/schema-privileges-table.html
var informationSchemaSchemataTablePrivileges = virtualSchemaTable{
comment: `schema privileges (incomplete; may contain excess users or roles)
` + base.DocsURL("information-schema.html#schema_privileges"),
schema: `
CREATE TABLE information_schema.schema_privileges (
GRANTEE STRING NOT NULL,
Expand Down Expand Up @@ -833,9 +860,10 @@ func dStringForIndexDirection(dir sqlbase.IndexDescriptor_Direction) tree.Datum
panic("unreachable")
}

// Postgres: https://www.postgresql.org/docs/9.6/static/infoschema-sequences.html
// MySQL: missing
var informationSchemaSequences = virtualSchemaTable{
comment: `sequences
` + base.DocsURL("information-schema.html#sequences") + `
https://www.postgresql.org/docs/9.5/infoschema-sequences.html`,
schema: `
CREATE TABLE information_schema.sequences (
SEQUENCE_CATALOG STRING NOT NULL,
Expand Down Expand Up @@ -878,6 +906,8 @@ CREATE TABLE information_schema.sequences (
// Postgres: missing
// MySQL: https://dev.mysql.com/doc/refman/5.7/en/statistics-table.html
var informationSchemaStatisticsTable = virtualSchemaTable{
comment: `index metadata and statistics (incomplete)
` + base.DocsURL("information-schema.html#statistics"),
schema: `
CREATE TABLE information_schema.statistics (
TABLE_CATALOG STRING NOT NULL,
Expand Down Expand Up @@ -974,9 +1004,11 @@ CREATE TABLE information_schema.statistics (
},
}

// Postgres: https://www.postgresql.org/docs/9.6/static/infoschema-table-constraints.html
// MySQL: https://dev.mysql.com/doc/refman/5.7/en/table-constraints-table.html
var informationSchemaTableConstraintTable = virtualSchemaTable{
comment: `table constraints
` + base.DocsURL("information-schema.html#table_constraints") + `
https://www.postgresql.org/docs/9.5/infoschema-table-constraints.html`,
schema: `
CREATE TABLE information_schema.table_constraints (
CONSTRAINT_CATALOG STRING NOT NULL,
Expand Down Expand Up @@ -1026,9 +1058,11 @@ CREATE TABLE information_schema.table_constraints (
},
}

// Postgres: missing
// Postgres: not provided
// MySQL: https://dev.mysql.com/doc/refman/5.7/en/user-privileges-table.html
// TODO(knz): this introspection facility is of dubious utility.
var informationSchemaUserPrivileges = virtualSchemaTable{
comment: `grantable privileges (incomplete)`,
schema: `
CREATE TABLE information_schema.user_privileges (
GRANTEE STRING NOT NULL,
Expand Down Expand Up @@ -1057,9 +1091,11 @@ CREATE TABLE information_schema.user_privileges (
},
}

// Postgres: https://www.postgresql.org/docs/9.6/static/infoschema-table-privileges.html
// MySQL: https://dev.mysql.com/doc/refman/5.7/en/table-privileges-table.html
var informationSchemaTablePrivileges = virtualSchemaTable{
comment: `privileges granted on table or views (incomplete; may contain excess users or roles)
` + base.DocsURL("information-schema.html#table_privileges") + `
https://www.postgresql.org/docs/9.5/infoschema-table-privileges.html`,
schema: `
CREATE TABLE information_schema.table_privileges (
GRANTOR STRING,
Expand Down Expand Up @@ -1112,6 +1148,9 @@ var (
)

var informationSchemaTablesTable = virtualSchemaTable{
comment: `tables and views
` + base.DocsURL("information-schema.html#tables") + `
https://www.postgresql.org/docs/9.5/infoschema-tables.html`,
schema: vtable.InformationSchemaTables,
populate: func(ctx context.Context, p *planner, dbContext *DatabaseDescriptor, addRow func(...tree.Datum) error) error {
return forEachTableDesc(ctx, p, dbContext, virtualMany,
Expand Down Expand Up @@ -1146,6 +1185,9 @@ var informationSchemaTablesTable = virtualSchemaTable{
// Postgres: https://www.postgresql.org/docs/9.6/static/infoschema-views.html
// MySQL: https://dev.mysql.com/doc/refman/5.7/en/views-table.html
var informationSchemaViewsTable = virtualSchemaTable{
comment: `views (incomplete)
` + base.DocsURL("information-schema.html#views") + `
https://www.postgresql.org/docs/9.5/infoschema-views.html`,
schema: `
CREATE TABLE information_schema.views (
TABLE_CATALOG STRING NOT NULL,
Expand Down
32 changes: 27 additions & 5 deletions pkg/sql/logictest/testdata/logic_test/builtin_function
Original file line number Diff line number Diff line change
Expand Up @@ -1912,14 +1912,36 @@ FOREIGN KEY (a) REFERENCES pg_indexdef_test (a) ON DELETE CASCADE
CHECK (c > a)
UNIQUE (b ASC)

# These functions always return NULL since we don't support comments.
query TTTT
# These functions always return NULL since we don't support comments on vtable columns and databases.
query TT
SELECT col_description('pg_class'::regclass::oid, 2),
obj_description('pg_class'::regclass::oid, 'pg_class'),
obj_description('pg_class'::regclass::oid),
shobj_description('pg_class'::regclass::oid, 'pg_class')
----
NULL NULL NULL NULL
NULL NULL

# vtable comments are supported
query TT
SELECT regexp_replace(obj_description('pg_class'::regclass::oid), e' .*', '') AS comment1,
regexp_replace(obj_description('pg_class'::regclass::oid, 'test'), e' .*', '') AS comment2
----
tables tables

# Regular table column comments are supported.
statement ok
CREATE TABLE t(x INT);

statement ok
COMMENT ON TABLE t IS 'waa'

statement ok
COMMENT ON COLUMN t.x IS 'woo'

query TTT
SELECT obj_description('t'::regclass::oid),
obj_description('t'::regclass::oid, 'test'),
col_description('t'::regclass, 1)
----
waa waa woo

# Check that base function names are also visible in namespace pg_catalog.
query I
Expand Down
7 changes: 4 additions & 3 deletions pkg/sql/logictest/testdata/logic_test/crdb_internal
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ node_runtime_info
node_sessions
node_statement_statistics
partitions
predefined_comments
ranges
ranges_no_leases
schema_changes
Expand Down Expand Up @@ -71,11 +72,11 @@ SELECT * FROM crdb_internal.schema_changes
----
table_id parent_id name type target_id target_name state direction

query IITTITRTTTTTT colnames
query IITTITRTTTTTTT colnames
SELECT * FROM crdb_internal.tables WHERE NAME = 'namespace'
----
table_id parent_id name database_name version mod_time mod_time_logical format_version state sc_lease_node_id sc_lease_expiration_time drop_time audit_mode
2 1 namespace system 1 1970-01-01 00:00:00 +0000 +0000 0E-10 InterleavedFormatVersion PUBLIC NULL NULL NULL DISABLED
table_id parent_id name database_name version mod_time mod_time_logical format_version state sc_lease_node_id sc_lease_expiration_time drop_time audit_mode schema_name
2 1 namespace system 1 1970-01-01 00:00:00 +0000 +0000 0E-10 InterleavedFormatVersion PUBLIC NULL NULL NULL DISABLED public

# Verify that table names are not double escaped.

Expand Down
1 change: 1 addition & 0 deletions pkg/sql/logictest/testdata/logic_test/grant_table
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ test crdb_internal node_runtime_info public S
test crdb_internal node_sessions public SELECT
test crdb_internal node_statement_statistics public SELECT
test crdb_internal partitions public SELECT
test crdb_internal predefined_comments public SELECT
test crdb_internal ranges public SELECT
test crdb_internal ranges_no_leases public SELECT
test crdb_internal schema_changes public SELECT
Expand Down
Loading

0 comments on commit 5f7de3c

Please sign in to comment.