Skip to content

Commit

Permalink
sql: add SHOW CREATE FUNCTION support
Browse files Browse the repository at this point in the history
Release note (sql change): This commit adds support for the
SHOW CREATE FUNCTION statement. If given function name is
qualified, the explicit schema will be searched. If function
name is not qualified, the schemas on search path are searched
and functions from the most significant schema are returned.
  • Loading branch information
chengxiong-ruan committed Aug 5, 2022
1 parent 4900dce commit d1cdc47
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 44 deletions.
1 change: 0 additions & 1 deletion pkg/sql/crdb_internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -2629,7 +2629,6 @@ CREATE TABLE crdb_internal.create_function_statements (
)
})
})
return nil
},
}

Expand Down
36 changes: 34 additions & 2 deletions pkg/sql/delegate/show_function.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,42 @@
package delegate

import (
"fmt"

"github.com/cockroachdb/cockroach/pkg/sql/lexbase"
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
"github.com/cockroachdb/cockroach/pkg/util/errorutil/unimplemented"
"github.com/cockroachdb/errors"
)

func (d *delegator) delegateShowCreateFunction(n *tree.ShowCreateFunction) (tree.Statement, error) {
return nil, unimplemented.New("SHOW CREATE FUNCTION", "this statement is not yet supported")
// We don't need to filter by db since we don't allow cross-database
// references.
query := `
SELECT function_name, create_statement
FROM crdb_internal.create_function_statements
WHERE schema_name = %[1]s
AND function_name = %[2]s
`
un, ok := n.Name.FunctionReference.(*tree.UnresolvedName)
if !ok {
return nil, errors.AssertionFailedf("not a valid function name")
}

fn, err := d.catalog.ResolveFunction(d.ctx, un, &d.evalCtx.SessionData().SearchPath)
if err != nil {
return nil, err
}

var udfSchema string
for _, o := range fn.Overloads {
if o.IsUDF {
udfSchema = o.Schema
}
}
if udfSchema == "" {
return nil, errors.Errorf("function %s does not exist", tree.AsString(un))
}

fullQuery := fmt.Sprintf(query, lexbase.EscapeSQLString(udfSchema), lexbase.EscapeSQLString(un.Parts[0]))
return parse(fullQuery)
}
5 changes: 0 additions & 5 deletions pkg/sql/logictest/testdata/logic_test/show_create
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,3 @@ CREATE TABLE public.t (
CONSTRAINT t_pkey PRIMARY KEY (rowid ASC)
);
COMMENT ON COLUMN public.t.c IS 'first comment'

subtest show_create_function

statement error this statement is not yet supported
SHOW CREATE FUNCTION lower
72 changes: 38 additions & 34 deletions pkg/sql/logictest/testdata/logic_test/udf
Original file line number Diff line number Diff line change
Expand Up @@ -333,54 +333,58 @@ $$ 104 test 118 sc 119 proc_f_2

subtest show_create_function

query TT
SHOW CREATE FUNCTION proc_f;
query T
SELECT @2 FROM [SHOW CREATE FUNCTION proc_f];
----
proc_f CREATE FUNCTION public.proc_f(IN INT8)
RETURNS INT8
VOLATILE
NOT LEAKPROOF
CALLED ON NULL INPUT
AS $$
SELECT 1;
CREATE FUNCTION public.proc_f(IN INT8)
RETURNS INT8
VOLATILE
NOT LEAKPROOF
CALLED ON NULL INPUT
LANGUAGE SQL
AS $$
SELECT 1;
$$
proc_f CREATE FUNCTION public.proc_f(IN STRING, IN b INT8)
RETURNS SETOF STRING
IMMUTABLE
LEAKPROOF
STRICT
AS $$
SELECT 'hello';
CREATE FUNCTION public.proc_f(IN STRING, IN b INT8)
RETURNS SETOF STRING
IMMUTABLE
LEAKPROOF
STRICT
LANGUAGE SQL
AS $$
SELECT 'hello';
$$

statement error pq: unknown function: proc_f_2()
SHOW CREATE FUNCTION proc_f_2;

query TT
SHOW CREATE FUNCTION sc.proc_f_2;
query T
SELECT @2 FROM [SHOW CREATE FUNCTION sc.proc_f_2];
----
proc_f_2 CREATE FUNCTION sc.proc_f_2(IN STRING)
RETURNS STRING
VOLATILE
NOT LEAKPROOF
CALLED ON NULL INPUT
AS $$
SELECT 'hello';
CREATE FUNCTION sc.proc_f_2(IN STRING)
RETURNS STRING
VOLATILE
NOT LEAKPROOF
CALLED ON NULL INPUT
LANGUAGE SQL
AS $$
SELECT 'hello';
$$

statement ok
SET search_path = sc;

query TT
SHOW CREATE FUNCTION proc_f_2;
query T
SELECT @2 FROM [SHOW CREATE FUNCTION proc_f_2];
----
proc_f_2 CREATE FUNCTION sc.proc_f_2(IN STRING)
RETURNS STRING
VOLATILE
NOT LEAKPROOF
CALLED ON NULL INPUT
AS $$
SELECT 'hello';
CREATE FUNCTION sc.proc_f_2(IN STRING)
RETURNS STRING
VOLATILE
NOT LEAKPROOF
CALLED ON NULL INPUT
LANGUAGE SQL
AS $$
SELECT 'hello';
$$

statement ok
Expand Down
4 changes: 2 additions & 2 deletions pkg/sql/opt_catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,13 +331,13 @@ func (oc *optCatalog) ResolveType(
func (oc *optCatalog) ResolveFunction(
ctx context.Context, name *tree.UnresolvedName, path tree.SearchPath,
) (*tree.ResolvedFunctionDefinition, error) {
return nil, errors.AssertionFailedf("unimplemented")
return oc.planner.ResolveFunction(ctx, name, path)
}

func (oc *optCatalog) ResolveFunctionByOID(
ctx context.Context, oid oid.Oid,
) (*tree.Overload, error) {
return nil, errors.AssertionFailedf("unimplemented")
return oc.planner.ResolveFunctionByOID(ctx, oid)
}

func getDescFromCatalogObjectForPermissions(o cat.Object) (catalog.Descriptor, error) {
Expand Down

0 comments on commit d1cdc47

Please sign in to comment.