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

builtins: add pg_function_is_visible; pg_get_function_result #40902

Merged
merged 1 commit into from
Sep 20, 2019
Merged
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
29 changes: 29 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/builtin_function
Original file line number Diff line number Diff line change
Expand Up @@ -1510,6 +1510,16 @@ SELECT current_schema()
----
public

query B
SELECT pg_catalog.pg_function_is_visible((select 'pg_table_is_visible'::regproc))
----
true

query B
SELECT pg_catalog.pg_function_is_visible(0)
----
NULL

# COLLATION FOR returns a locale name for a collated string
# but for a not collated string 'default' locale name is a Postgres compatible behavior:
# https://www.postgresql.org/docs/10/functions-info.html#FUNCTIONS-INFO-CATALOG-TABLE
Expand Down Expand Up @@ -2298,3 +2308,22 @@ query T
SELECT pg_get_function_identity_arguments((select oid from pg_proc where proname='variance' and proargtypes[0] = 'int'::regtype))
----
int8

# Sanity check pg_get_function_result.

query T
SELECT pg_get_function_result('array_length'::regproc)
----
int8

query T
SELECT pg_get_function_result((select oid from pg_proc where proname='variance' and proargtypes[0] = 'int'::regtype))
----
numeric


# Slight incompatibility: in Postgres, the latter returns SETOF anyelement.
query TT
SELECT pg_get_function_result('pg_sleep'::regproc), pg_get_function_result('unnest'::regproc)
----
bool anyelement
52 changes: 52 additions & 0 deletions pkg/sql/sem/builtins/pg_builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,32 @@ var pgBuiltins = map[string]builtinDefinition{
makePGGetConstraintDef(tree.ArgTypes{{"constraint_oid", types.Oid}}),
),

// pg_get_function_result returns the types of the result of an builtin
// function. Multi-return builtins currently are returned as anyelement, which
// is a known incompatibility with Postgres.
// https://www.postgresql.org/docs/11/functions-info.html
"pg_get_function_result": makeBuiltin(defProps(),
tree.Overload{
Types: tree.ArgTypes{{"func_oid", types.Oid}},
ReturnType: tree.FixedReturnType(types.String),
Fn: func(ctx *tree.EvalContext, args tree.Datums) (tree.Datum, error) {
funcOid := tree.MustBeDOid(args[0])
t, err := ctx.InternalExecutor.QueryRow(
ctx.Ctx(), "pg_get_function_result",
ctx.Txn,
`SELECT prorettype::REGTYPE::TEXT FROM pg_proc WHERE oid=$1`, int(funcOid.DInt))
if err != nil {
return nil, err
}
if len(t) == 0 {
return tree.NewDString(""), nil
}
return t[0], nil
},
Info: notUsableInfo,
},
),

// pg_get_function_identity_arguments returns the argument list necessary to
// identify a function, in the form it would need to appear in within ALTER
// FUNCTION, for instance. This form omits default values.
Expand Down Expand Up @@ -913,6 +939,32 @@ SELECT description
},
),

// pg_function_is_visible returns true if the input oid corresponds to a
// builtin function that is part of the databases on the search path.
// CockroachDB doesn't have a concept of namespaced functions, so this is
// always true if the builtin exists at all, and NULL otherwise.
// https://www.postgresql.org/docs/9.6/static/functions-info.html
"pg_function_is_visible": makeBuiltin(defProps(),
tree.Overload{
Types: tree.ArgTypes{{"oid", types.Oid}},
ReturnType: tree.FixedReturnType(types.Bool),
Fn: func(ctx *tree.EvalContext, args tree.Datums) (tree.Datum, error) {
oid := tree.MustBeDOid(args[0])
t, err := ctx.InternalExecutor.QueryRow(
ctx.Ctx(), "pg_function_is_visible",
ctx.Txn,
"SELECT * from pg_proc WHERE oid=$1 LIMIT 1", int(oid.DInt))
if err != nil {
return nil, err
}
if t != nil {
return tree.DBoolTrue, nil
}
return tree.DNull, nil
},
Info: notUsableInfo,
},
),
// pg_table_is_visible returns true if the input oid corresponds to a table
// that is part of the databases on the search path.
// https://www.postgresql.org/docs/9.6/static/functions-info.html
Expand Down