Skip to content

Commit

Permalink
sql: update format_type to handle user defined types
Browse files Browse the repository at this point in the history
Fixes #53684.

Update the `format_type` builtin to handle user defined types.

Release justification: bug fix
Release note: None
  • Loading branch information
rohany committed Aug 31, 2020
1 parent 410616f commit 666d47d
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 3 deletions.
13 changes: 13 additions & 0 deletions pkg/sql/faketreeeval/evalctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/cockroachdb/cockroach/pkg/sql/types"
"github.com/cockroachdb/cockroach/pkg/util/errorutil/unimplemented"
"github.com/cockroachdb/errors"
"github.com/lib/pq/oid"
)

// DummySequenceOperators implements the tree.SequenceOperators interface by
Expand Down Expand Up @@ -119,6 +120,18 @@ func (ep *DummyEvalPlanner) EvalSubquery(expr *tree.Subquery) (tree.Datum, error
return nil, errors.WithStack(errEvalPlanner)
}

// ResolveTypeByOID implements the tree.TypeReferenceResolver interface.
func (ep *DummyEvalPlanner) ResolveTypeByOID(_ context.Context, _ oid.Oid) (*types.T, error) {
return nil, errors.WithStack(errEvalPlanner)
}

// ResolveType implements the tree.TypeReferenceResolver interface.
func (ep *DummyEvalPlanner) ResolveType(
_ context.Context, _ *tree.UnresolvedObjectName,
) (*types.T, error) {
return nil, errors.WithStack(errEvalPlanner)
}

// DummyPrivilegedAccessor implements the tree.PrivilegedAccessor interface by returning errors.
type DummyPrivilegedAccessor struct{}

Expand Down
15 changes: 15 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/pg_builtins
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,18 @@ SELECT pg_my_temp_schema()
# Regression test for #49072.
statement ok
SELECT has_table_privilege('root'::NAME, 0, 'select')

# Regression test for #53684.
statement ok
CREATE TYPE typ AS ENUM ('hello')

query T
SELECT format_type(oid, 0) FROM pg_catalog.pg_type WHERE typname = 'typ'
----
typ

# Nothing breaks if we put a non-existing oid into format_type.
query T
SELECT format_type(152100, 0)
----
unknown (OID=152100)
23 changes: 20 additions & 3 deletions pkg/sql/sem/builtins/pg_builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"time"

"github.com/cockroachdb/cockroach/pkg/keys"
"github.com/cockroachdb/cockroach/pkg/sql/catalog"
"github.com/cockroachdb/cockroach/pkg/sql/catalog/catconstants"
"github.com/cockroachdb/cockroach/pkg/sql/parser"
"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode"
Expand Down Expand Up @@ -827,7 +828,7 @@ var pgBuiltins = map[string]builtinDefinition{
},
),

"format_type": makeBuiltin(tree.FunctionProperties{NullableArgs: true},
"format_type": makeBuiltin(tree.FunctionProperties{NullableArgs: true, DistsqlBlocklist: true},
tree.Overload{
Types: tree.ArgTypes{{"type_oid", types.Oid}, {"typemod", types.Int}},
ReturnType: tree.FixedReturnType(types.String),
Expand All @@ -838,9 +839,25 @@ var pgBuiltins = map[string]builtinDefinition{
return tree.DNull, nil
}
maybeTypmod := args[1]
typ, ok := types.OidToType[oid.Oid(int(oidArg.(*tree.DOid).DInt))]
oid := oid.Oid(int(oidArg.(*tree.DOid).DInt))
typ, ok := types.OidToType[oid]
if !ok {
return tree.NewDString(fmt.Sprintf("unknown (OID=%s)", oidArg)), nil
// If the type wasn't statically known, try looking it up as a user
// defined type.
var err error
typ, err = ctx.Planner.ResolveTypeByOID(ctx.Context, oid)
if err != nil {
// If the error is a descriptor does not exist error, then swallow it.
unknown := tree.NewDString(fmt.Sprintf("unknown (OID=%s)", oidArg))
switch {
case errors.Is(err, catalog.ErrDescriptorNotFound):
return unknown, nil
case pgerror.GetPGCode(err) == pgcode.UndefinedObject:
return unknown, nil
default:
return nil, err
}
}
}
var hasTypmod bool
var typmod int
Expand Down
1 change: 1 addition & 0 deletions pkg/sql/sem/tree/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -2993,6 +2993,7 @@ type EvalDatabase interface {
// EvalPlanner is a limited planner that can be used from EvalContext.
type EvalPlanner interface {
EvalDatabase
TypeReferenceResolver
// ParseType parses a column type.
ParseType(sql string) (*types.T, error)

Expand Down

0 comments on commit 666d47d

Please sign in to comment.