Skip to content

Commit

Permalink
sql: populate information_schema.role_routine_grants with builtins
Browse files Browse the repository at this point in the history
Backport resolves #84297.
This commit populates information_schema.role_routine_grants with
builtin functions. To match what postgres has, and since we don't
have a concept of privileges for builtin functions yet(anyone can
call builtins), two `grantee`s (root, PUBLIC) are used with `EXECUTE`
privilege not grantable.

Release note (sql change): information_schema.role_routine_grants
is now populated properly with both builtin functions and user-defined
functions.
Release justification: low risk GA blocker.
  • Loading branch information
chengxiong-ruan committed Sep 20, 2022
1 parent 58589fd commit 8107bc5
Show file tree
Hide file tree
Showing 2 changed files with 157 additions and 3 deletions.
53 changes: 50 additions & 3 deletions pkg/sql/information_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import (
"github.com/cockroachdb/cockroach/pkg/sql/catalog/schemaexpr"
"github.com/cockroachdb/cockroach/pkg/sql/catalog/tabledesc"
"github.com/cockroachdb/cockroach/pkg/sql/privilege"
"github.com/cockroachdb/cockroach/pkg/sql/sem/builtins"
"github.com/cockroachdb/cockroach/pkg/sql/sem/builtins/builtinsregistry"
"github.com/cockroachdb/cockroach/pkg/sql/sem/catconstants"
"github.com/cockroachdb/cockroach/pkg/sql/sem/catid"
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
Expand Down Expand Up @@ -1603,7 +1605,6 @@ var informationSchemaRoutinePrivilegesTable = virtualSchemaTable{
}

var informationSchemaRoleRoutineGrantsTable = virtualSchemaTable{
// TODO(chengxiong): add builtin function privileges as well.
comment: "privileges granted on functions (incomplete; only contains privileges of user-defined functions)",
schema: vtable.InformationSchemaRoleRoutineGrants,
populate: func(ctx context.Context, p *planner, db catalog.DatabaseDescriptor, addRow func(...tree.Datum) error) error {
Expand All @@ -1618,6 +1619,54 @@ var informationSchemaRoleRoutineGrantsTable = virtualSchemaTable{
dbDescs = append(dbDescs, db)
}
for _, db := range dbDescs {
dbNameStr := tree.NewDString(db.GetName())
exPriv := tree.NewDString(privilege.EXECUTE.String())
roleNameForBuiltins := []*tree.DString{
tree.NewDString(username.RootUser),
tree.NewDString(username.PublicRole),
}
for _, name := range builtins.AllBuiltinNames() {
parts := strings.Split(name, ".")
if len(parts) > 2 || len(parts) == 0 {
// This shouldn't happen in theory.
return errors.AssertionFailedf("invalid builtin function name: %s", name)
}

var fnNameStr string
var fnName *tree.DString
var scNameStr *tree.DString
if len(parts) == 2 {
scNameStr = tree.NewDString(parts[0])
fnNameStr = parts[1]
fnName = tree.NewDString(fnNameStr)
} else {
scNameStr = tree.NewDString(catconstants.PgCatalogName)
fnNameStr = name
fnName = tree.NewDString(fnNameStr)
}

_, overloads := builtinsregistry.GetBuiltinProperties(name)
for _, o := range overloads {
fnSpecificName := tree.NewDString(fmt.Sprintf("%s_%d", fnNameStr, o.Oid))
for _, grantee := range roleNameForBuiltins {
if err := addRow(
tree.DNull, // grantor
grantee,
dbNameStr, // specific_catalog
scNameStr, // specific_schema
fnSpecificName, // specific_name
dbNameStr, // routine_catalog
scNameStr, // routine_schema
fnName, // routine_name
exPriv, // privilege_type
noString, // is_grantable
); err != nil {
return err
}
}
}
}

err := db.ForEachSchema(func(id descpb.ID, name string) error {
sc, err := p.Descriptors().GetImmutableSchemaByID(ctx, p.txn, id, tree.SchemaLookupFlags{Required: true})
if err != nil {
Expand All @@ -1629,12 +1678,10 @@ var informationSchemaRoleRoutineGrantsTable = virtualSchemaTable{
return err
}
privs := fn.GetPrivileges()
dbNameStr := tree.NewDString(db.GetName())
scNameStr := tree.NewDString(sc.GetName())
fnSpecificName := tree.NewDString(fmt.Sprintf("%s_%d", fn.GetName(), catid.FuncIDToOID(fn.GetID())))
fnName := tree.NewDString(fn.GetName())
// EXECUTE is the only privilege kind relevant to functions.
exPriv := tree.NewDString(privilege.EXECUTE.String())
if err := addRow(
tree.DNull, // grantor
tree.NewDString(privs.Owner().Normalized()), // grantee
Expand Down
107 changes: 107 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/information_schema
Original file line number Diff line number Diff line change
Expand Up @@ -5140,3 +5140,110 @@ i NEVER
x NEVER
y NEVER
z ALWAYS

subtest role_routine_grants

query TTTTTTTTTT colnames
SELECT * FROM information_schema.role_routine_grants
WHERE reverse(split_part(reverse(specific_name), '_', 1))::INT < 50
ORDER BY specific_name, grantee;
----
grantor grantee specific_catalog specific_schema specific_name routine_catalog routine_schema routine_name privilege_type is_grantable
NULL public test pg_catalog array_agg_1 test pg_catalog array_agg EXECUTE NO
NULL root test pg_catalog array_agg_1 test pg_catalog array_agg EXECUTE NO
NULL public test pg_catalog array_agg_10 test pg_catalog array_agg EXECUTE NO
NULL root test pg_catalog array_agg_10 test pg_catalog array_agg EXECUTE NO
NULL public test pg_catalog array_agg_11 test pg_catalog array_agg EXECUTE NO
NULL root test pg_catalog array_agg_11 test pg_catalog array_agg EXECUTE NO
NULL public test pg_catalog array_agg_12 test pg_catalog array_agg EXECUTE NO
NULL root test pg_catalog array_agg_12 test pg_catalog array_agg EXECUTE NO
NULL public test pg_catalog array_agg_13 test pg_catalog array_agg EXECUTE NO
NULL root test pg_catalog array_agg_13 test pg_catalog array_agg EXECUTE NO
NULL public test pg_catalog array_agg_14 test pg_catalog array_agg EXECUTE NO
NULL root test pg_catalog array_agg_14 test pg_catalog array_agg EXECUTE NO
NULL public test pg_catalog array_agg_15 test pg_catalog array_agg EXECUTE NO
NULL root test pg_catalog array_agg_15 test pg_catalog array_agg EXECUTE NO
NULL public test pg_catalog array_agg_16 test pg_catalog array_agg EXECUTE NO
NULL root test pg_catalog array_agg_16 test pg_catalog array_agg EXECUTE NO
NULL public test pg_catalog array_agg_17 test pg_catalog array_agg EXECUTE NO
NULL root test pg_catalog array_agg_17 test pg_catalog array_agg EXECUTE NO
NULL public test pg_catalog array_agg_18 test pg_catalog array_agg EXECUTE NO
NULL root test pg_catalog array_agg_18 test pg_catalog array_agg EXECUTE NO
NULL public test pg_catalog array_agg_19 test pg_catalog array_agg EXECUTE NO
NULL root test pg_catalog array_agg_19 test pg_catalog array_agg EXECUTE NO
NULL public test pg_catalog array_agg_2 test pg_catalog array_agg EXECUTE NO
NULL root test pg_catalog array_agg_2 test pg_catalog array_agg EXECUTE NO
NULL public test pg_catalog array_agg_20 test pg_catalog array_agg EXECUTE NO
NULL root test pg_catalog array_agg_20 test pg_catalog array_agg EXECUTE NO
NULL public test pg_catalog array_agg_21 test pg_catalog array_agg EXECUTE NO
NULL root test pg_catalog array_agg_21 test pg_catalog array_agg EXECUTE NO
NULL public test pg_catalog array_agg_22 test pg_catalog array_agg EXECUTE NO
NULL root test pg_catalog array_agg_22 test pg_catalog array_agg EXECUTE NO
NULL public test pg_catalog array_agg_3 test pg_catalog array_agg EXECUTE NO
NULL root test pg_catalog array_agg_3 test pg_catalog array_agg EXECUTE NO
NULL public test pg_catalog array_agg_4 test pg_catalog array_agg EXECUTE NO
NULL root test pg_catalog array_agg_4 test pg_catalog array_agg EXECUTE NO
NULL public test pg_catalog array_agg_5 test pg_catalog array_agg EXECUTE NO
NULL root test pg_catalog array_agg_5 test pg_catalog array_agg EXECUTE NO
NULL public test pg_catalog array_agg_6 test pg_catalog array_agg EXECUTE NO
NULL root test pg_catalog array_agg_6 test pg_catalog array_agg EXECUTE NO
NULL public test pg_catalog array_agg_7 test pg_catalog array_agg EXECUTE NO
NULL root test pg_catalog array_agg_7 test pg_catalog array_agg EXECUTE NO
NULL public test pg_catalog array_agg_8 test pg_catalog array_agg EXECUTE NO
NULL root test pg_catalog array_agg_8 test pg_catalog array_agg EXECUTE NO
NULL public test pg_catalog array_agg_9 test pg_catalog array_agg EXECUTE NO
NULL root test pg_catalog array_agg_9 test pg_catalog array_agg EXECUTE NO
NULL public test pg_catalog avg_23 test pg_catalog avg EXECUTE NO
NULL root test pg_catalog avg_23 test pg_catalog avg EXECUTE NO
NULL public test pg_catalog avg_24 test pg_catalog avg EXECUTE NO
NULL root test pg_catalog avg_24 test pg_catalog avg EXECUTE NO
NULL public test pg_catalog avg_25 test pg_catalog avg EXECUTE NO
NULL root test pg_catalog avg_25 test pg_catalog avg EXECUTE NO
NULL public test pg_catalog avg_26 test pg_catalog avg EXECUTE NO
NULL root test pg_catalog avg_26 test pg_catalog avg EXECUTE NO
NULL public test pg_catalog bit_and_27 test pg_catalog bit_and EXECUTE NO
NULL root test pg_catalog bit_and_27 test pg_catalog bit_and EXECUTE NO
NULL public test pg_catalog bit_and_28 test pg_catalog bit_and EXECUTE NO
NULL root test pg_catalog bit_and_28 test pg_catalog bit_and EXECUTE NO
NULL public test pg_catalog bit_or_29 test pg_catalog bit_or EXECUTE NO
NULL root test pg_catalog bit_or_29 test pg_catalog bit_or EXECUTE NO
NULL public test pg_catalog bit_or_30 test pg_catalog bit_or EXECUTE NO
NULL root test pg_catalog bit_or_30 test pg_catalog bit_or EXECUTE NO
NULL public test pg_catalog bool_and_31 test pg_catalog bool_and EXECUTE NO
NULL root test pg_catalog bool_and_31 test pg_catalog bool_and EXECUTE NO
NULL public test pg_catalog bool_or_32 test pg_catalog bool_or EXECUTE NO
NULL root test pg_catalog bool_or_32 test pg_catalog bool_or EXECUTE NO
NULL public test pg_catalog concat_agg_33 test pg_catalog concat_agg EXECUTE NO
NULL root test pg_catalog concat_agg_33 test pg_catalog concat_agg EXECUTE NO
NULL public test pg_catalog concat_agg_34 test pg_catalog concat_agg EXECUTE NO
NULL root test pg_catalog concat_agg_34 test pg_catalog concat_agg EXECUTE NO
NULL public test pg_catalog corr_35 test pg_catalog corr EXECUTE NO
NULL root test pg_catalog corr_35 test pg_catalog corr EXECUTE NO
NULL public test pg_catalog corr_36 test pg_catalog corr EXECUTE NO
NULL root test pg_catalog corr_36 test pg_catalog corr EXECUTE NO
NULL public test pg_catalog corr_37 test pg_catalog corr EXECUTE NO
NULL root test pg_catalog corr_37 test pg_catalog corr EXECUTE NO
NULL public test pg_catalog corr_38 test pg_catalog corr EXECUTE NO
NULL root test pg_catalog corr_38 test pg_catalog corr EXECUTE NO
NULL public test pg_catalog corr_39 test pg_catalog corr EXECUTE NO
NULL root test pg_catalog corr_39 test pg_catalog corr EXECUTE NO
NULL public test pg_catalog corr_40 test pg_catalog corr EXECUTE NO
NULL root test pg_catalog corr_40 test pg_catalog corr EXECUTE NO
NULL public test pg_catalog corr_41 test pg_catalog corr EXECUTE NO
NULL root test pg_catalog corr_41 test pg_catalog corr EXECUTE NO
NULL public test pg_catalog corr_42 test pg_catalog corr EXECUTE NO
NULL root test pg_catalog corr_42 test pg_catalog corr EXECUTE NO
NULL public test pg_catalog corr_43 test pg_catalog corr EXECUTE NO
NULL root test pg_catalog corr_43 test pg_catalog corr EXECUTE NO
NULL public test pg_catalog covar_pop_44 test pg_catalog covar_pop EXECUTE NO
NULL root test pg_catalog covar_pop_44 test pg_catalog covar_pop EXECUTE NO
NULL public test pg_catalog covar_pop_45 test pg_catalog covar_pop EXECUTE NO
NULL root test pg_catalog covar_pop_45 test pg_catalog covar_pop EXECUTE NO
NULL public test pg_catalog covar_pop_46 test pg_catalog covar_pop EXECUTE NO
NULL root test pg_catalog covar_pop_46 test pg_catalog covar_pop EXECUTE NO
NULL public test pg_catalog covar_pop_47 test pg_catalog covar_pop EXECUTE NO
NULL root test pg_catalog covar_pop_47 test pg_catalog covar_pop EXECUTE NO
NULL public test pg_catalog covar_pop_48 test pg_catalog covar_pop EXECUTE NO
NULL root test pg_catalog covar_pop_48 test pg_catalog covar_pop EXECUTE NO
NULL public test pg_catalog covar_pop_49 test pg_catalog covar_pop EXECUTE NO
NULL root test pg_catalog covar_pop_49 test pg_catalog covar_pop EXECUTE NO

0 comments on commit 8107bc5

Please sign in to comment.