Skip to content

Commit

Permalink
sql: properly implement create_type_statements index
Browse files Browse the repository at this point in the history
Release note (sql change): The `create_type_statements` table now has an
index on `descriptor_id`.
  • Loading branch information
otan committed Dec 9, 2021
1 parent e89328d commit 48a0695
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 63 deletions.
114 changes: 73 additions & 41 deletions pkg/sql/crdb_internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -2233,6 +2233,54 @@ CREATE TABLE crdb_internal.builtin_functions (
},
}

func writeCreateTypeDescRow(
db catalog.DatabaseDescriptor,
sc string,
typeDesc catalog.TypeDescriptor,
addRow func(...tree.Datum) error,
) (written bool, err error) {
switch typeDesc.GetKind() {
case descpb.TypeDescriptor_ENUM:
var enumLabels tree.EnumValueList
enumLabelsDatum := tree.NewDArray(types.String)
for i := 0; i < typeDesc.NumEnumMembers(); i++ {
rep := typeDesc.GetMemberLogicalRepresentation(i)
enumLabels = append(enumLabels, tree.EnumValue(rep))
if err := enumLabelsDatum.Append(tree.NewDString(rep)); err != nil {
return false, err
}
}
name, err := tree.NewUnresolvedObjectName(2, [3]string{typeDesc.GetName(), sc}, 0)
if err != nil {
return false, err
}
node := &tree.CreateType{
Variety: tree.Enum,
TypeName: name,
EnumLabels: enumLabels,
}
return true, addRow(
tree.NewDInt(tree.DInt(db.GetID())), // database_id
tree.NewDString(db.GetName()), // database_name
tree.NewDString(sc), // schema_name
tree.NewDInt(tree.DInt(typeDesc.GetID())), // descriptor_id
tree.NewDString(typeDesc.GetName()), // descriptor_name
tree.NewDString(tree.AsString(node)), // create_statement
enumLabelsDatum,
)
case descpb.TypeDescriptor_MULTIREGION_ENUM:
// Multi-region enums are created implicitly, so we don't have create
// statements for them.
return false, nil
case descpb.TypeDescriptor_ALIAS:
// Alias types are created implicitly, so we don't have create
// statements for them.
return false, nil
default:
return false, errors.AssertionFailedf("unknown type descriptor kind %s", typeDesc.GetKind().String())
}
}

var crdbInternalCreateTypeStmtsTable = virtualSchemaTable{
comment: "CREATE statements for all user defined types accessible by the current user in current database (KV scan)",
schema: `
Expand All @@ -2243,53 +2291,37 @@ CREATE TABLE crdb_internal.create_type_statements (
descriptor_id INT,
descriptor_name STRING,
create_statement STRING,
enum_members STRING[] -- populated only for ENUM types
enum_members STRING[], -- populated only for ENUM types
INDEX (descriptor_id)
)
`,
populate: func(ctx context.Context, p *planner, db catalog.DatabaseDescriptor, addRow func(...tree.Datum) error) error {
return forEachTypeDesc(ctx, p, db, func(db catalog.DatabaseDescriptor, sc string, typeDesc catalog.TypeDescriptor) error {
switch typeDesc.GetKind() {
case descpb.TypeDescriptor_ENUM:
var enumLabels tree.EnumValueList
enumLabelsDatum := tree.NewDArray(types.String)
for i := 0; i < typeDesc.NumEnumMembers(); i++ {
rep := typeDesc.GetMemberLogicalRepresentation(i)
enumLabels = append(enumLabels, tree.EnumValue(rep))
if err := enumLabelsDatum.Append(tree.NewDString(rep)); err != nil {
return err
}
}
name, err := tree.NewUnresolvedObjectName(2, [3]string{typeDesc.GetName(), sc}, 0)
if err != nil {
return err
}
node := &tree.CreateType{
Variety: tree.Enum,
TypeName: name,
EnumLabels: enumLabels,
_, err := writeCreateTypeDescRow(db, sc, typeDesc, addRow)
return err
})
},
indexes: []virtualIndex{
{
populate: func(
ctx context.Context,
constraint tree.Datum,
p *planner,
db catalog.DatabaseDescriptor,
addRow func(...tree.Datum) error,
) (matched bool, err error) {
d := tree.UnwrapDatum(p.EvalContext(), constraint)
if d == tree.DNull {
return false, nil
}
if err := addRow(
tree.NewDInt(tree.DInt(db.GetID())), // database_id
tree.NewDString(db.GetName()), // database_name
tree.NewDString(sc), // schema_name
tree.NewDInt(tree.DInt(typeDesc.GetID())), // descriptor_id
tree.NewDString(typeDesc.GetName()), // descriptor_name
tree.NewDString(tree.AsString(node)), // create_statement
enumLabelsDatum,
); err != nil {
return err
id := descpb.ID(tree.MustBeDInt(d))
scName, typDesc, err := getSchemaAndTypeByTypeID(ctx, p, id)
if err != nil || typDesc == nil {
return false, err
}
case descpb.TypeDescriptor_MULTIREGION_ENUM:
// Multi-region enums are created implicitly, so we don't have create
// statements for them.
case descpb.TypeDescriptor_ALIAS:
// Alias types are created implicitly, so we don't have create
// statements for them.
default:
return errors.AssertionFailedf("unknown type descriptor kind %s", typeDesc.GetKind().String())
}
return nil
})
return writeCreateTypeDescRow(db, scName, typDesc, addRow)
},
},
},
}

Expand Down
9 changes: 9 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/crdb_internal
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,15 @@ SELECT * FROM crdb_internal.create_type_statements

# Test the virtual index as well.

query ITTITTT
SELECT * FROM crdb_internal.create_type_statements WHERE descriptor_id = (('enum1'::regtype::oid::int) - 100000)::oid
----
54 test public 66 enum1 CREATE TYPE public.enum1 AS ENUM ('hello', 'hi') {hello,hi}

query ITTITTT
SELECT * FROM crdb_internal.create_type_statements WHERE descriptor_id = 'foo'::regclass::oid
----

statement ok
SET application_name = "test_txn_statistics"

Expand Down
6 changes: 4 additions & 2 deletions pkg/sql/logictest/testdata/logic_test/create_statements
Original file line number Diff line number Diff line change
Expand Up @@ -289,15 +289,17 @@ CREATE TABLE crdb_internal.create_type_statements (
descriptor_id INT8 NULL,
descriptor_name STRING NULL,
create_statement STRING NULL,
enum_members STRING[] NULL
enum_members STRING[] NULL,
INDEX create_type_statements_descriptor_id_idx (descriptor_id ASC) STORING (database_id, database_name, schema_name, descriptor_name, create_statement, enum_members)
) CREATE TABLE crdb_internal.create_type_statements (
database_id INT8 NULL,
database_name STRING NULL,
schema_name STRING NULL,
descriptor_id INT8 NULL,
descriptor_name STRING NULL,
create_statement STRING NULL,
enum_members STRING[] NULL
enum_members STRING[] NULL,
INDEX create_type_statements_descriptor_id_idx (descriptor_id ASC) STORING (database_id, database_name, schema_name, descriptor_name, create_statement, enum_members)
) {} {}
CREATE TABLE crdb_internal.cross_db_references (
object_database STRING NOT NULL,
Expand Down
48 changes: 28 additions & 20 deletions pkg/sql/pg_catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -2825,6 +2825,30 @@ func addPGTypeRow(
)
}

func getSchemaAndTypeByTypeID(
ctx context.Context, p *planner, id descpb.ID,
) (string, catalog.TypeDescriptor, error) {
typDesc, err := p.Descriptors().GetImmutableTypeByID(ctx, p.txn, id, tree.ObjectLookupFlags{})
if err != nil {
// If the type was not found, it may be a table.
if !(errors.Is(err, catalog.ErrDescriptorNotFound) || pgerror.GetPGCode(err) == pgcode.UndefinedObject) {
return "", nil, err
}
return "", nil, nil
}

sc, err := p.Descriptors().GetImmutableSchemaByID(
ctx,
p.txn,
typDesc.GetParentSchemaID(),
tree.SchemaLookupFlags{},
)
if err != nil {
return "", nil, err
}
return sc.GetName(), typDesc, nil
}

var pgCatalogTypeTable = virtualSchemaTable{
comment: `scalar types (incomplete)
https://www.postgresql.org/docs/9.5/catalog-pg-type.html`,
Expand Down Expand Up @@ -2906,17 +2930,10 @@ https://www.postgresql.org/docs/9.5/catalog-pg-type.html`,
if err != nil {
return false, err
}
typDesc, err := p.Descriptors().GetImmutableTypeByID(ctx, p.txn, id, tree.ObjectLookupFlags{})
if err != nil {
// If the type was not found, it may be a table.
if !(errors.Is(err, catalog.ErrDescriptorNotFound) || pgerror.GetPGCode(err) == pgcode.UndefinedObject) {
return false, err
}
typDesc = nil
}

if typDesc == nil {
return false, nil
scName, typDesc, err := getSchemaAndTypeByTypeID(ctx, p, id)
if err != nil || typDesc == nil {
return false, err
}

// It's an entry for the implicit record type created on behalf of each
Expand Down Expand Up @@ -2952,16 +2969,7 @@ https://www.postgresql.org/docs/9.5/catalog-pg-type.html`,
return true, nil
}

sc, err := p.Descriptors().GetImmutableSchemaByID(
ctx,
p.txn,
typDesc.GetParentSchemaID(),
tree.SchemaLookupFlags{},
)
if err != nil {
return false, err
}
nspOid = h.NamespaceOid(db.GetID(), sc.GetName())
nspOid = h.NamespaceOid(db.GetID(), scName)
typ, err = typDesc.MakeTypesT(ctx, tree.NewUnqualifiedTypeName(typDesc.GetName()), p)
if err != nil {
return false, err
Expand Down

0 comments on commit 48a0695

Please sign in to comment.