Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sql: extend SHOW CREATE TABLE to use fully-qualified names #137719

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion docs/generated/sql/bnf/stmt_block.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -1186,6 +1186,7 @@ unreserved_keyword ::=
| 'FORCE_ZIGZAG'
| 'FORWARD'
| 'FREEZE'
| 'FULLY_QUALIFIED'
| 'FUNCTION'
| 'FUNCTIONS'
| 'GENERATED'
Expand Down Expand Up @@ -2044,7 +2045,7 @@ with_comment ::=
|

opt_show_create_format_options ::=
'WITH' 'REDACT'
'WITH' show_create_format_options

opt_on_targets_roles ::=
'ON' targets_roles
Expand Down Expand Up @@ -2845,6 +2846,9 @@ extra_var_value ::=
show_backup_options_list ::=
( show_backup_options ) ( ( ',' show_backup_options ) )*

show_create_format_options ::=
'REDACT'

targets_roles ::=
'ROLE' role_spec_list
| 'SCHEMA' schema_name_list
Expand Down Expand Up @@ -3904,6 +3908,7 @@ bare_label_keywords ::=
| 'FORWARD'
| 'FREEZE'
| 'FULL'
| 'FULLY_QUALIFIED'
| 'FUNCTION'
| 'FUNCTIONS'
| 'GENERATED'
Expand Down
4 changes: 2 additions & 2 deletions pkg/ccl/logictestccl/testdata/logic_test/crdb_internal_tenant
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,10 @@ SELECT * FROM crdb_internal.builtin_functions WHERE function = ''
----
function signature category details schema oid

query ITTITTTTTTTTBBBB colnames
query ITTITTTTTTTTTTBBBB colnames
SELECT * FROM crdb_internal.create_statements WHERE database_name = ''
----
database_id database_name schema_name descriptor_id descriptor_type descriptor_name create_statement state create_nofks alter_statements validate_statements create_redactable has_partitions is_multi_region is_virtual is_temporary
database_id database_name schema_name descriptor_id descriptor_type descriptor_name create_statement create_statement_fq state create_nofks alter_statements validate_statements create_redactable create_redactable_fq has_partitions is_multi_region is_virtual is_temporary

query ITITTBTB colnames
SELECT * FROM crdb_internal.table_columns WHERE descriptor_name = ''
Expand Down
10 changes: 9 additions & 1 deletion pkg/sql/catalog/schemaexpr/column.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,17 @@ func FormatColumnForDisplay(
semaCtx *tree.SemaContext,
sessionData *sessiondata.SessionData,
redactableValues bool,
fullyQualifyUDTNames bool,
) (string, error) {
f := tree.NewFmtCtx(tree.FmtSimple)
name := col.GetName()
f.FormatNameP(&name)
f.WriteByte(' ')
f.WriteString(col.GetType().SQLString())
if fullyQualifyUDTNames {
f.WriteString(col.GetType().SQLStringFullyQualified())
} else {
f.WriteString(col.GetType().SQLString())
}
if col.IsHidden() {
f.WriteString(" NOT VISIBLE")
}
Expand All @@ -103,6 +108,9 @@ func FormatColumnForDisplay(
if redactableValues {
fmtFlags |= tree.FmtMarkRedactionNode | tree.FmtOmitNameRedaction
}
if fullyQualifyUDTNames {
fmtFlags |= tree.FmtAlwaysQualifyUserDefinedTypeNames
}
if col.HasDefault() {
if col.IsGeneratedAsIdentity() {
if col.IsGeneratedAlwaysAsIdentity() {
Expand Down
53 changes: 40 additions & 13 deletions pkg/sql/crdb_internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -3770,11 +3770,13 @@ CREATE TABLE crdb_internal.create_statements (
descriptor_type STRING NOT NULL,
descriptor_name STRING NOT NULL,
create_statement STRING NOT NULL,
create_statement_fq STRING NOT NULL,
state STRING NOT NULL,
create_nofks STRING NOT NULL,
alter_statements STRING[] NOT NULL,
validate_statements STRING[] NOT NULL,
create_redactable STRING NOT NULL,
create_redactable_fq STRING NOT NULL,
has_partitions BOOL NOT NULL,
is_multi_region BOOL NOT NULL,
is_virtual BOOL NOT NULL,
Expand All @@ -3785,24 +3787,34 @@ CREATE TABLE crdb_internal.create_statements (
func(ctx context.Context, p *planner, h oidHasher, db catalog.DatabaseDescriptor, sc catalog.SchemaDescriptor,
table catalog.TableDescriptor, lookup simpleSchemaResolver, addRow func(...tree.Datum) error,
) error {
contextName := ""
dbPrefix := ""
parentNameStr := tree.DNull
if db != nil {
contextName = db.GetName()
parentNameStr = tree.NewDString(contextName)
dbPrefix = db.GetName()
parentNameStr = tree.NewDString(dbPrefix)
}
scNameStr := tree.NewDString(sc.GetName())

var descType tree.Datum
var stmt, createNofk, createRedactable string
var createStmt, createStmtFQ, createNofk, createRedactable, createRedactableFQ string
alterStmts := tree.NewDArray(types.String)
validateStmts := tree.NewDArray(types.String)
namePrefix := tree.ObjectNamePrefix{SchemaName: tree.Name(sc.GetName()), ExplicitSchema: true}
name := tree.MakeTableNameFromPrefix(namePrefix, tree.Name(table.GetName()))
var fqName tree.TableName
if db != nil {
fqNamePrefix := tree.ObjectNamePrefix{
CatalogName: tree.Name(db.GetName()), ExplicitCatalog: true,
SchemaName: tree.Name(sc.GetName()), ExplicitSchema: true,
}
fqName = tree.MakeTableNameFromPrefix(fqNamePrefix, tree.Name(table.GetName()))
} else {
fqName = tree.MakeUnqualifiedTableName(tree.Name(table.GetName()))
}
var err error
if table.IsView() {
descType = typeView
stmt, err = ShowCreateView(
createStmt, err = ShowCreateView(
ctx, p.EvalContext(), &p.semaCtx, p.SessionData(), &name, table, false, /* redactableValues */
)
if err != nil {
Expand All @@ -3813,28 +3825,41 @@ CREATE TABLE crdb_internal.create_statements (
)
} else if table.IsSequence() {
descType = typeSequence
stmt, err = ShowCreateSequence(ctx, &name, table)
createRedactable = stmt
createStmt, err = ShowCreateSequence(ctx, &name, table)
createRedactable = createStmt
} else {
descType = typeTable
displayOptions := ShowCreateDisplayOptions{
FKDisplayMode: OmitFKClausesFromCreate,
}
createNofk, err = ShowCreateTable(ctx, p, &name, contextName, table, lookup, displayOptions)
createNofk, err = ShowCreateTable(ctx, p, &name, dbPrefix, table, lookup, displayOptions)
if err != nil {
return err
}
if err := showAlterStatement(ctx, &name, contextName, lookup, table, alterStmts, validateStmts); err != nil {
if err := showAlterStatement(ctx, &name, dbPrefix, lookup, table, alterStmts, validateStmts); err != nil {
return err
}
displayOptions.FKDisplayMode = IncludeFkClausesInCreate
stmt, err = ShowCreateTable(ctx, p, &name, contextName, table, lookup, displayOptions)
createStmt, err = ShowCreateTable(ctx, p, &name, dbPrefix, table, lookup, displayOptions)
if err != nil {
return err
}
displayOptions.FullyQualifyUDTNames = true
createStmtFQ, err = ShowCreateTable(ctx, p, &fqName, "" /* dbPrefix */, table, lookup, displayOptions)
if err != nil {
return err
}
displayOptions.FullyQualifyUDTNames = false
displayOptions.RedactableValues = true
createRedactable, err = ShowCreateTable(
ctx, p, &name, contextName, table, lookup, displayOptions,
ctx, p, &name, dbPrefix, table, lookup, displayOptions,
)
if err != nil {
return err
}
displayOptions.FullyQualifyUDTNames = true
createRedactableFQ, err = ShowCreateTable(
ctx, p, &fqName, "" /* dbPrefix */, table, lookup, displayOptions,
)
}
if err != nil {
Expand All @@ -3844,7 +3869,7 @@ CREATE TABLE crdb_internal.create_statements (
descID := tree.NewDInt(tree.DInt(table.GetID()))
dbDescID := tree.NewDInt(tree.DInt(table.GetParentID()))
if createNofk == "" {
createNofk = stmt
createNofk = createStmt
}
hasPartitions := nil != catalog.FindIndex(table, catalog.IndexOpts{}, func(idx catalog.Index) bool {
return idx.PartitioningColumnCount() != 0
Expand All @@ -3856,12 +3881,14 @@ CREATE TABLE crdb_internal.create_statements (
descID,
descType,
tree.NewDString(table.GetName()),
tree.NewDString(stmt),
tree.NewDString(createStmt),
tree.NewDString(createStmtFQ),
tree.NewDString(table.GetState().String()),
tree.NewDString(createNofk),
alterStmts,
validateStmts,
tree.NewDString(createRedactable),
tree.NewDString(createRedactableFQ),
tree.MakeDBool(tree.DBool(hasPartitions)),
tree.MakeDBool(tree.DBool(db != nil && db.IsMultiRegion())),
tree.MakeDBool(tree.DBool(table.IsVirtualTable())),
Expand Down
8 changes: 6 additions & 2 deletions pkg/sql/delegate/show_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,13 @@ WHERE name = %s

func (d *delegator) delegateShowCreateTable(n *tree.ShowCreate) (tree.Statement, error) {
createField := "create_statement"
switch n.FmtOpt {
case tree.ShowCreateFormatOptionRedactedValues:
switch {
case n.FmtOpt.RedactedValues && !n.FmtOpt.FullyQualified:
createField = "crdb_internal.redact(create_redactable)"
case !n.FmtOpt.RedactedValues && n.FmtOpt.FullyQualified:
createField = "create_statement_fq"
case n.FmtOpt.RedactedValues && n.FmtOpt.FullyQualified:
createField = "crdb_internal.redact(create_redactable_fq)"
}

showCreateQuery := `
Expand Down
8 changes: 2 additions & 6 deletions pkg/sql/explain_bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -983,15 +983,11 @@ func (c *stmtEnvCollector) PrintCreateTable(
) error {
var formatOption string
if redactValues {
formatOption = " WITH REDACT"
formatOption = ", REDACT"
}
createStatement, err := c.query(
fmt.Sprintf("SELECT create_statement FROM [SHOW CREATE TABLE %s%s]", tn.FQString(), formatOption),
fmt.Sprintf("SELECT create_statement FROM [SHOW CREATE TABLE %s WITH FULLY_QUALIFIED%s]", tn.FQString(), formatOption),
)
// We need to replace schema.table_name in the create statement with the fully
// qualified table name.
createStatement = strings.Replace(createStatement,
fmt.Sprintf("%s.%s", tn.SchemaName, tn.Table()), tn.FQString(), 1)
if err != nil {
return err
}
Expand Down
69 changes: 56 additions & 13 deletions pkg/sql/logictest/testdata/logic_test/crdb_internal
Original file line number Diff line number Diff line change
Expand Up @@ -374,10 +374,10 @@ SELECT * FROM crdb_internal.builtin_functions WHERE function = ''
----
function signature category details schema oid

query ITTITTTTTTTTBBBB colnames
query ITTITTTTTTTTTTBBBB colnames
SELECT * FROM crdb_internal.create_statements WHERE database_name = ''
----
database_id database_name schema_name descriptor_id descriptor_type descriptor_name create_statement state create_nofks alter_statements validate_statements create_redactable has_partitions is_multi_region is_virtual is_temporary
database_id database_name schema_name descriptor_id descriptor_type descriptor_name create_statement create_statement_fq state create_nofks alter_statements validate_statements create_redactable create_redactable_fq has_partitions is_multi_region is_virtual is_temporary

query ITITTBTB colnames
SELECT * FROM crdb_internal.table_columns WHERE descriptor_name = ''
Expand Down Expand Up @@ -1127,8 +1127,10 @@ SELECT is_temporary FROM crdb_internal.create_statements WHERE descriptor_name =
true

statement ok
CREATE TABLE defaultdb.public.in_other_db (x INT PRIMARY KEY);
CREATE TABLE public.in_this_db (x INT PRIMARY KEY);
CREATE TYPE defaultdb.public.udt AS ENUM ();
CREATE TABLE defaultdb.public.in_other_db (x INT PRIMARY KEY, e defaultdb.public.udt, FAMILY (x, e));
CREATE TYPE public.udt AS ENUM ();
CREATE TABLE public.in_this_db (x INT PRIMARY KEY, e public.udt, FAMILY (x, e));

# Verify that we can inspect all databases by using "" as the database name.
query TTT colnames
Expand All @@ -1141,7 +1143,48 @@ database_name schema_name descriptor_name
defaultdb public in_other_db
test public in_this_db

# Also verify that using the virtul index on descriptor_id works.
# Check that table and UDT names are fully-qualified in the right column.
query TT colnames
SELECT database_name, create_statement
FROM "".crdb_internal.create_statements
WHERE descriptor_name IN ('in_other_db', 'in_this_db')
ORDER BY 1
----
database_name create_statement
defaultdb CREATE TABLE public.in_other_db (
x INT8 NOT NULL,
e public.udt NULL,
CONSTRAINT in_other_db_pkey PRIMARY KEY (x ASC),
FAMILY fam_0_x_e (x, e)
)
test CREATE TABLE public.in_this_db (
x INT8 NOT NULL,
e public.udt NULL,
CONSTRAINT in_this_db_pkey PRIMARY KEY (x ASC),
FAMILY fam_0_x_e (x, e)
)

query TT colnames
SELECT database_name, create_statement_fq
FROM "".crdb_internal.create_statements
WHERE descriptor_name IN ('in_other_db', 'in_this_db')
ORDER BY 1
----
database_name create_statement_fq
defaultdb CREATE TABLE defaultdb.public.in_other_db (
x INT8 NOT NULL,
e defaultdb.public.udt NULL,
CONSTRAINT in_other_db_pkey PRIMARY KEY (x ASC),
FAMILY fam_0_x_e (x, e)
)
test CREATE TABLE test.public.in_this_db (
x INT8 NOT NULL,
e test.public.udt NULL,
CONSTRAINT in_this_db_pkey PRIMARY KEY (x ASC),
FAMILY fam_0_x_e (x, e)
)

# Also verify that using the virtual index on descriptor_id works.
query TTT colnames
SELECT database_name, schema_name, descriptor_name
FROM "".crdb_internal.create_statements
Expand Down Expand Up @@ -1512,19 +1555,19 @@ FROM crdb_internal.create_procedure_statements
WHERE procedure_name IN ('p', 'p2')
ORDER BY procedure_id;
----
104 test 105 public 139 p CREATE PROCEDURE public.p(INT8)
104 test 105 public 143 p CREATE PROCEDURE public.p(INT8)
LANGUAGE SQL
SECURITY INVOKER
AS $$
SELECT 1;
$$
104 test 105 public 140 p CREATE PROCEDURE public.p(STRING, b INT8)
104 test 105 public 144 p CREATE PROCEDURE public.p(STRING, b INT8)
LANGUAGE SQL
SECURITY INVOKER
AS $$
SELECT 'hello';
$$
104 test 142 sc 143 p2 CREATE PROCEDURE sc.p2(STRING)
104 test 146 sc 147 p2 CREATE PROCEDURE sc.p2(STRING)
LANGUAGE SQL
SECURITY INVOKER
AS $$
Expand All @@ -1543,25 +1586,25 @@ FROM "".crdb_internal.create_procedure_statements
WHERE procedure_name IN ('p', 'p2', 'p_cross_db')
ORDER BY procedure_id;
----
104 test 105 public 139 p CREATE PROCEDURE public.p(INT8)
104 test 105 public 143 p CREATE PROCEDURE public.p(INT8)
LANGUAGE SQL
SECURITY INVOKER
AS $$
SELECT 1;
$$
104 test 105 public 140 p CREATE PROCEDURE public.p(STRING, b INT8)
104 test 105 public 144 p CREATE PROCEDURE public.p(STRING, b INT8)
LANGUAGE SQL
SECURITY INVOKER
AS $$
SELECT 'hello';
$$
104 test 142 sc 143 p2 CREATE PROCEDURE sc.p2(STRING)
104 test 146 sc 147 p2 CREATE PROCEDURE sc.p2(STRING)
LANGUAGE SQL
SECURITY INVOKER
AS $$
SELECT 'hello';
$$
144 test_cross_db 145 public 146 p_cross_db CREATE PROCEDURE public.p_cross_db()
148 test_cross_db 149 public 150 p_cross_db CREATE PROCEDURE public.p_cross_db()
LANGUAGE SQL
SECURITY INVOKER
AS $$
Expand Down Expand Up @@ -1686,4 +1729,4 @@ CREATE TYPE other_db.public.enum1 AS ENUM ('yo');
query ITTITTT
SELECT * FROM "".crdb_internal.create_type_statements WHERE descriptor_id = (('other_db.public.enum1'::regtype::int) - 100000)::oid
----
121 other_db public 151 enum1 CREATE TYPE other_db.public.enum1 AS ENUM ('yo') {yo}
121 other_db public 155 enum1 CREATE TYPE other_db.public.enum1 AS ENUM ('yo') {yo}
6 changes: 3 additions & 3 deletions pkg/sql/logictest/testdata/logic_test/sequences
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,11 @@ CREATE SEQUENCE ignored_options_test NO CYCLE
statement ok
CREATE SEQUENCE show_create_test

query ITTITTTTTTTTBBBB colnames
query ITTITTTTTTTTTTBBBB colnames
SELECT * FROM crdb_internal.create_statements WHERE descriptor_name = 'show_create_test'
----
database_id database_name schema_name descriptor_id descriptor_type descriptor_name create_statement state create_nofks alter_statements validate_statements create_redactable has_partitions is_multi_region is_virtual is_temporary
104 test public 111 sequence show_create_test CREATE SEQUENCE public.show_create_test MINVALUE 1 MAXVALUE 9223372036854775807 INCREMENT 1 START 1 PUBLIC CREATE SEQUENCE public.show_create_test MINVALUE 1 MAXVALUE 9223372036854775807 INCREMENT 1 START 1 {} {} CREATE SEQUENCE public.show_create_test MINVALUE 1 MAXVALUE 9223372036854775807 INCREMENT 1 START 1 false false false false
database_id database_name schema_name descriptor_id descriptor_type descriptor_name create_statement create_statement_fq state create_nofks alter_statements validate_statements create_redactable create_redactable_fq has_partitions is_multi_region is_virtual is_temporary
104 test public 111 sequence show_create_test CREATE SEQUENCE public.show_create_test MINVALUE 1 MAXVALUE 9223372036854775807 INCREMENT 1 START 1 · PUBLIC CREATE SEQUENCE public.show_create_test MINVALUE 1 MAXVALUE 9223372036854775807 INCREMENT 1 START 1 {} {} CREATE SEQUENCE public.show_create_test MINVALUE 1 MAXVALUE 9223372036854775807 INCREMENT 1 START 1 · false false false false

query TT colnames
SHOW CREATE SEQUENCE show_create_test
Expand Down
Loading
Loading