diff --git a/docs/generated/sql/bnf/alter_func_stmt.bnf b/docs/generated/sql/bnf/alter_func_stmt.bnf index 3620edcf23c6..3d2b4368831c 100644 --- a/docs/generated/sql/bnf/alter_func_stmt.bnf +++ b/docs/generated/sql/bnf/alter_func_stmt.bnf @@ -1,5 +1,5 @@ alter_func_stmt ::= - ( 'ALTER' 'FUNCTION' function_with_paramtypes ( ( ( 'CALLED' 'ON' 'NULL' 'INPUT' | 'RETURNS' 'NULL' 'ON' 'NULL' 'INPUT' | 'STRICT' | 'IMMUTABLE' | 'STABLE' | 'VOLATILE' | 'LEAKPROOF' | 'NOT' 'LEAKPROOF' ) ) ( ( ( 'CALLED' 'ON' 'NULL' 'INPUT' | 'RETURNS' 'NULL' 'ON' 'NULL' 'INPUT' | 'STRICT' | 'IMMUTABLE' | 'STABLE' | 'VOLATILE' | 'LEAKPROOF' | 'NOT' 'LEAKPROOF' ) ) )* ) ( 'RESTRICT' | ) ) + ( 'ALTER' 'FUNCTION' function_with_paramtypes ( ( ( 'CALLED' 'ON' 'NULL' 'INPUT' | 'RETURNS' 'NULL' 'ON' 'NULL' 'INPUT' | 'STRICT' | 'IMMUTABLE' | 'STABLE' | 'VOLATILE' | 'EXTERNAL' 'SECURITY' 'DEFINER' | 'EXTERNAL' 'SECURITY' 'INVOKER' | 'SECURITY' 'DEFINER' | 'SECURITY' 'INVOKER' | 'LEAKPROOF' | 'NOT' 'LEAKPROOF' ) ) ( ( ( 'CALLED' 'ON' 'NULL' 'INPUT' | 'RETURNS' 'NULL' 'ON' 'NULL' 'INPUT' | 'STRICT' | 'IMMUTABLE' | 'STABLE' | 'VOLATILE' | 'EXTERNAL' 'SECURITY' 'DEFINER' | 'EXTERNAL' 'SECURITY' 'INVOKER' | 'SECURITY' 'DEFINER' | 'SECURITY' 'INVOKER' | 'LEAKPROOF' | 'NOT' 'LEAKPROOF' ) ) )* ) ( 'RESTRICT' | ) ) | ( 'ALTER' 'FUNCTION' function_with_paramtypes 'RENAME' 'TO' function_new_name ) | ( 'ALTER' 'FUNCTION' function_with_paramtypes 'OWNER' 'TO' role_spec ) | ( 'ALTER' 'FUNCTION' function_with_paramtypes 'SET' 'SCHEMA' schema_name ) diff --git a/docs/generated/sql/bnf/create_func.bnf b/docs/generated/sql/bnf/create_func.bnf index 90ae04a97ba4..4e162a18fd5d 100644 --- a/docs/generated/sql/bnf/create_func.bnf +++ b/docs/generated/sql/bnf/create_func.bnf @@ -1,3 +1,3 @@ create_func_stmt ::= - 'CREATE' ( 'OR' 'REPLACE' | ) 'FUNCTION' routine_create_name '(' ( ( ( ( routine_param | routine_param | routine_param ) ) ( ( ',' ( routine_param | routine_param | routine_param ) ) )* ) | ) ')' 'RETURNS' ( 'SETOF' | ) routine_return_type ( ( ( ( 'AS' routine_body_str | 'LANGUAGE' ('SQL' | 'PLPGSQL') | ( 'CALLED' 'ON' 'NULL' 'INPUT' | 'RETURNS' 'NULL' 'ON' 'NULL' 'INPUT' | 'STRICT' | 'IMMUTABLE' | 'STABLE' | 'VOLATILE' | 'LEAKPROOF' | 'NOT' 'LEAKPROOF' ) ) ) ( ( ( 'AS' routine_body_str | 'LANGUAGE' ('SQL' | 'PLPGSQL') | ( 'CALLED' 'ON' 'NULL' 'INPUT' | 'RETURNS' 'NULL' 'ON' 'NULL' 'INPUT' | 'STRICT' | 'IMMUTABLE' | 'STABLE' | 'VOLATILE' | 'LEAKPROOF' | 'NOT' 'LEAKPROOF' ) ) ) )* ) | ) - | 'CREATE' ( 'OR' 'REPLACE' | ) 'FUNCTION' routine_create_name '(' ( ( ( ( routine_param | routine_param | routine_param ) ) ( ( ',' ( routine_param | routine_param | routine_param ) ) )* ) | ) ')' ( ( ( ( 'AS' routine_body_str | 'LANGUAGE' ('SQL' | 'PLPGSQL') | ( 'CALLED' 'ON' 'NULL' 'INPUT' | 'RETURNS' 'NULL' 'ON' 'NULL' 'INPUT' | 'STRICT' | 'IMMUTABLE' | 'STABLE' | 'VOLATILE' | 'LEAKPROOF' | 'NOT' 'LEAKPROOF' ) ) ) ( ( ( 'AS' routine_body_str | 'LANGUAGE' ('SQL' | 'PLPGSQL') | ( 'CALLED' 'ON' 'NULL' 'INPUT' | 'RETURNS' 'NULL' 'ON' 'NULL' 'INPUT' | 'STRICT' | 'IMMUTABLE' | 'STABLE' | 'VOLATILE' | 'LEAKPROOF' | 'NOT' 'LEAKPROOF' ) ) ) )* ) | ) + 'CREATE' ( 'OR' 'REPLACE' | ) 'FUNCTION' routine_create_name '(' ( ( ( ( routine_param | routine_param | routine_param ) ) ( ( ',' ( routine_param | routine_param | routine_param ) ) )* ) | ) ')' 'RETURNS' ( 'SETOF' | ) routine_return_type ( ( ( ( 'AS' routine_body_str | 'LANGUAGE' ('SQL' | 'PLPGSQL') | ( 'CALLED' 'ON' 'NULL' 'INPUT' | 'RETURNS' 'NULL' 'ON' 'NULL' 'INPUT' | 'STRICT' | 'IMMUTABLE' | 'STABLE' | 'VOLATILE' | 'EXTERNAL' 'SECURITY' 'DEFINER' | 'EXTERNAL' 'SECURITY' 'INVOKER' | 'SECURITY' 'DEFINER' | 'SECURITY' 'INVOKER' | 'LEAKPROOF' | 'NOT' 'LEAKPROOF' ) ) ) ( ( ( 'AS' routine_body_str | 'LANGUAGE' ('SQL' | 'PLPGSQL') | ( 'CALLED' 'ON' 'NULL' 'INPUT' | 'RETURNS' 'NULL' 'ON' 'NULL' 'INPUT' | 'STRICT' | 'IMMUTABLE' | 'STABLE' | 'VOLATILE' | 'EXTERNAL' 'SECURITY' 'DEFINER' | 'EXTERNAL' 'SECURITY' 'INVOKER' | 'SECURITY' 'DEFINER' | 'SECURITY' 'INVOKER' | 'LEAKPROOF' | 'NOT' 'LEAKPROOF' ) ) ) )* ) | ) + | 'CREATE' ( 'OR' 'REPLACE' | ) 'FUNCTION' routine_create_name '(' ( ( ( ( routine_param | routine_param | routine_param ) ) ( ( ',' ( routine_param | routine_param | routine_param ) ) )* ) | ) ')' ( ( ( ( 'AS' routine_body_str | 'LANGUAGE' ('SQL' | 'PLPGSQL') | ( 'CALLED' 'ON' 'NULL' 'INPUT' | 'RETURNS' 'NULL' 'ON' 'NULL' 'INPUT' | 'STRICT' | 'IMMUTABLE' | 'STABLE' | 'VOLATILE' | 'EXTERNAL' 'SECURITY' 'DEFINER' | 'EXTERNAL' 'SECURITY' 'INVOKER' | 'SECURITY' 'DEFINER' | 'SECURITY' 'INVOKER' | 'LEAKPROOF' | 'NOT' 'LEAKPROOF' ) ) ) ( ( ( 'AS' routine_body_str | 'LANGUAGE' ('SQL' | 'PLPGSQL') | ( 'CALLED' 'ON' 'NULL' 'INPUT' | 'RETURNS' 'NULL' 'ON' 'NULL' 'INPUT' | 'STRICT' | 'IMMUTABLE' | 'STABLE' | 'VOLATILE' | 'EXTERNAL' 'SECURITY' 'DEFINER' | 'EXTERNAL' 'SECURITY' 'INVOKER' | 'SECURITY' 'DEFINER' | 'SECURITY' 'INVOKER' | 'LEAKPROOF' | 'NOT' 'LEAKPROOF' ) ) ) )* ) | ) diff --git a/docs/generated/sql/bnf/stmt_block.bnf b/docs/generated/sql/bnf/stmt_block.bnf index bb9163d130b1..29a4aab3af77 100644 --- a/docs/generated/sql/bnf/stmt_block.bnf +++ b/docs/generated/sql/bnf/stmt_block.bnf @@ -3552,6 +3552,10 @@ common_routine_opt_item ::= | 'IMMUTABLE' | 'STABLE' | 'VOLATILE' + | 'EXTERNAL' 'SECURITY' 'DEFINER' + | 'EXTERNAL' 'SECURITY' 'INVOKER' + | 'SECURITY' 'DEFINER' + | 'SECURITY' 'INVOKER' | 'LEAKPROOF' | 'NOT' 'LEAKPROOF' diff --git a/pkg/ccl/backupccl/testdata/backup-restore/plpgsql_procedures b/pkg/ccl/backupccl/testdata/backup-restore/plpgsql_procedures index 15108a5b2e45..b93d4305cb27 100644 --- a/pkg/ccl/backupccl/testdata/backup-restore/plpgsql_procedures +++ b/pkg/ccl/backupccl/testdata/backup-restore/plpgsql_procedures @@ -94,6 +94,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE sc1.p1] ---- CREATE PROCEDURE sc1.p1(a sc1.enum1) LANGUAGE plpgsql + SECURITY INVOKER AS $$ DECLARE foobar sc1.enum1; @@ -134,6 +135,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE sc1.p1] ---- CREATE PROCEDURE sc1.p1(a sc1.enum1) LANGUAGE plpgsql + SECURITY INVOKER AS $$ DECLARE foobar sc1.enum1; @@ -300,6 +302,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE sc1.p1] ---- CREATE PROCEDURE sc1.p1(a sc1.enum1) LANGUAGE plpgsql + SECURITY INVOKER AS $$ DECLARE foobar sc1.enum1; @@ -341,6 +344,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE sc1.p1] ---- CREATE PROCEDURE sc1.p1(a sc1.enum1) LANGUAGE plpgsql + SECURITY INVOKER AS $$ DECLARE foobar sc1.enum1; diff --git a/pkg/ccl/backupccl/testdata/backup-restore/plpgsql_user_defined_functions b/pkg/ccl/backupccl/testdata/backup-restore/plpgsql_user_defined_functions index d720c6355d98..76f689693562 100644 --- a/pkg/ccl/backupccl/testdata/backup-restore/plpgsql_user_defined_functions +++ b/pkg/ccl/backupccl/testdata/backup-restore/plpgsql_user_defined_functions @@ -115,6 +115,7 @@ CREATE FUNCTION sc1.f1(a sc1.enum1) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE plpgsql + SECURITY INVOKER AS $$ DECLARE x INT8 := 0; @@ -140,6 +141,7 @@ CREATE FUNCTION sc2.f2() NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE plpgsql + SECURITY INVOKER AS $$ DECLARE x INT8; @@ -176,6 +178,7 @@ CREATE FUNCTION sc1.f1(a sc1.enum1) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE plpgsql + SECURITY INVOKER AS $$ DECLARE x INT8 := 0; @@ -196,6 +199,7 @@ CREATE FUNCTION sc2.f2() NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE plpgsql + SECURITY INVOKER AS $$ DECLARE x INT8; @@ -366,6 +370,7 @@ CREATE FUNCTION sc1.f1(a sc1.enum1) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE plpgsql + SECURITY INVOKER AS $$ DECLARE x INT8; @@ -409,6 +414,7 @@ CREATE FUNCTION sc1.f1(a sc1.enum1) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE plpgsql + SECURITY INVOKER AS $$ DECLARE x INT8; diff --git a/pkg/ccl/backupccl/testdata/backup-restore/procedures b/pkg/ccl/backupccl/testdata/backup-restore/procedures index 43110e061a71..efc0ac268267 100644 --- a/pkg/ccl/backupccl/testdata/backup-restore/procedures +++ b/pkg/ccl/backupccl/testdata/backup-restore/procedures @@ -88,6 +88,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE sc1.p1] ---- CREATE PROCEDURE sc1.p1(a sc1.enum1) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT a FROM db1.sc1.tbl1; SELECT 'Good':::sc1.enum1; @@ -124,6 +125,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE sc1.p1] ---- CREATE PROCEDURE sc1.p1(a sc1.enum1) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT a FROM db1_new.sc1.tbl1; SELECT 'Good':::sc1.enum1; @@ -280,6 +282,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE sc1.p1] ---- CREATE PROCEDURE sc1.p1(a sc1.enum1) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT a FROM db1.sc1.tbl1; SELECT 'Good':::sc1.enum1; @@ -317,6 +320,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE sc1.p1] ---- CREATE PROCEDURE sc1.p1(a sc1.enum1) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT a FROM db1.sc1.tbl1; SELECT 'Good':::sc1.enum1; diff --git a/pkg/ccl/backupccl/testdata/backup-restore/user-defined-functions b/pkg/ccl/backupccl/testdata/backup-restore/user-defined-functions index 330252f3b41d..4adaeb06527b 100644 --- a/pkg/ccl/backupccl/testdata/backup-restore/user-defined-functions +++ b/pkg/ccl/backupccl/testdata/backup-restore/user-defined-functions @@ -91,6 +91,7 @@ CREATE FUNCTION sc1.f1(a sc1.enum1) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT a FROM db1.sc1.tbl1; SELECT 'Good':::sc1.enum1; @@ -127,6 +128,7 @@ CREATE FUNCTION sc1.f1(a sc1.enum1) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT a FROM db1_new.sc1.tbl1; SELECT 'Good':::sc1.enum1; @@ -275,6 +277,7 @@ CREATE FUNCTION sc1.f1(a sc1.enum1) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT a FROM db1.sc1.tbl1; SELECT 'Good':::sc1.enum1; @@ -312,6 +315,7 @@ CREATE FUNCTION sc1.f1(a sc1.enum1) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT a FROM db1.sc1.tbl1; SELECT 'Good':::sc1.enum1; diff --git a/pkg/ccl/logictestccl/testdata/logic_test/procedure_params b/pkg/ccl/logictestccl/testdata/logic_test/procedure_params index 0c77f4cd0e36..1bb26675ee8b 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/procedure_params +++ b/pkg/ccl/logictestccl/testdata/logic_test/procedure_params @@ -347,6 +347,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE p_param_types]; ---- CREATE PROCEDURE public.p_param_types(IN p1 INT8, INOUT p2 INT8, INOUT p3 INT8, OUT p4 INT8) LANGUAGE plpgsql + SECURITY INVOKER AS $$ BEGIN SELECT p2, p3, p1; @@ -368,6 +369,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE p_param_types]; ---- CREATE PROCEDURE public.p_param_types(OUT param INT8) LANGUAGE plpgsql + SECURITY INVOKER AS $$ BEGIN SELECT 1; @@ -480,6 +482,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE p_default_names]; ---- CREATE PROCEDURE public.p_default_names(OUT INT8, OUT param2 INT8, IN INT8, OUT column3 INT8) LANGUAGE plpgsql + SECURITY INVOKER AS $$ BEGIN SELECT 3 INTO column3; @@ -505,6 +508,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE p_default_names]; ---- CREATE PROCEDURE public.p_default_names(OUT INT8, OUT param2 INT8, IN INT8, OUT INT8) LANGUAGE plpgsql + SECURITY INVOKER AS $$ BEGIN param2 := 2; @@ -526,6 +530,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE p_default_names]; ---- CREATE PROCEDURE public.p_default_names(OUT INT8, OUT param2 INT8, IN in_param INT8, OUT INT8) LANGUAGE plpgsql + SECURITY INVOKER AS $$ BEGIN SELECT in_param INTO param2; diff --git a/pkg/ccl/logictestccl/testdata/logic_test/show_create b/pkg/ccl/logictestccl/testdata/logic_test/show_create index 7db494238417..b6b7156f2fd5 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/show_create +++ b/pkg/ccl/logictestccl/testdata/logic_test/show_create @@ -76,6 +76,7 @@ r1 CREATE FUNCTION public.r1() NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -85,6 +86,7 @@ r1 CREATE FUNCTION public.r1(i INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -95,11 +97,13 @@ SELECT * FROM [SHOW CREATE PROCEDURE r1] ORDER BY 2 ---- r1 CREATE PROCEDURE public.r1(s STRING) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ r1 CREATE PROCEDURE public.r1(s STRING, i INT8) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -131,6 +135,7 @@ r2 CREATE FUNCTION sc.r2() NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -140,6 +145,7 @@ SHOW CREATE PROCEDURE r2 ---- r2 CREATE PROCEDURE sc.r2(s STRING) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -169,6 +175,7 @@ f112134 CREATE FUNCTION sc.f112134() NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE plpgsql + SECURITY INVOKER AS $$ DECLARE x INT8 := 0; diff --git a/pkg/ccl/logictestccl/testdata/logic_test/udf_params b/pkg/ccl/logictestccl/testdata/logic_test/udf_params index 14797533673d..1f385c3faee4 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/udf_params +++ b/pkg/ccl/logictestccl/testdata/logic_test/udf_params @@ -224,6 +224,7 @@ CREATE FUNCTION public.f_param_types(IN p1 INT8, INOUT p2 INT8, INOUT p3 INT8, O NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE plpgsql + SECURITY INVOKER AS $$ BEGIN SELECT p2, p3, p1; @@ -249,6 +250,7 @@ CREATE FUNCTION public.f_param_types(OUT param INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE plpgsql + SECURITY INVOKER AS $$ BEGIN SELECT 1; @@ -323,6 +325,7 @@ CREATE FUNCTION public.f_out_int(OUT param_new INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE plpgsql + SECURITY INVOKER AS $$ BEGIN param_new := 2; @@ -378,6 +381,7 @@ CREATE FUNCTION public.f_int(INOUT param INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE plpgsql + SECURITY INVOKER AS $$ BEGIN param := 2; @@ -408,6 +412,7 @@ CREATE FUNCTION public.f_int(IN param INT8, OUT param_out INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE plpgsql + SECURITY INVOKER AS $$ BEGIN SELECT param INTO param_out; @@ -432,6 +437,7 @@ CREATE FUNCTION public.f_int(OUT param_out INT8, IN param INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE plpgsql + SECURITY INVOKER AS $$ BEGIN SELECT param INTO param_out; @@ -456,6 +462,7 @@ CREATE FUNCTION public.f_int(INOUT param INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE plpgsql + SECURITY INVOKER AS $$ BEGIN param := param; @@ -488,6 +495,7 @@ CREATE FUNCTION public.f_default_names(OUT INT8, OUT param2 INT8, IN INT8, OUT I NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE plpgsql + SECURITY INVOKER AS $$ BEGIN param2 := 2; @@ -546,6 +554,7 @@ CREATE FUNCTION public.f_default_names(OUT INT8, OUT param2 INT8, IN INT8, OUT c NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE plpgsql + SECURITY INVOKER AS $$ BEGIN SELECT 3 INTO column3; @@ -575,6 +584,7 @@ CREATE FUNCTION public.f_default_names(OUT INT8, OUT param2 INT8, IN INT8, OUT I NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE plpgsql + SECURITY INVOKER AS $$ BEGIN param2 := 2; @@ -594,6 +604,7 @@ CREATE FUNCTION public.f_default_names(OUT INT8, OUT param2 INT8, IN in_param IN NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE plpgsql + SECURITY INVOKER AS $$ BEGIN SELECT in_param INTO param2; diff --git a/pkg/ccl/logictestccl/testdata/logic_test/udf_rewrite b/pkg/ccl/logictestccl/testdata/logic_test/udf_rewrite index e5a93d563f05..3f908d4faeca 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/udf_rewrite +++ b/pkg/ccl/logictestccl/testdata/logic_test/udf_rewrite @@ -94,6 +94,7 @@ f_rewrite CREATE FUNCTION public.f_rewrite() NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE plpgsql + SECURITY INVOKER AS $$ DECLARE i INT8 := nextval('public.seq'::REGCLASS); @@ -157,6 +158,7 @@ f_rewrite CREATE FUNCTION public.f_rewrite() NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE plpgsql + SECURITY INVOKER AS $$ DECLARE i INT8 := nextval('public.renamed'::REGCLASS); @@ -289,6 +291,7 @@ f_rewrite CREATE FUNCTION public.f_rewrite() NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE plpgsql + SECURITY INVOKER AS $$ DECLARE day public.weekday := 'wednesday':::public.weekday; @@ -355,6 +358,7 @@ f_rewrite CREATE FUNCTION public.f_rewrite() NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE plpgsql + SECURITY INVOKER AS $$ DECLARE day public.workday := 'humpday':::public.workday; @@ -434,6 +438,7 @@ f_rewrite CREATE FUNCTION public.f_rewrite(INOUT param1 public.weekday, OUT par NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE plpgsql + SECURITY INVOKER AS $$ BEGIN param2 := param1; @@ -461,6 +466,7 @@ f_rewrite CREATE FUNCTION public.f_rewrite(INOUT param1 public.workday, OUT par NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE plpgsql + SECURITY INVOKER AS $$ BEGIN param2 := param1; @@ -533,6 +539,7 @@ SHOW CREATE PROCEDURE p_rewrite; ---- p_rewrite CREATE PROCEDURE public.p_rewrite(INOUT param1 public.weekday, OUT param2 public.weekday) LANGUAGE plpgsql + SECURITY INVOKER AS $$ BEGIN param2 := param1; @@ -556,6 +563,7 @@ SHOW CREATE PROCEDURE p_rewrite; ---- p_rewrite CREATE PROCEDURE public.p_rewrite(INOUT param1 public.workday, OUT param2 public.workday) LANGUAGE plpgsql + SECURITY INVOKER AS $$ BEGIN param2 := param1; diff --git a/pkg/sql/catalog/catpb/function.proto b/pkg/sql/catalog/catpb/function.proto index ae6b0681d0f6..2c0da590be3a 100644 --- a/pkg/sql/catalog/catpb/function.proto +++ b/pkg/sql/catalog/catpb/function.proto @@ -46,6 +46,11 @@ message Function { VARIADIC = 4; } } + + enum Security { + INVOKER = 0; + DEFINER = 1; + } } // These wrappers are for the convenience of referencing the enum types from a @@ -69,3 +74,9 @@ message FunctionParamClass { option (gogoproto.equal) = true; optional Function.Param.Class class = 1 [(gogoproto.nullable) = false]; } + +message FunctionSecurity { + option (gogoproto.equal) = true; + // If security is not explicitly set, the default security mode is INVOKER. + optional Function.Security security = 1 [(gogoproto.nullable) = false]; +} diff --git a/pkg/sql/catalog/descpb/structured.proto b/pkg/sql/catalog/descpb/structured.proto index 7121af7d2253..c7321b0d7a4e 100644 --- a/pkg/sql/catalog/descpb/structured.proto +++ b/pkg/sql/catalog/descpb/structured.proto @@ -1732,7 +1732,11 @@ message FunctionDescriptor { // depends on. repeated uint32 depends_on_functions = 22 [(gogoproto.casttype) = "ID"]; - // Next field id is 23 + // Security contains the security mode that this function gets executed with. + // The default mode is INVOKER. + optional cockroach.sql.catalog.catpb.Function.Security security = 23 [(gogoproto.nullable) = false]; + + // Next field id is 24 } // Descriptor is a union type for descriptors for tables, schemas, databases, diff --git a/pkg/sql/catalog/descriptor.go b/pkg/sql/catalog/descriptor.go index 86b80ceda0d1..c306338dd457 100644 --- a/pkg/sql/catalog/descriptor.go +++ b/pkg/sql/catalog/descriptor.go @@ -999,6 +999,9 @@ type FunctionDescriptor interface { // IsProcedure returns true if the descriptor represents a procedure. It // returns false if the descriptor represents a user-defined function. IsProcedure() bool + + // GetSecurity returns the security specification of this function. + GetSecurity() catpb.Function_Security } // FilterDroppedDescriptor returns an error if the descriptor state is DROP. diff --git a/pkg/sql/catalog/funcdesc/func_desc.go b/pkg/sql/catalog/funcdesc/func_desc.go index a27a91e4f802..0f915230c481 100644 --- a/pkg/sql/catalog/funcdesc/func_desc.go +++ b/pkg/sql/catalog/funcdesc/func_desc.go @@ -576,6 +576,11 @@ func (desc *Mutable) SetFuncBody(v string) { desc.FunctionBody = v } +// SetSecurity sets the Security attribute. +func (desc *Mutable) SetSecurity(v catpb.Function_Security) { + desc.Security = v +} + // SetName sets the function name. func (desc *Mutable) SetName(n string) { desc.Name = n @@ -775,6 +780,10 @@ func (desc *immutable) GetLanguage() catpb.Function_Language { return desc.Lang } +func (desc *immutable) GetSecurity() catpb.Function_Security { + return desc.Security +} + func (desc *immutable) ToOverload() (ret *tree.Overload, err error) { routineType := tree.UDFRoutine if desc.IsProcedure() { @@ -885,14 +894,15 @@ func (desc *immutable) ToCreateExpr() (ret *tree.CreateRoutine, err error) { } } } - // We only store 5 function attributes at the moment. We may extend the + // We only store 6 function attributes at the moment. We may extend the // pre-allocated capacity in the future. - ret.Options = make(tree.RoutineOptions, 0, 5) + ret.Options = make(tree.RoutineOptions, 0, 6) ret.Options = append(ret.Options, desc.getCreateExprVolatility()) ret.Options = append(ret.Options, tree.RoutineLeakproof(desc.LeakProof)) ret.Options = append(ret.Options, desc.getCreateExprNullInputBehavior()) ret.Options = append(ret.Options, tree.RoutineBodyStr(desc.FunctionBody)) ret.Options = append(ret.Options, desc.getCreateExprLang()) + ret.Options = append(ret.Options, desc.getCreateExprSecurity()) return ret, nil } @@ -935,7 +945,17 @@ func (desc *immutable) getCreateExprNullInputBehavior() tree.RoutineNullInputBeh return 0 } -// ToTreeRoutineParamClass converts the proto enum value to the correspoding +func (desc *immutable) getCreateExprSecurity() tree.RoutineSecurity { + switch desc.Security { + case catpb.Function_INVOKER: + return tree.RoutineInvoker + case catpb.Function_DEFINER: + return tree.RoutineDefiner + } + return 0 +} + +// ToTreeRoutineParamClass converts the proto enum value to the corresponding // tree.RoutineParamClass. func ToTreeRoutineParamClass(class catpb.Function_Param_Class) tree.RoutineParamClass { switch class { diff --git a/pkg/sql/catalog/funcinfo/properties.go b/pkg/sql/catalog/funcinfo/properties.go index 3e8bf510247a..910ba25b20bf 100644 --- a/pkg/sql/catalog/funcinfo/properties.go +++ b/pkg/sql/catalog/funcinfo/properties.go @@ -135,3 +135,14 @@ func ParamClassToProto(v tree.RoutineParamClass) (catpb.Function_Param_Class, er return -1, errors.AssertionFailedf("unknown function parameter class %q", v) } + +// SecurityToProto converts sql statement input security to protobuf type. +func SecurityToProto(v tree.RoutineSecurity) (catpb.Function_Security, error) { + switch v { + case tree.RoutineInvoker: + return catpb.Function_INVOKER, nil + case tree.RoutineDefiner: + return catpb.Function_DEFINER, nil + } + return -1, errors.AssertionFailedf("unknown function security class %q", v) +} diff --git a/pkg/sql/catalog/tabledesc/validate_test.go b/pkg/sql/catalog/tabledesc/validate_test.go index e75f2e01e06e..68f8703165c5 100644 --- a/pkg/sql/catalog/tabledesc/validate_test.go +++ b/pkg/sql/catalog/tabledesc/validate_test.go @@ -330,6 +330,7 @@ var validationMap = []struct { "Version": {status: thisFieldReferencesNoObjects}, "DeclarativeSchemaChangerState": {status: thisFieldReferencesNoObjects}, "IsProcedure": {status: thisFieldReferencesNoObjects}, + "Security": {status: thisFieldReferencesNoObjects}, }, }, } diff --git a/pkg/sql/create_function.go b/pkg/sql/create_function.go index a94012b510f0..033f0d843f55 100644 --- a/pkg/sql/create_function.go +++ b/pkg/sql/create_function.go @@ -575,6 +575,12 @@ func setFuncOptions( // Handle the body after the loop, since we don't yet know what language // it is. body = string(t) + case tree.RoutineSecurity: + sec, err := funcinfo.SecurityToProto(t) + if err != nil { + return err + } + udfDesc.SetSecurity(sec) default: return pgerror.Newf(pgcode.InvalidParameterValue, "Unknown function option %q", t) } diff --git a/pkg/sql/logictest/testdata/logic_test/crdb_internal b/pkg/sql/logictest/testdata/logic_test/crdb_internal index e783e5847265..119306f4ab3d 100644 --- a/pkg/sql/logictest/testdata/logic_test/crdb_internal +++ b/pkg/sql/logictest/testdata/logic_test/crdb_internal @@ -1496,6 +1496,7 @@ test public f CREATE FUNCTION public.f(INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -1505,6 +1506,7 @@ test public f CREATE FUNCTION public.f(STRING, b INT8) LEAKPROOF STRICT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 'hello'; $$ @@ -1514,6 +1516,7 @@ test sc f2 CREATE FUNCTION sc.f2(STRING) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 'hello'; $$ @@ -1536,6 +1539,7 @@ test public f CREATE FUNCTION public.f(INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -1545,6 +1549,7 @@ test public f CREATE FUNCTION public.f(STRING, b INT8) LEAKPROOF STRICT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 'hello'; $$ @@ -1554,6 +1559,7 @@ test sc f2 CREATE FUNCTION sc.f2(STRING) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 'hello'; $$ @@ -1563,6 +1569,7 @@ test_cross_db public f_cross_db CREATE FUNCTION public.f_cross_db() NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -1610,16 +1617,19 @@ ORDER BY procedure_id; ---- 104 test 105 public 139 p CREATE PROCEDURE public.p(INT8) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ 104 test 105 public 140 p CREATE PROCEDURE public.p(STRING, b INT8) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 'hello'; $$ 104 test 142 sc 143 p2 CREATE PROCEDURE sc.p2(STRING) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 'hello'; $$ @@ -1638,21 +1648,25 @@ ORDER BY procedure_id; ---- 104 test 105 public 139 p CREATE PROCEDURE public.p(INT8) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ 104 test 105 public 140 p CREATE PROCEDURE public.p(STRING, b INT8) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 'hello'; $$ 104 test 142 sc 143 p2 CREATE PROCEDURE sc.p2(STRING) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 'hello'; $$ 144 test_cross_db 145 public 146 p_cross_db CREATE PROCEDURE public.p_cross_db() LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ diff --git a/pkg/sql/logictest/testdata/logic_test/drop_function b/pkg/sql/logictest/testdata/logic_test/drop_function index 7a57e508a289..a513811845ae 100644 --- a/pkg/sql/logictest/testdata/logic_test/drop_function +++ b/pkg/sql/logictest/testdata/logic_test/drop_function @@ -22,6 +22,7 @@ CREATE FUNCTION public.f_test_drop() NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -31,6 +32,7 @@ CREATE FUNCTION public.f_test_drop(INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -44,6 +46,7 @@ CREATE FUNCTION sc1.f_test_drop(INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -94,6 +97,7 @@ CREATE FUNCTION public.f_test_drop(INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -107,6 +111,7 @@ CREATE FUNCTION sc1.f_test_drop(INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -128,6 +133,7 @@ CREATE FUNCTION sc1.f_test_drop(INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -153,6 +159,7 @@ CREATE FUNCTION public.f_test_drop() NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -166,6 +173,7 @@ CREATE FUNCTION sc1.f_test_drop() NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -211,6 +219,7 @@ CREATE FUNCTION public.f114677(v public.t114677) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 0; $$ @@ -220,6 +229,7 @@ CREATE FUNCTION public.f114677(v public.t114677_2) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -239,6 +249,7 @@ CREATE FUNCTION public.f114677(v public.t114677_2) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ diff --git a/pkg/sql/logictest/testdata/logic_test/drop_procedure b/pkg/sql/logictest/testdata/logic_test/drop_procedure index 20b3642ef109..8fb221c1630f 100644 --- a/pkg/sql/logictest/testdata/logic_test/drop_procedure +++ b/pkg/sql/logictest/testdata/logic_test/drop_procedure @@ -18,11 +18,13 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE public.p_test_drop] ORDER BY ---- CREATE PROCEDURE public.p_test_drop() LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ CREATE PROCEDURE public.p_test_drop(INT8) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -32,6 +34,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE sc1.p_test_drop] ---- CREATE PROCEDURE sc1.p_test_drop(INT8) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -81,6 +84,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE public.p_test_drop] ---- CREATE PROCEDURE public.p_test_drop(INT8) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -90,6 +94,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE sc1.p_test_drop] ---- CREATE PROCEDURE sc1.p_test_drop(INT8) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -110,6 +115,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE sc1.p_test_drop] ---- CREATE PROCEDURE sc1.p_test_drop(INT8) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -134,6 +140,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE public.p_test_drop] ---- CREATE PROCEDURE public.p_test_drop() LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -143,6 +150,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE sc1.p_test_drop] ---- CREATE PROCEDURE sc1.p_test_drop() LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ diff --git a/pkg/sql/logictest/testdata/logic_test/procedure_params b/pkg/sql/logictest/testdata/logic_test/procedure_params index d33f69b45396..35d818aa366e 100644 --- a/pkg/sql/logictest/testdata/logic_test/procedure_params +++ b/pkg/sql/logictest/testdata/logic_test/procedure_params @@ -223,6 +223,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE p]; ---- CREATE PROCEDURE public.p(IN p1 INT8, INOUT p2 INT8, INOUT p3 INT8, OUT p4 INT8) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT p2, p3, p1; $$ @@ -240,6 +241,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE p]; ---- CREATE PROCEDURE public.p(OUT param INT8) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -368,6 +370,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE p_3_in_2_out]; ---- CREATE PROCEDURE public.p_3_in_2_out(IN param1 INT8, OUT param1 INT8, IN param2 INT8, IN param3 INT8, OUT param2 INT8) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT (param1, param2 + param3); $$ @@ -390,6 +393,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE p_3_in_2_out]; ---- CREATE PROCEDURE public.p_3_in_2_out(INOUT param1 INT8, INOUT param2 INT8, IN param3 INT8) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT (param1, param2 + param3); $$ @@ -415,6 +419,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE p_default_names]; ---- CREATE PROCEDURE public.p_default_names(OUT INT8, OUT param2 INT8, IN INT8, OUT INT8) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT (1:::INT8, 2:::INT8, 3:::INT8); $$ @@ -439,6 +444,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE p_default_names]; ---- CREATE PROCEDURE public.p_default_names(OUT INT8, OUT param2 INT8, IN INT8, OUT column3 INT8) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT (1:::INT8, 2:::INT8, 3:::INT8); $$ @@ -458,6 +464,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE p_default_names]; ---- CREATE PROCEDURE public.p_default_names(OUT INT8, OUT param2 INT8, IN INT8, OUT INT8) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT (1:::INT8, 2:::INT8, 3:::INT8); $$ @@ -477,6 +484,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE p_default_names]; ---- CREATE PROCEDURE public.p_default_names(OUT INT8, OUT param2 INT8, IN in_param INT8, OUT INT8) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT (in_param, 2, 3); $$ diff --git a/pkg/sql/logictest/testdata/logic_test/procedure_schema_change b/pkg/sql/logictest/testdata/logic_test/procedure_schema_change index d37390ad2898..84c82f1ac580 100644 --- a/pkg/sql/logictest/testdata/logic_test/procedure_schema_change +++ b/pkg/sql/logictest/testdata/logic_test/procedure_schema_change @@ -35,6 +35,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE p_new]; ---- CREATE PROCEDURE public.p_new() LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -52,11 +53,13 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE p_int] ORDER BY 1 ---- CREATE PROCEDURE public.p_int() LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ CREATE PROCEDURE public.p_int(INT8) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -71,6 +74,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE p_int] ORDER BY 1 ---- CREATE PROCEDURE public.p_int() LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -80,6 +84,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE p_func] ---- CREATE PROCEDURE public.p_func(INT8) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -176,11 +181,13 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE public.p] ORDER BY 1 ---- CREATE PROCEDURE public.p() LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ CREATE PROCEDURE public.p(INT8) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 2; $$ @@ -207,6 +214,7 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE public.p]; ---- CREATE PROCEDURE public.p() LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -216,11 +224,13 @@ SELECT create_statement FROM [SHOW CREATE PROCEDURE sc.p] ORDER BY 1 ---- CREATE PROCEDURE sc.p() LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 3; $$ CREATE PROCEDURE sc.p(INT8) LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 2; $$ diff --git a/pkg/sql/logictest/testdata/logic_test/udf b/pkg/sql/logictest/testdata/logic_test/udf index d63fcc1ba04f..83d0350782e5 100644 --- a/pkg/sql/logictest/testdata/logic_test/udf +++ b/pkg/sql/logictest/testdata/logic_test/udf @@ -70,6 +70,7 @@ CREATE FUNCTION public.f_no_ref(a INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -103,6 +104,7 @@ CREATE FUNCTION public.f(a public.notmyworkday) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT a FROM test.public.t; SELECT b FROM test.public.t@t_idx_b; @@ -250,6 +252,7 @@ CREATE FUNCTION public.f_test_cor(a INT8, b INT8) LEAKPROOF STRICT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -268,6 +271,7 @@ CREATE FUNCTION public.f_test_cor(a INT8, b INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 2; $$ @@ -284,6 +288,7 @@ CREATE FUNCTION public.f_test_cor(a INT8, b INT8) LEAKPROOF STRICT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 3; $$ @@ -670,6 +675,7 @@ CREATE FUNCTION public.single_quote(s STRING) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT (e'\'' || s) || e'\''; $$ diff --git a/pkg/sql/logictest/testdata/logic_test/udf_options b/pkg/sql/logictest/testdata/logic_test/udf_options index 0b7bc01d1931..e62faaa1946f 100644 --- a/pkg/sql/logictest/testdata/logic_test/udf_options +++ b/pkg/sql/logictest/testdata/logic_test/udf_options @@ -36,6 +36,11 @@ CREATE FUNCTION f() RETURNS INT IMMUTABLE LANGUAGE SQL AS $$ SELECT 1 $$ AS $$ S statement error pgcode 42601 pq: LANGUAGE SQL: conflicting or redundant options CREATE FUNCTION f() RETURNS INT IMMUTABLE LANGUAGE SQL LANGUAGE SQL AS $$ SELECT 1 $$; +statement error pgcode 42601 pq: SECURITY DEFINER: conflicting or redundant options +CREATE FUNCTION f() RETURNS INT IMMUTABLE SECURITY INVOKER SECURITY DEFINER LANGUAGE SQL AS $$ SELECT 1 $$; + +statement error pgcode 42601 pq: SECURITY INVOKER: conflicting or redundant options +CREATE FUNCTION f() RETURNS INT IMMUTABLE SECURITY INVOKER EXTERNAL SECURITY INVOKER LANGUAGE SQL AS $$ SELECT 1 $$; subtest volatility @@ -67,6 +72,7 @@ CREATE FUNCTION public.get_l(i INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT v FROM test.public.kv WHERE k = i; $$ diff --git a/pkg/sql/logictest/testdata/logic_test/udf_params b/pkg/sql/logictest/testdata/logic_test/udf_params index b0175c35544d..5f87a3e4d189 100644 --- a/pkg/sql/logictest/testdata/logic_test/udf_params +++ b/pkg/sql/logictest/testdata/logic_test/udf_params @@ -98,6 +98,7 @@ CREATE FUNCTION public.f_param_types(IN p1 INT8, INOUT p2 INT8, INOUT p3 INT8, O NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT p2, p3, p1; $$ @@ -119,6 +120,7 @@ CREATE FUNCTION public.f_param_types(OUT param INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -248,6 +250,7 @@ CREATE FUNCTION public.f_out_int(OUT param_new INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -298,6 +301,7 @@ CREATE FUNCTION public.f_int(INOUT param INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT param; $$ @@ -326,6 +330,7 @@ CREATE FUNCTION public.f_int(IN param INT8, OUT param_out INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT param; $$ @@ -348,6 +353,7 @@ CREATE FUNCTION public.f_int(OUT param_out INT8, IN param INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT param; $$ @@ -370,6 +376,7 @@ CREATE FUNCTION public.f_int(INOUT param INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT param; $$ @@ -409,6 +416,7 @@ CREATE FUNCTION public.f_3_in_2_out(IN param1 INT8, OUT param1 INT8, IN param2 I NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT (param1, param2 + param3); $$ @@ -435,6 +443,7 @@ CREATE FUNCTION public.f_3_in_2_out(INOUT param1 INT8, INOUT param2 INT8, IN par NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT (param1, param2 + param3); $$ @@ -465,6 +474,7 @@ CREATE FUNCTION public.f_default_names(OUT INT8, OUT param2 INT8, IN INT8, OUT I NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT (1:::INT8, 2:::INT8, 3:::INT8); $$ @@ -523,6 +533,7 @@ CREATE FUNCTION public.f_default_names(OUT INT8, OUT param2 INT8, IN INT8, OUT c NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT (1:::INT8, 2:::INT8, 3:::INT8); $$ @@ -540,6 +551,7 @@ CREATE FUNCTION public.f_default_names(OUT INT8, OUT param2 INT8, IN INT8, OUT I NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT (1:::INT8, 2:::INT8, 3:::INT8); $$ @@ -557,6 +569,7 @@ CREATE FUNCTION public.f_default_names(OUT INT8, OUT param2 INT8, IN in_param IN NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT (in_param, 2, 3); $$ diff --git a/pkg/sql/logictest/testdata/logic_test/udf_record b/pkg/sql/logictest/testdata/logic_test/udf_record index 4922e035cdcb..9fcdc6062db6 100644 --- a/pkg/sql/logictest/testdata/logic_test/udf_record +++ b/pkg/sql/logictest/testdata/logic_test/udf_record @@ -80,6 +80,7 @@ f_table CREATE FUNCTION public.f_table() NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT t.a, t.b FROM test.public.t ORDER BY a LIMIT 1; $$ diff --git a/pkg/sql/logictest/testdata/logic_test/udf_regressions b/pkg/sql/logictest/testdata/logic_test/udf_regressions index 522a18d299f7..1be0e04eb47e 100644 --- a/pkg/sql/logictest/testdata/logic_test/udf_regressions +++ b/pkg/sql/logictest/testdata/logic_test/udf_regressions @@ -518,6 +518,7 @@ CREATE FUNCTION public.func104242() NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1 FROM test.public.tab104242 WHERE NULL IN (); $$ @@ -536,6 +537,7 @@ CREATE FUNCTION public.func104242_not_null() NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1 FROM test.public.tab104242 WHERE 'foo':::public.typ104242 IN (); $$ diff --git a/pkg/sql/logictest/testdata/logic_test/udf_schema_change b/pkg/sql/logictest/testdata/logic_test/udf_schema_change index 57d8fcc1b246..93eea0087d8f 100644 --- a/pkg/sql/logictest/testdata/logic_test/udf_schema_change +++ b/pkg/sql/logictest/testdata/logic_test/udf_schema_change @@ -16,6 +16,7 @@ CREATE FUNCTION public.f_test_alter_opt(INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -38,6 +39,7 @@ CREATE FUNCTION public.f_test_alter_opt(INT8) LEAKPROOF STRICT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -67,6 +69,7 @@ CREATE FUNCTION public.f_test_alter_name(INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -98,6 +101,7 @@ CREATE FUNCTION public.f_test_alter_name_new(INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -117,6 +121,7 @@ CREATE FUNCTION public.f_test_alter_name_diff_in() NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -126,6 +131,7 @@ CREATE FUNCTION public.f_test_alter_name_diff_in(INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -241,6 +247,7 @@ CREATE FUNCTION public.f_test_sc() NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -250,6 +257,7 @@ CREATE FUNCTION public.f_test_sc(INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 2; $$ @@ -291,6 +299,7 @@ CREATE FUNCTION public.f_test_sc() NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 1; $$ @@ -304,6 +313,7 @@ CREATE FUNCTION test_alter_sc.f_test_sc() NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 3; $$ @@ -313,6 +323,7 @@ CREATE FUNCTION test_alter_sc.f_test_sc(INT8) NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 2; $$ @@ -334,6 +345,7 @@ CREATE FUNCTION public.f_udt_rewrite() NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT 'Monday':::public.notmyworkday; $$ diff --git a/pkg/sql/logictest/testdata/logic_test/udf_star b/pkg/sql/logictest/testdata/logic_test/udf_star index 4a221891eb47..c175689640df 100644 --- a/pkg/sql/logictest/testdata/logic_test/udf_star +++ b/pkg/sql/logictest/testdata/logic_test/udf_star @@ -111,6 +111,7 @@ f_subquery CREATE FUNCTION public.f_subquery() NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT bar.a FROM (SELECT a FROM (SELECT t_onecol.a FROM test.public.t_onecol) AS foo) AS bar; $$ @@ -124,6 +125,7 @@ f_allcolsel_alias CREATE FUNCTION public.f_allcolsel_alias() NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT t1.a, t1.b FROM test.public.t_twocol AS t1, test.public.t_twocol AS t2 WHERE t1.a = t2.a; $$ diff --git a/pkg/sql/logictest/testdata/logic_test/udf_unsupported b/pkg/sql/logictest/testdata/logic_test/udf_unsupported index 91a22a20eca9..d6d52ee9c787 100644 --- a/pkg/sql/logictest/testdata/logic_test/udf_unsupported +++ b/pkg/sql/logictest/testdata/logic_test/udf_unsupported @@ -57,6 +57,7 @@ CREATE FUNCTION public.test_vf_f() NOT LEAKPROOF CALLED ON NULL INPUT LANGUAGE SQL + SECURITY INVOKER AS $$ SELECT lower('hello':::STRING); $$ diff --git a/pkg/sql/parser/sql.y b/pkg/sql/parser/sql.y index d1f79c2a21ba..c4ad7f9585ea 100644 --- a/pkg/sql/parser/sql.y +++ b/pkg/sql/parser/sql.y @@ -1725,7 +1725,7 @@ func (u *sqlSymUnion) triggerForEach() tree.TriggerForEach { %type opt_in_schemas %type target_object_type -// User defined function relevant components. +// Routine (UDF/SP) relevant components. %type opt_or_replace opt_return_table opt_return_set opt_no %type param_name routine_as %type opt_routine_param_with_default_list routine_param_with_default_list func_params func_params_list @@ -4884,6 +4884,7 @@ create_extension_stmt: // | [ NOT ] LEAKPROOF // | { CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT } // | AS 'definition' +// | { [ EXTERNAL ] SECURITY DEFINER } // } ... // %SeeAlso: WEBDOCS/create-function.html create_func_stmt: @@ -5099,19 +5100,19 @@ common_routine_opt_item: } | EXTERNAL SECURITY DEFINER { - return unimplemented(sqllex, "create function...security") + $$.val = tree.RoutineDefiner } | EXTERNAL SECURITY INVOKER { - return unimplemented(sqllex, "create function...security") + $$.val = tree.RoutineInvoker } | SECURITY DEFINER { - return unimplemented(sqllex, "create function...security") + $$.val = tree.RoutineDefiner } | SECURITY INVOKER { - return unimplemented(sqllex, "create function...security") + $$.val = tree.RoutineInvoker } | LEAKPROOF { diff --git a/pkg/sql/parser/testdata/alter_function b/pkg/sql/parser/testdata/alter_function index 29b3596306e5..5070afd94b22 100644 --- a/pkg/sql/parser/testdata/alter_function +++ b/pkg/sql/parser/testdata/alter_function @@ -70,3 +70,11 @@ ALTER FUNCTION f(INT8) NO DEPENDS ON EXTENSION postgis -- normalized! ALTER FUNCTION f(INT8) NO DEPENDS ON EXTENSION postgis -- fully parenthesized ALTER FUNCTION f(INT8) NO DEPENDS ON EXTENSION postgis -- literals removed ALTER FUNCTION _(INT8) NO DEPENDS ON EXTENSION postgis -- identifiers removed + +parse +ALTER FUNCTION f(int) EXTERNAL SECURITY DEFINER +---- +ALTER FUNCTION f(INT8) SECURITY DEFINER -- normalized! +ALTER FUNCTION f(INT8) SECURITY DEFINER -- fully parenthesized +ALTER FUNCTION f(INT8) SECURITY DEFINER -- literals removed +ALTER FUNCTION _(INT8) SECURITY DEFINER -- identifiers removed diff --git a/pkg/sql/parser/testdata/create_function b/pkg/sql/parser/testdata/create_function index c7da59a7849e..f1a92edf37ad 100644 --- a/pkg/sql/parser/testdata/create_function +++ b/pkg/sql/parser/testdata/create_function @@ -326,90 +326,6 @@ We appreciate your feedback. ---- ---- -error -CREATE OR REPLACE FUNCTION f(a int = 7) RETURNS INT EXTERNAL SECURITY DEFINER AS 'SELECT 1' LANGUAGE SQL ----- ----- -at or near "definer": syntax error: unimplemented: this syntax -DETAIL: source SQL: -CREATE OR REPLACE FUNCTION f(a int = 7) RETURNS INT EXTERNAL SECURITY DEFINER AS 'SELECT 1' LANGUAGE SQL - ^ -HINT: You have attempted to use a feature that is not yet implemented. - -Please check the public issue tracker to check whether this problem is -already tracked. If you cannot find it there, please report the error -with details by creating a new issue. - -If you would rather not post publicly, please contact us directly -using the support form. - -We appreciate your feedback. ----- ----- - -error -CREATE OR REPLACE FUNCTION f(a int = 7) RETURNS INT EXTERNAL SECURITY INVOKER AS 'SELECT 1' LANGUAGE SQL ----- ----- -at or near "invoker": syntax error: unimplemented: this syntax -DETAIL: source SQL: -CREATE OR REPLACE FUNCTION f(a int = 7) RETURNS INT EXTERNAL SECURITY INVOKER AS 'SELECT 1' LANGUAGE SQL - ^ -HINT: You have attempted to use a feature that is not yet implemented. - -Please check the public issue tracker to check whether this problem is -already tracked. If you cannot find it there, please report the error -with details by creating a new issue. - -If you would rather not post publicly, please contact us directly -using the support form. - -We appreciate your feedback. ----- ----- - -error -CREATE OR REPLACE FUNCTION f(a int = 7) RETURNS INT SECURITY DEFINER AS 'SELECT 1' LANGUAGE SQL ----- ----- -at or near "definer": syntax error: unimplemented: this syntax -DETAIL: source SQL: -CREATE OR REPLACE FUNCTION f(a int = 7) RETURNS INT SECURITY DEFINER AS 'SELECT 1' LANGUAGE SQL - ^ -HINT: You have attempted to use a feature that is not yet implemented. - -Please check the public issue tracker to check whether this problem is -already tracked. If you cannot find it there, please report the error -with details by creating a new issue. - -If you would rather not post publicly, please contact us directly -using the support form. - -We appreciate your feedback. ----- ----- - -error -CREATE OR REPLACE FUNCTION f(a int = 7) RETURNS INT SECURITY INVOKER AS 'SELECT 1' LANGUAGE SQL ----- ----- -at or near "invoker": syntax error: unimplemented: this syntax -DETAIL: source SQL: -CREATE OR REPLACE FUNCTION f(a int = 7) RETURNS INT SECURITY INVOKER AS 'SELECT 1' LANGUAGE SQL - ^ -HINT: You have attempted to use a feature that is not yet implemented. - -Please check the public issue tracker to check whether this problem is -already tracked. If you cannot find it there, please report the error -with details by creating a new issue. - -If you would rather not post publicly, please contact us directly -using the support form. - -We appreciate your feedback. ----- ----- - error CREATE OR REPLACE FUNCTION f(a int = 7) RETURNS INT ROWS 123 AS 'SELECT 1' LANGUAGE SQL ---- @@ -562,3 +478,99 @@ CREATE FUNCTION f() RETURNS TABLE 'SELECT 1' LANGUAGE SQL ^ HINT: You have attempted to use a feature that is not yet implemented. See: https://go.crdb.dev/issue-v/100226/ + +parse +CREATE OR REPLACE FUNCTION f(a int = 7) RETURNS INT EXTERNAL SECURITY DEFINER AS 'SELECT 1' LANGUAGE SQL +---- +CREATE OR REPLACE FUNCTION f(a INT8 DEFAULT 7) + RETURNS INT8 + SECURITY DEFINER + LANGUAGE SQL + AS $$SELECT 1$$ -- normalized! +CREATE OR REPLACE FUNCTION f(a INT8 DEFAULT (7)) + RETURNS INT8 + SECURITY DEFINER + LANGUAGE SQL + AS $$SELECT 1$$ -- fully parenthesized +CREATE OR REPLACE FUNCTION f(a INT8 DEFAULT _) + RETURNS INT8 + SECURITY DEFINER + LANGUAGE SQL + AS $$_$$ -- literals removed +CREATE OR REPLACE FUNCTION _(_ INT8 DEFAULT 7) + RETURNS INT8 + SECURITY DEFINER + LANGUAGE SQL + AS $$_$$ -- identifiers removed + +parse +CREATE OR REPLACE FUNCTION f(a int = 7) RETURNS INT EXTERNAL SECURITY INVOKER AS 'SELECT 1' LANGUAGE SQL +---- +CREATE OR REPLACE FUNCTION f(a INT8 DEFAULT 7) + RETURNS INT8 + SECURITY INVOKER + LANGUAGE SQL + AS $$SELECT 1$$ -- normalized! +CREATE OR REPLACE FUNCTION f(a INT8 DEFAULT (7)) + RETURNS INT8 + SECURITY INVOKER + LANGUAGE SQL + AS $$SELECT 1$$ -- fully parenthesized +CREATE OR REPLACE FUNCTION f(a INT8 DEFAULT _) + RETURNS INT8 + SECURITY INVOKER + LANGUAGE SQL + AS $$_$$ -- literals removed +CREATE OR REPLACE FUNCTION _(_ INT8 DEFAULT 7) + RETURNS INT8 + SECURITY INVOKER + LANGUAGE SQL + AS $$_$$ -- identifiers removed + +parse +CREATE OR REPLACE FUNCTION f(a int = 7) RETURNS INT SECURITY DEFINER AS 'SELECT 1' LANGUAGE SQL +---- +CREATE OR REPLACE FUNCTION f(a INT8 DEFAULT 7) + RETURNS INT8 + SECURITY DEFINER + LANGUAGE SQL + AS $$SELECT 1$$ -- normalized! +CREATE OR REPLACE FUNCTION f(a INT8 DEFAULT (7)) + RETURNS INT8 + SECURITY DEFINER + LANGUAGE SQL + AS $$SELECT 1$$ -- fully parenthesized +CREATE OR REPLACE FUNCTION f(a INT8 DEFAULT _) + RETURNS INT8 + SECURITY DEFINER + LANGUAGE SQL + AS $$_$$ -- literals removed +CREATE OR REPLACE FUNCTION _(_ INT8 DEFAULT 7) + RETURNS INT8 + SECURITY DEFINER + LANGUAGE SQL + AS $$_$$ -- identifiers removed + +parse +CREATE OR REPLACE FUNCTION f(a int = 7) RETURNS INT SECURITY INVOKER AS 'SELECT 1' LANGUAGE SQL +---- +CREATE OR REPLACE FUNCTION f(a INT8 DEFAULT 7) + RETURNS INT8 + SECURITY INVOKER + LANGUAGE SQL + AS $$SELECT 1$$ -- normalized! +CREATE OR REPLACE FUNCTION f(a INT8 DEFAULT (7)) + RETURNS INT8 + SECURITY INVOKER + LANGUAGE SQL + AS $$SELECT 1$$ -- fully parenthesized +CREATE OR REPLACE FUNCTION f(a INT8 DEFAULT _) + RETURNS INT8 + SECURITY INVOKER + LANGUAGE SQL + AS $$_$$ -- literals removed +CREATE OR REPLACE FUNCTION _(_ INT8 DEFAULT 7) + RETURNS INT8 + SECURITY INVOKER + LANGUAGE SQL + AS $$_$$ -- identifiers removed diff --git a/pkg/sql/parser/testdata/create_procedure b/pkg/sql/parser/testdata/create_procedure index 8708c8ab52a5..6f8f9b8c3672 100644 --- a/pkg/sql/parser/testdata/create_procedure +++ b/pkg/sql/parser/testdata/create_procedure @@ -113,27 +113,6 @@ We appreciate your feedback. ---- ---- -error -CREATE PROCEDURE f() EXTERNAL SECURITY DEFINER AS 'SELECT 1' LANGUAGE SQL ----- ----- -at or near "definer": syntax error: unimplemented: this syntax -DETAIL: source SQL: -CREATE PROCEDURE f() EXTERNAL SECURITY DEFINER AS 'SELECT 1' LANGUAGE SQL - ^ -HINT: You have attempted to use a feature that is not yet implemented. - -Please check the public issue tracker to check whether this problem is -already tracked. If you cannot find it there, please report the error -with details by creating a new issue. - -If you would rather not post publicly, please contact us directly -using the support form. - -We appreciate your feedback. ----- ----- - error CREATE PROCEDURE f() SET a = 123 AS 'SELECT 1' LANGUAGE SQL ---- @@ -212,3 +191,83 @@ CREATE PROCEDURE "family"() BEGIN ATOMIC START TRANSACTION; COMMIT TRANSACTION; END -- literals removed CREATE PROCEDURE _() BEGIN ATOMIC START TRANSACTION; COMMIT TRANSACTION; END -- identifiers removed + +parse +CREATE PROCEDURE f() EXTERNAL SECURITY DEFINER AS 'SELECT 1' LANGUAGE SQL +---- +CREATE PROCEDURE f() + SECURITY DEFINER + LANGUAGE SQL + AS $$SELECT 1$$ -- normalized! +CREATE PROCEDURE f() + SECURITY DEFINER + LANGUAGE SQL + AS $$SELECT 1$$ -- fully parenthesized +CREATE PROCEDURE f() + SECURITY DEFINER + LANGUAGE SQL + AS $$_$$ -- literals removed +CREATE PROCEDURE _() + SECURITY DEFINER + LANGUAGE SQL + AS $$_$$ -- identifiers removed + +parse +CREATE PROCEDURE f() EXTERNAL SECURITY INVOKER AS 'SELECT 1' LANGUAGE SQL +---- +CREATE PROCEDURE f() + SECURITY INVOKER + LANGUAGE SQL + AS $$SELECT 1$$ -- normalized! +CREATE PROCEDURE f() + SECURITY INVOKER + LANGUAGE SQL + AS $$SELECT 1$$ -- fully parenthesized +CREATE PROCEDURE f() + SECURITY INVOKER + LANGUAGE SQL + AS $$_$$ -- literals removed +CREATE PROCEDURE _() + SECURITY INVOKER + LANGUAGE SQL + AS $$_$$ -- identifiers removed + +parse +CREATE PROCEDURE f() SECURITY DEFINER AS 'SELECT 1' LANGUAGE SQL +---- +CREATE PROCEDURE f() + SECURITY DEFINER + LANGUAGE SQL + AS $$SELECT 1$$ -- normalized! +CREATE PROCEDURE f() + SECURITY DEFINER + LANGUAGE SQL + AS $$SELECT 1$$ -- fully parenthesized +CREATE PROCEDURE f() + SECURITY DEFINER + LANGUAGE SQL + AS $$_$$ -- literals removed +CREATE PROCEDURE _() + SECURITY DEFINER + LANGUAGE SQL + AS $$_$$ -- identifiers removed + +parse +CREATE PROCEDURE f() SECURITY INVOKER AS 'SELECT 1' LANGUAGE SQL +---- +CREATE PROCEDURE f() + SECURITY INVOKER + LANGUAGE SQL + AS $$SELECT 1$$ -- normalized! +CREATE PROCEDURE f() + SECURITY INVOKER + LANGUAGE SQL + AS $$SELECT 1$$ -- fully parenthesized +CREATE PROCEDURE f() + SECURITY INVOKER + LANGUAGE SQL + AS $$_$$ -- literals removed +CREATE PROCEDURE _() + SECURITY INVOKER + LANGUAGE SQL + AS $$_$$ -- identifiers removed diff --git a/pkg/sql/schemachanger/scbuild/internal/scbuildstmt/create_function.go b/pkg/sql/schemachanger/scbuild/internal/scbuildstmt/create_function.go index d8f7b70bcae1..b95ec0d072da 100644 --- a/pkg/sql/schemachanger/scbuild/internal/scbuildstmt/create_function.go +++ b/pkg/sql/schemachanger/scbuild/internal/scbuildstmt/create_function.go @@ -173,6 +173,15 @@ func CreateFunction(b BuildCtx, n *tree.CreateRoutine) { lang = v case tree.RoutineBodyStr: fnBodyStr = string(t) + case tree.RoutineSecurity: + s, err := funcinfo.SecurityToProto(t) + if err != nil { + panic(err) + } + b.Add(&scpb.FunctionSecurity{ + FunctionID: fnID, + Security: catpb.FunctionSecurity{Security: s}, + }) } } owner, ups := b.BuildUserPrivilegesFromDefaultPrivileges( diff --git a/pkg/sql/schemachanger/scbuild/testdata/drop_function b/pkg/sql/schemachanger/scbuild/testdata/drop_function index a5d6636571c1..aee177439d71 100644 --- a/pkg/sql/schemachanger/scbuild/testdata/drop_function +++ b/pkg/sql/schemachanger/scbuild/testdata/drop_function @@ -41,5 +41,7 @@ DROP FUNCTION f; {functionId: 109} - [[FunctionNullInputBehavior:{DescID: 109}, ABSENT], PUBLIC] {functionId: 109, nullInputBehavior: {nullInputBehavior: CALLED_ON_NULL_INPUT}} +- [[FunctionSecurity:{DescID: 109}, ABSENT], PUBLIC] + {functionId: 109, security: {}} - [[FunctionBody:{DescID: 109}, ABSENT], PUBLIC] {body: "SELECT a FROM defaultdb.public.t;\nSELECT b FROM defaultdb.public.t@t_idx_b;\nSELECT c FROM defaultdb.public.t@t_idx_c;\nSELECT a FROM defaultdb.public.v;\nSELECT nextval(105:::REGCLASS);", functionId: 109, lang: {lang: SQL}, usesSequenceIds: [105], usesTables: [{columnIds: [1], tableId: 104}, {columnIds: [2], indexId: 2, tableId: 104}, {columnIds: [3], indexId: 3, tableId: 104}], usesTypeIds: [107, 108], usesViews: [{columnIds: [1], viewId: 106}]} diff --git a/pkg/sql/schemachanger/scdecomp/decomp.go b/pkg/sql/schemachanger/scdecomp/decomp.go index 78ea28ba5577..07279e776486 100644 --- a/pkg/sql/schemachanger/scdecomp/decomp.go +++ b/pkg/sql/schemachanger/scdecomp/decomp.go @@ -873,6 +873,10 @@ func (w *walkCtx) walkFunction(fnDesc catalog.FunctionDescriptor) { FunctionID: fnDesc.GetID(), NullInputBehavior: catpb.FunctionNullInputBehavior{NullInputBehavior: fnDesc.GetNullInputBehavior()}, }) + w.ev(scpb.Status_PUBLIC, &scpb.FunctionSecurity{ + FunctionID: fnDesc.GetID(), + Security: catpb.FunctionSecurity{Security: fnDesc.GetSecurity()}, + }) fnBody := &scpb.FunctionBody{ FunctionID: fnDesc.GetID(), diff --git a/pkg/sql/schemachanger/scdecomp/testdata/function b/pkg/sql/schemachanger/scdecomp/testdata/function index 3fe51f52d59b..d0fc168413c0 100644 --- a/pkg/sql/schemachanger/scdecomp/testdata/function +++ b/pkg/sql/schemachanger/scdecomp/testdata/function @@ -122,6 +122,11 @@ ElementState: nullInputBehavior: nullInputBehavior: CALLED_ON_NULL_INPUT Status: PUBLIC +- FunctionSecurity: + functionId: 110 + security: + security: INVOKER + Status: PUBLIC - FunctionVolatility: functionId: 110 volatility: diff --git a/pkg/sql/schemachanger/scexec/scmutationexec/function.go b/pkg/sql/schemachanger/scexec/scmutationexec/function.go index 1256eeec65f8..d258a9befeda 100644 --- a/pkg/sql/schemachanger/scexec/scmutationexec/function.go +++ b/pkg/sql/schemachanger/scexec/scmutationexec/function.go @@ -103,3 +103,14 @@ func (i *immediateVisitor) SetFunctionBody(ctx context.Context, op scop.SetFunct return nil } + +func (i *immediateVisitor) SetFunctionSecurity( + ctx context.Context, op scop.SetFunctionSecurity, +) error { + fn, err := i.checkOutFunction(ctx, op.FunctionID) + if err != nil { + return err + } + fn.SetSecurity(op.Security) + return nil +} diff --git a/pkg/sql/schemachanger/scop/immediate_mutation.go b/pkg/sql/schemachanger/scop/immediate_mutation.go index 9b3afa7e06f7..511692236295 100644 --- a/pkg/sql/schemachanger/scop/immediate_mutation.go +++ b/pkg/sql/schemachanger/scop/immediate_mutation.go @@ -839,6 +839,12 @@ type SetFunctionBody struct { Body scpb.FunctionBody } +type SetFunctionSecurity struct { + immediateMutationOp + FunctionID descpb.ID + Security catpb.Function_Security +} + type UpdateFunctionTypeReferences struct { immediateMutationOp FunctionID descpb.ID diff --git a/pkg/sql/schemachanger/scop/immediate_mutation_visitor_generated.go b/pkg/sql/schemachanger/scop/immediate_mutation_visitor_generated.go index ad316fcb6666..c3e845e2795b 100644 --- a/pkg/sql/schemachanger/scop/immediate_mutation_visitor_generated.go +++ b/pkg/sql/schemachanger/scop/immediate_mutation_visitor_generated.go @@ -126,6 +126,7 @@ type ImmediateMutationVisitor interface { SetFunctionLeakProof(context.Context, SetFunctionLeakProof) error SetFunctionNullInputBehavior(context.Context, SetFunctionNullInputBehavior) error SetFunctionBody(context.Context, SetFunctionBody) error + SetFunctionSecurity(context.Context, SetFunctionSecurity) error UpdateFunctionTypeReferences(context.Context, UpdateFunctionTypeReferences) error UpdateFunctionRelationReferences(context.Context, UpdateFunctionRelationReferences) error SetObjectParentID(context.Context, SetObjectParentID) error @@ -660,6 +661,11 @@ func (op SetFunctionBody) Visit(ctx context.Context, v ImmediateMutationVisitor) return v.SetFunctionBody(ctx, op) } +// Visit is part of the ImmediateMutationOp interface. +func (op SetFunctionSecurity) Visit(ctx context.Context, v ImmediateMutationVisitor) error { + return v.SetFunctionSecurity(ctx, op) +} + // Visit is part of the ImmediateMutationOp interface. func (op UpdateFunctionTypeReferences) Visit(ctx context.Context, v ImmediateMutationVisitor) error { return v.UpdateFunctionTypeReferences(ctx, op) diff --git a/pkg/sql/schemachanger/scpb/elements.proto b/pkg/sql/schemachanger/scpb/elements.proto index 3723caa7c8f9..24c511ad9d1d 100644 --- a/pkg/sql/schemachanger/scpb/elements.proto +++ b/pkg/sql/schemachanger/scpb/elements.proto @@ -148,6 +148,7 @@ message ElementProto { FunctionLeakProof function_leak_proof = 162 [(gogoproto.moretags) = "parent:\"Function\""]; FunctionNullInputBehavior function_null_input_behavior = 163 [(gogoproto.moretags) = "parent:\"Function\""]; FunctionBody function_body = 164 [(gogoproto.moretags) = "parent:\"Function\""]; + FunctionSecurity function_security = 165 [(gogoproto.moretags) = "parent:\"Function\""]; // Type elements. TypeComment type_comment = 180 [(gogoproto.moretags) = "parent:\"CompositeType,EnumType\""]; @@ -769,6 +770,11 @@ message FunctionBody { repeated uint32 uses_function_ids = 8 [(gogoproto.customname) = "UsesFunctionIDs", (gogoproto.casttype) = "github.com/cockroachdb/cockroach/pkg/sql/sem/catid.DescID"]; } +message FunctionSecurity { + uint32 function_id = 1 [(gogoproto.customname) = "FunctionID", (gogoproto.casttype) = "github.com/cockroachdb/cockroach/pkg/sql/sem/catid.DescID"]; + cockroach.sql.catalog.catpb.FunctionSecurity security = 2 [(gogoproto.nullable) = false]; +} + message ElementCreationMetadata { bool in_23_1_or_later = 1; bool in_24_3_or_later = 2; diff --git a/pkg/sql/schemachanger/scpb/elements_generated.go b/pkg/sql/schemachanger/scpb/elements_generated.go index c03c214f8b07..429cefe7c871 100644 --- a/pkg/sql/schemachanger/scpb/elements_generated.go +++ b/pkg/sql/schemachanger/scpb/elements_generated.go @@ -1199,6 +1199,43 @@ func (c *ElementCollection[E]) FilterFunctionNullInputBehavior() *ElementCollect return (*ElementCollection[*FunctionNullInputBehavior])(ret) } +func (e FunctionSecurity) element() {} + +// Element implements ElementGetter. +func (e * ElementProto_FunctionSecurity) Element() Element { + return e.FunctionSecurity +} + +// ForEachFunctionSecurity iterates over elements of type FunctionSecurity. +// Deprecated +func ForEachFunctionSecurity( + c *ElementCollection[Element], fn func(current Status, target TargetStatus, e *FunctionSecurity), +) { + c.FilterFunctionSecurity().ForEach(fn) +} + +// FindFunctionSecurity finds the first element of type FunctionSecurity. +// Deprecated +func FindFunctionSecurity( + c *ElementCollection[Element], +) (current Status, target TargetStatus, element *FunctionSecurity) { + if tc := c.FilterFunctionSecurity(); !tc.IsEmpty() { + var e Element + current, target, e = tc.Get(0) + element = e.(*FunctionSecurity) + } + return current, target, element +} + +// FunctionSecurityElements filters elements of type FunctionSecurity. +func (c *ElementCollection[E]) FilterFunctionSecurity() *ElementCollection[*FunctionSecurity] { + ret := c.genericFilter(func(_ Status, _ TargetStatus, e Element) bool { + _, ok := e.(*FunctionSecurity) + return ok + }) + return (*ElementCollection[*FunctionSecurity])(ret) +} + func (e FunctionVolatility) element() {} // Element implements ElementGetter. @@ -2600,6 +2637,8 @@ func (e* ElementProto) SetElement(element Element) { e.ElementOneOf = &ElementProto_FunctionName{ FunctionName: t} case *FunctionNullInputBehavior: e.ElementOneOf = &ElementProto_FunctionNullInputBehavior{ FunctionNullInputBehavior: t} + case *FunctionSecurity: + e.ElementOneOf = &ElementProto_FunctionSecurity{ FunctionSecurity: t} case *FunctionVolatility: e.ElementOneOf = &ElementProto_FunctionVolatility{ FunctionVolatility: t} case *IndexColumn: @@ -2710,6 +2749,7 @@ func GetElementOneOfProtos() []interface{} { ((*ElementProto_FunctionLeakProof)(nil)), ((*ElementProto_FunctionName)(nil)), ((*ElementProto_FunctionNullInputBehavior)(nil)), + ((*ElementProto_FunctionSecurity)(nil)), ((*ElementProto_FunctionVolatility)(nil)), ((*ElementProto_IndexColumn)(nil)), ((*ElementProto_IndexComment)(nil)), @@ -2785,6 +2825,7 @@ func GetElementTypes() []interface{} { ((*FunctionLeakProof)(nil)), ((*FunctionName)(nil)), ((*FunctionNullInputBehavior)(nil)), + ((*FunctionSecurity)(nil)), ((*FunctionVolatility)(nil)), ((*IndexColumn)(nil)), ((*IndexComment)(nil)), diff --git a/pkg/sql/schemachanger/scpb/uml/table.puml b/pkg/sql/schemachanger/scpb/uml/table.puml index 7ebf1f226d63..23dc4ef9c83e 100644 --- a/pkg/sql/schemachanger/scpb/uml/table.puml +++ b/pkg/sql/schemachanger/scpb/uml/table.puml @@ -210,6 +210,11 @@ object FunctionNullInputBehavior FunctionNullInputBehavior : FunctionID FunctionNullInputBehavior : NullInputBehavior +object FunctionSecurity + +FunctionSecurity : FunctionID +FunctionSecurity : Security + object FunctionVolatility FunctionVolatility : FunctionID @@ -454,6 +459,7 @@ Function <|-- FunctionBody Function <|-- FunctionLeakProof Function <|-- FunctionName Function <|-- FunctionNullInputBehavior +Function <|-- FunctionSecurity Function <|-- FunctionVolatility PrimaryIndex <|-- IndexColumn SecondaryIndex <|-- IndexColumn diff --git a/pkg/sql/schemachanger/scplan/internal/opgen/BUILD.bazel b/pkg/sql/schemachanger/scplan/internal/opgen/BUILD.bazel index 38de72dcb739..b2f9b3f89502 100644 --- a/pkg/sql/schemachanger/scplan/internal/opgen/BUILD.bazel +++ b/pkg/sql/schemachanger/scplan/internal/opgen/BUILD.bazel @@ -37,6 +37,7 @@ go_library( "opgen_function_leakproof.go", "opgen_function_name.go", "opgen_function_null_input.go", + "opgen_function_security.go", "opgen_function_volatility.go", "opgen_index_column.go", "opgen_index_comment.go", diff --git a/pkg/sql/schemachanger/scplan/internal/opgen/opgen_function_security.go b/pkg/sql/schemachanger/scplan/internal/opgen/opgen_function_security.go new file mode 100644 index 000000000000..af8ad48d8ba0 --- /dev/null +++ b/pkg/sql/schemachanger/scplan/internal/opgen/opgen_function_security.go @@ -0,0 +1,40 @@ +// Copyright 2024 The Cockroach Authors. +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package opgen + +import ( + "github.com/cockroachdb/cockroach/pkg/sql/schemachanger/scop" + "github.com/cockroachdb/cockroach/pkg/sql/schemachanger/scpb" +) + +func init() { + opRegistry.register((*scpb.FunctionSecurity)(nil), + toPublic( + scpb.Status_ABSENT, + to(scpb.Status_PUBLIC, + emit(func(this *scpb.FunctionSecurity) *scop.SetFunctionSecurity { + return &scop.SetFunctionSecurity{ + FunctionID: this.FunctionID, + Security: this.Security.Security, + } + }), + ), + ), + toAbsent( + scpb.Status_PUBLIC, + to(scpb.Status_ABSENT, + emit(func(this *scpb.FunctionSecurity) *scop.NotImplementedForPublicObjects { + return notImplementedForPublicObjects(this) + }), + ), + ), + ) +} diff --git a/pkg/sql/schemachanger/scplan/internal/rules/current/testdata/deprules b/pkg/sql/schemachanger/scplan/internal/rules/current/testdata/deprules index 30f6d978074c..aded0a480298 100644 --- a/pkg/sql/schemachanger/scplan/internal/rules/current/testdata/deprules +++ b/pkg/sql/schemachanger/scplan/internal/rules/current/testdata/deprules @@ -2891,7 +2891,7 @@ deprules kind: Precedence to: relation-Node query: - - $dependent[Type] IN ['*scpb.CheckConstraint', '*scpb.CheckConstraintUnvalidated', '*scpb.Column', '*scpb.ColumnComment', '*scpb.ColumnComputeExpression', '*scpb.ColumnDefaultExpression', '*scpb.ColumnFamily', '*scpb.ColumnName', '*scpb.ColumnNotNull', '*scpb.ColumnOnUpdateExpression', '*scpb.ColumnType', '*scpb.CompositeTypeAttrName', '*scpb.CompositeTypeAttrType', '*scpb.ConstraintComment', '*scpb.ConstraintWithoutIndexName', '*scpb.DatabaseComment', '*scpb.DatabaseRegionConfig', '*scpb.DatabaseRoleSetting', '*scpb.DatabaseZoneConfig', '*scpb.EnumTypeValue', '*scpb.ForeignKeyConstraint', '*scpb.ForeignKeyConstraintUnvalidated', '*scpb.FunctionBody', '*scpb.FunctionLeakProof', '*scpb.FunctionName', '*scpb.FunctionNullInputBehavior', '*scpb.FunctionVolatility', '*scpb.IndexColumn', '*scpb.IndexComment', '*scpb.IndexName', '*scpb.IndexPartitioning', '*scpb.IndexZoneConfig', '*scpb.Namespace', '*scpb.Owner', '*scpb.PrimaryIndex', '*scpb.RowLevelTTL', '*scpb.SchemaChild', '*scpb.SchemaComment', '*scpb.SchemaParent', '*scpb.SecondaryIndex', '*scpb.SecondaryIndexPartial', '*scpb.SequenceOption', '*scpb.SequenceOwner', '*scpb.TableComment', '*scpb.TableLocalityGlobal', '*scpb.TableLocalityPrimaryRegion', '*scpb.TableLocalityRegionalByRow', '*scpb.TableLocalitySecondaryRegion', '*scpb.TablePartitioning', '*scpb.TableSchemaLocked', '*scpb.TableZoneConfig', '*scpb.TemporaryIndex', '*scpb.TypeComment', '*scpb.UniqueWithoutIndexConstraint', '*scpb.UniqueWithoutIndexConstraintUnvalidated', '*scpb.UserPrivileges'] + - $dependent[Type] IN ['*scpb.CheckConstraint', '*scpb.CheckConstraintUnvalidated', '*scpb.Column', '*scpb.ColumnComment', '*scpb.ColumnComputeExpression', '*scpb.ColumnDefaultExpression', '*scpb.ColumnFamily', '*scpb.ColumnName', '*scpb.ColumnNotNull', '*scpb.ColumnOnUpdateExpression', '*scpb.ColumnType', '*scpb.CompositeTypeAttrName', '*scpb.CompositeTypeAttrType', '*scpb.ConstraintComment', '*scpb.ConstraintWithoutIndexName', '*scpb.DatabaseComment', '*scpb.DatabaseRegionConfig', '*scpb.DatabaseRoleSetting', '*scpb.DatabaseZoneConfig', '*scpb.EnumTypeValue', '*scpb.ForeignKeyConstraint', '*scpb.ForeignKeyConstraintUnvalidated', '*scpb.FunctionBody', '*scpb.FunctionLeakProof', '*scpb.FunctionName', '*scpb.FunctionNullInputBehavior', '*scpb.FunctionSecurity', '*scpb.FunctionVolatility', '*scpb.IndexColumn', '*scpb.IndexComment', '*scpb.IndexName', '*scpb.IndexPartitioning', '*scpb.IndexZoneConfig', '*scpb.Namespace', '*scpb.Owner', '*scpb.PrimaryIndex', '*scpb.RowLevelTTL', '*scpb.SchemaChild', '*scpb.SchemaComment', '*scpb.SchemaParent', '*scpb.SecondaryIndex', '*scpb.SecondaryIndexPartial', '*scpb.SequenceOption', '*scpb.SequenceOwner', '*scpb.TableComment', '*scpb.TableLocalityGlobal', '*scpb.TableLocalityPrimaryRegion', '*scpb.TableLocalityRegionalByRow', '*scpb.TableLocalitySecondaryRegion', '*scpb.TablePartitioning', '*scpb.TableSchemaLocked', '*scpb.TableZoneConfig', '*scpb.TemporaryIndex', '*scpb.TypeComment', '*scpb.UniqueWithoutIndexConstraint', '*scpb.UniqueWithoutIndexConstraintUnvalidated', '*scpb.UserPrivileges'] - $relation[Type] IN ['*scpb.AliasType', '*scpb.CompositeType', '*scpb.Database', '*scpb.EnumType', '*scpb.Function', '*scpb.Schema', '*scpb.Sequence', '*scpb.Table', '*scpb.View'] - joinOnDescID($dependent, $relation, $relation-id) - ToPublicOrTransient($dependent-Target, $relation-Target) @@ -3135,7 +3135,7 @@ deprules to: referencing-via-attr-Node query: - $referenced-descriptor[Type] IN ['*scpb.AliasType', '*scpb.CompositeType', '*scpb.Database', '*scpb.EnumType', '*scpb.Function', '*scpb.Schema', '*scpb.Sequence', '*scpb.Table', '*scpb.View'] - - $referencing-via-attr[Type] IN ['*scpb.CheckConstraintUnvalidated', '*scpb.ColumnComment', '*scpb.ColumnComputeExpression', '*scpb.ColumnDefaultExpression', '*scpb.ColumnFamily', '*scpb.ColumnName', '*scpb.ColumnOnUpdateExpression', '*scpb.ColumnType', '*scpb.CompositeTypeAttrName', '*scpb.CompositeTypeAttrType', '*scpb.ConstraintComment', '*scpb.ConstraintWithoutIndexName', '*scpb.DatabaseComment', '*scpb.DatabaseRegionConfig', '*scpb.DatabaseRoleSetting', '*scpb.DatabaseZoneConfig', '*scpb.EnumTypeValue', '*scpb.ForeignKeyConstraintUnvalidated', '*scpb.FunctionBody', '*scpb.FunctionLeakProof', '*scpb.FunctionName', '*scpb.FunctionNullInputBehavior', '*scpb.FunctionVolatility', '*scpb.IndexColumn', '*scpb.IndexComment', '*scpb.IndexName', '*scpb.IndexPartitioning', '*scpb.IndexZoneConfig', '*scpb.Namespace', '*scpb.Owner', '*scpb.RowLevelTTL', '*scpb.SchemaComment', '*scpb.SecondaryIndexPartial', '*scpb.SequenceOption', '*scpb.SequenceOwner', '*scpb.TableComment', '*scpb.TableLocalityGlobal', '*scpb.TableLocalityPrimaryRegion', '*scpb.TableLocalityRegionalByRow', '*scpb.TableLocalitySecondaryRegion', '*scpb.TablePartitioning', '*scpb.TableSchemaLocked', '*scpb.TableZoneConfig', '*scpb.TypeComment', '*scpb.UniqueWithoutIndexConstraintUnvalidated', '*scpb.UserPrivileges'] + - $referencing-via-attr[Type] IN ['*scpb.CheckConstraintUnvalidated', '*scpb.ColumnComment', '*scpb.ColumnComputeExpression', '*scpb.ColumnDefaultExpression', '*scpb.ColumnFamily', '*scpb.ColumnName', '*scpb.ColumnOnUpdateExpression', '*scpb.ColumnType', '*scpb.CompositeTypeAttrName', '*scpb.CompositeTypeAttrType', '*scpb.ConstraintComment', '*scpb.ConstraintWithoutIndexName', '*scpb.DatabaseComment', '*scpb.DatabaseRegionConfig', '*scpb.DatabaseRoleSetting', '*scpb.DatabaseZoneConfig', '*scpb.EnumTypeValue', '*scpb.ForeignKeyConstraintUnvalidated', '*scpb.FunctionBody', '*scpb.FunctionLeakProof', '*scpb.FunctionName', '*scpb.FunctionNullInputBehavior', '*scpb.FunctionSecurity', '*scpb.FunctionVolatility', '*scpb.IndexColumn', '*scpb.IndexComment', '*scpb.IndexName', '*scpb.IndexPartitioning', '*scpb.IndexZoneConfig', '*scpb.Namespace', '*scpb.Owner', '*scpb.RowLevelTTL', '*scpb.SchemaComment', '*scpb.SecondaryIndexPartial', '*scpb.SequenceOption', '*scpb.SequenceOwner', '*scpb.TableComment', '*scpb.TableLocalityGlobal', '*scpb.TableLocalityPrimaryRegion', '*scpb.TableLocalityRegionalByRow', '*scpb.TableLocalitySecondaryRegion', '*scpb.TablePartitioning', '*scpb.TableSchemaLocked', '*scpb.TableZoneConfig', '*scpb.TypeComment', '*scpb.UniqueWithoutIndexConstraintUnvalidated', '*scpb.UserPrivileges'] - joinReferencedDescID($referencing-via-attr, $referenced-descriptor, $desc-id) - toAbsent($referenced-descriptor-Target, $referencing-via-attr-Target) - $referenced-descriptor-Node[CurrentStatus] = DROPPED @@ -3191,7 +3191,7 @@ deprules to: dependent-Node query: - $descriptor[Type] IN ['*scpb.AliasType', '*scpb.CompositeType', '*scpb.Database', '*scpb.EnumType', '*scpb.Function', '*scpb.Schema', '*scpb.Sequence', '*scpb.Table', '*scpb.View'] - - $dependent[Type] IN ['*scpb.CheckConstraintUnvalidated', '*scpb.ColumnComment', '*scpb.ColumnComputeExpression', '*scpb.ColumnDefaultExpression', '*scpb.ColumnFamily', '*scpb.ColumnName', '*scpb.ColumnOnUpdateExpression', '*scpb.ColumnType', '*scpb.CompositeTypeAttrName', '*scpb.CompositeTypeAttrType', '*scpb.DatabaseComment', '*scpb.DatabaseRegionConfig', '*scpb.DatabaseRoleSetting', '*scpb.DatabaseZoneConfig', '*scpb.EnumTypeValue', '*scpb.ForeignKeyConstraintUnvalidated', '*scpb.FunctionBody', '*scpb.FunctionLeakProof', '*scpb.FunctionName', '*scpb.FunctionNullInputBehavior', '*scpb.FunctionVolatility', '*scpb.IndexColumn', '*scpb.IndexComment', '*scpb.IndexName', '*scpb.IndexPartitioning', '*scpb.IndexZoneConfig', '*scpb.Namespace', '*scpb.Owner', '*scpb.RowLevelTTL', '*scpb.SchemaChild', '*scpb.SchemaComment', '*scpb.SchemaParent', '*scpb.SecondaryIndexPartial', '*scpb.SequenceOption', '*scpb.SequenceOwner', '*scpb.TableComment', '*scpb.TableLocalityGlobal', '*scpb.TableLocalityPrimaryRegion', '*scpb.TableLocalityRegionalByRow', '*scpb.TableLocalitySecondaryRegion', '*scpb.TablePartitioning', '*scpb.TableSchemaLocked', '*scpb.TableZoneConfig', '*scpb.TypeComment', '*scpb.UniqueWithoutIndexConstraintUnvalidated', '*scpb.UserPrivileges'] + - $dependent[Type] IN ['*scpb.CheckConstraintUnvalidated', '*scpb.ColumnComment', '*scpb.ColumnComputeExpression', '*scpb.ColumnDefaultExpression', '*scpb.ColumnFamily', '*scpb.ColumnName', '*scpb.ColumnOnUpdateExpression', '*scpb.ColumnType', '*scpb.CompositeTypeAttrName', '*scpb.CompositeTypeAttrType', '*scpb.DatabaseComment', '*scpb.DatabaseRegionConfig', '*scpb.DatabaseRoleSetting', '*scpb.DatabaseZoneConfig', '*scpb.EnumTypeValue', '*scpb.ForeignKeyConstraintUnvalidated', '*scpb.FunctionBody', '*scpb.FunctionLeakProof', '*scpb.FunctionName', '*scpb.FunctionNullInputBehavior', '*scpb.FunctionSecurity', '*scpb.FunctionVolatility', '*scpb.IndexColumn', '*scpb.IndexComment', '*scpb.IndexName', '*scpb.IndexPartitioning', '*scpb.IndexZoneConfig', '*scpb.Namespace', '*scpb.Owner', '*scpb.RowLevelTTL', '*scpb.SchemaChild', '*scpb.SchemaComment', '*scpb.SchemaParent', '*scpb.SecondaryIndexPartial', '*scpb.SequenceOption', '*scpb.SequenceOwner', '*scpb.TableComment', '*scpb.TableLocalityGlobal', '*scpb.TableLocalityPrimaryRegion', '*scpb.TableLocalityRegionalByRow', '*scpb.TableLocalitySecondaryRegion', '*scpb.TablePartitioning', '*scpb.TableSchemaLocked', '*scpb.TableZoneConfig', '*scpb.TypeComment', '*scpb.UniqueWithoutIndexConstraintUnvalidated', '*scpb.UserPrivileges'] - joinOnDescID($descriptor, $dependent, $desc-id) - toAbsent($descriptor-Target, $dependent-Target) - $descriptor-Node[CurrentStatus] = DROPPED @@ -3230,7 +3230,7 @@ deprules to: dependent-Node query: - $relation[Type] IN ['*scpb.AliasType', '*scpb.CompositeType', '*scpb.Database', '*scpb.EnumType', '*scpb.Function', '*scpb.Schema', '*scpb.Sequence', '*scpb.Table', '*scpb.View'] - - $dependent[Type] IN ['*scpb.CheckConstraint', '*scpb.CheckConstraintUnvalidated', '*scpb.Column', '*scpb.ColumnComment', '*scpb.ColumnComputeExpression', '*scpb.ColumnDefaultExpression', '*scpb.ColumnFamily', '*scpb.ColumnName', '*scpb.ColumnNotNull', '*scpb.ColumnOnUpdateExpression', '*scpb.ColumnType', '*scpb.CompositeTypeAttrName', '*scpb.CompositeTypeAttrType', '*scpb.ConstraintComment', '*scpb.ConstraintWithoutIndexName', '*scpb.DatabaseComment', '*scpb.DatabaseData', '*scpb.DatabaseRegionConfig', '*scpb.DatabaseRoleSetting', '*scpb.DatabaseZoneConfig', '*scpb.EnumTypeValue', '*scpb.ForeignKeyConstraint', '*scpb.ForeignKeyConstraintUnvalidated', '*scpb.FunctionBody', '*scpb.FunctionLeakProof', '*scpb.FunctionName', '*scpb.FunctionNullInputBehavior', '*scpb.FunctionVolatility', '*scpb.IndexColumn', '*scpb.IndexComment', '*scpb.IndexData', '*scpb.IndexName', '*scpb.IndexPartitioning', '*scpb.IndexZoneConfig', '*scpb.Namespace', '*scpb.Owner', '*scpb.PrimaryIndex', '*scpb.RowLevelTTL', '*scpb.SchemaChild', '*scpb.SchemaComment', '*scpb.SchemaParent', '*scpb.SecondaryIndex', '*scpb.SecondaryIndexPartial', '*scpb.SequenceOption', '*scpb.SequenceOwner', '*scpb.TableComment', '*scpb.TableData', '*scpb.TableLocalityGlobal', '*scpb.TableLocalityPrimaryRegion', '*scpb.TableLocalityRegionalByRow', '*scpb.TableLocalitySecondaryRegion', '*scpb.TablePartitioning', '*scpb.TableSchemaLocked', '*scpb.TableZoneConfig', '*scpb.TemporaryIndex', '*scpb.TypeComment', '*scpb.UniqueWithoutIndexConstraint', '*scpb.UniqueWithoutIndexConstraintUnvalidated', '*scpb.UserPrivileges'] + - $dependent[Type] IN ['*scpb.CheckConstraint', '*scpb.CheckConstraintUnvalidated', '*scpb.Column', '*scpb.ColumnComment', '*scpb.ColumnComputeExpression', '*scpb.ColumnDefaultExpression', '*scpb.ColumnFamily', '*scpb.ColumnName', '*scpb.ColumnNotNull', '*scpb.ColumnOnUpdateExpression', '*scpb.ColumnType', '*scpb.CompositeTypeAttrName', '*scpb.CompositeTypeAttrType', '*scpb.ConstraintComment', '*scpb.ConstraintWithoutIndexName', '*scpb.DatabaseComment', '*scpb.DatabaseData', '*scpb.DatabaseRegionConfig', '*scpb.DatabaseRoleSetting', '*scpb.DatabaseZoneConfig', '*scpb.EnumTypeValue', '*scpb.ForeignKeyConstraint', '*scpb.ForeignKeyConstraintUnvalidated', '*scpb.FunctionBody', '*scpb.FunctionLeakProof', '*scpb.FunctionName', '*scpb.FunctionNullInputBehavior', '*scpb.FunctionSecurity', '*scpb.FunctionVolatility', '*scpb.IndexColumn', '*scpb.IndexComment', '*scpb.IndexData', '*scpb.IndexName', '*scpb.IndexPartitioning', '*scpb.IndexZoneConfig', '*scpb.Namespace', '*scpb.Owner', '*scpb.PrimaryIndex', '*scpb.RowLevelTTL', '*scpb.SchemaChild', '*scpb.SchemaComment', '*scpb.SchemaParent', '*scpb.SecondaryIndex', '*scpb.SecondaryIndexPartial', '*scpb.SequenceOption', '*scpb.SequenceOwner', '*scpb.TableComment', '*scpb.TableData', '*scpb.TableLocalityGlobal', '*scpb.TableLocalityPrimaryRegion', '*scpb.TableLocalityRegionalByRow', '*scpb.TableLocalitySecondaryRegion', '*scpb.TablePartitioning', '*scpb.TableSchemaLocked', '*scpb.TableZoneConfig', '*scpb.TemporaryIndex', '*scpb.TypeComment', '*scpb.UniqueWithoutIndexConstraint', '*scpb.UniqueWithoutIndexConstraintUnvalidated', '*scpb.UserPrivileges'] - joinOnDescID($relation, $dependent, $relation-id) - ToPublicOrTransient($relation-Target, $dependent-Target) - $relation-Node[CurrentStatus] = DESCRIPTOR_ADDED @@ -3671,7 +3671,7 @@ deprules kind: Precedence to: descriptor-Node query: - - $dependent[Type] IN ['*scpb.CheckConstraint', '*scpb.CheckConstraintUnvalidated', '*scpb.Column', '*scpb.ColumnComment', '*scpb.ColumnComputeExpression', '*scpb.ColumnDefaultExpression', '*scpb.ColumnFamily', '*scpb.ColumnName', '*scpb.ColumnNotNull', '*scpb.ColumnOnUpdateExpression', '*scpb.ColumnType', '*scpb.CompositeTypeAttrName', '*scpb.CompositeTypeAttrType', '*scpb.ConstraintComment', '*scpb.ConstraintWithoutIndexName', '*scpb.DatabaseComment', '*scpb.DatabaseRegionConfig', '*scpb.DatabaseRoleSetting', '*scpb.DatabaseZoneConfig', '*scpb.EnumTypeValue', '*scpb.ForeignKeyConstraint', '*scpb.ForeignKeyConstraintUnvalidated', '*scpb.FunctionBody', '*scpb.FunctionLeakProof', '*scpb.FunctionName', '*scpb.FunctionNullInputBehavior', '*scpb.FunctionVolatility', '*scpb.IndexColumn', '*scpb.IndexComment', '*scpb.IndexName', '*scpb.IndexPartitioning', '*scpb.IndexZoneConfig', '*scpb.Namespace', '*scpb.Owner', '*scpb.PrimaryIndex', '*scpb.RowLevelTTL', '*scpb.SchemaChild', '*scpb.SchemaComment', '*scpb.SchemaParent', '*scpb.SecondaryIndex', '*scpb.SecondaryIndexPartial', '*scpb.SequenceOption', '*scpb.SequenceOwner', '*scpb.TableComment', '*scpb.TableLocalityGlobal', '*scpb.TableLocalityPrimaryRegion', '*scpb.TableLocalityRegionalByRow', '*scpb.TableLocalitySecondaryRegion', '*scpb.TablePartitioning', '*scpb.TableSchemaLocked', '*scpb.TableZoneConfig', '*scpb.TemporaryIndex', '*scpb.TypeComment', '*scpb.UniqueWithoutIndexConstraint', '*scpb.UniqueWithoutIndexConstraintUnvalidated', '*scpb.UserPrivileges'] + - $dependent[Type] IN ['*scpb.CheckConstraint', '*scpb.CheckConstraintUnvalidated', '*scpb.Column', '*scpb.ColumnComment', '*scpb.ColumnComputeExpression', '*scpb.ColumnDefaultExpression', '*scpb.ColumnFamily', '*scpb.ColumnName', '*scpb.ColumnNotNull', '*scpb.ColumnOnUpdateExpression', '*scpb.ColumnType', '*scpb.CompositeTypeAttrName', '*scpb.CompositeTypeAttrType', '*scpb.ConstraintComment', '*scpb.ConstraintWithoutIndexName', '*scpb.DatabaseComment', '*scpb.DatabaseRegionConfig', '*scpb.DatabaseRoleSetting', '*scpb.DatabaseZoneConfig', '*scpb.EnumTypeValue', '*scpb.ForeignKeyConstraint', '*scpb.ForeignKeyConstraintUnvalidated', '*scpb.FunctionBody', '*scpb.FunctionLeakProof', '*scpb.FunctionName', '*scpb.FunctionNullInputBehavior', '*scpb.FunctionSecurity', '*scpb.FunctionVolatility', '*scpb.IndexColumn', '*scpb.IndexComment', '*scpb.IndexName', '*scpb.IndexPartitioning', '*scpb.IndexZoneConfig', '*scpb.Namespace', '*scpb.Owner', '*scpb.PrimaryIndex', '*scpb.RowLevelTTL', '*scpb.SchemaChild', '*scpb.SchemaComment', '*scpb.SchemaParent', '*scpb.SecondaryIndex', '*scpb.SecondaryIndexPartial', '*scpb.SequenceOption', '*scpb.SequenceOwner', '*scpb.TableComment', '*scpb.TableLocalityGlobal', '*scpb.TableLocalityPrimaryRegion', '*scpb.TableLocalityRegionalByRow', '*scpb.TableLocalitySecondaryRegion', '*scpb.TablePartitioning', '*scpb.TableSchemaLocked', '*scpb.TableZoneConfig', '*scpb.TemporaryIndex', '*scpb.TypeComment', '*scpb.UniqueWithoutIndexConstraint', '*scpb.UniqueWithoutIndexConstraintUnvalidated', '*scpb.UserPrivileges'] - $descriptor[Type] IN ['*scpb.AliasType', '*scpb.CompositeType', '*scpb.Database', '*scpb.EnumType', '*scpb.Function', '*scpb.Schema', '*scpb.Sequence', '*scpb.Table', '*scpb.View'] - joinOnDescID($dependent, $descriptor, $desc-id) - toAbsent($dependent-Target, $descriptor-Target) @@ -7267,7 +7267,7 @@ deprules kind: Precedence to: relation-Node query: - - $dependent[Type] IN ['*scpb.CheckConstraint', '*scpb.CheckConstraintUnvalidated', '*scpb.Column', '*scpb.ColumnComment', '*scpb.ColumnComputeExpression', '*scpb.ColumnDefaultExpression', '*scpb.ColumnFamily', '*scpb.ColumnName', '*scpb.ColumnNotNull', '*scpb.ColumnOnUpdateExpression', '*scpb.ColumnType', '*scpb.CompositeTypeAttrName', '*scpb.CompositeTypeAttrType', '*scpb.ConstraintComment', '*scpb.ConstraintWithoutIndexName', '*scpb.DatabaseComment', '*scpb.DatabaseRegionConfig', '*scpb.DatabaseRoleSetting', '*scpb.DatabaseZoneConfig', '*scpb.EnumTypeValue', '*scpb.ForeignKeyConstraint', '*scpb.ForeignKeyConstraintUnvalidated', '*scpb.FunctionBody', '*scpb.FunctionLeakProof', '*scpb.FunctionName', '*scpb.FunctionNullInputBehavior', '*scpb.FunctionVolatility', '*scpb.IndexColumn', '*scpb.IndexComment', '*scpb.IndexName', '*scpb.IndexPartitioning', '*scpb.IndexZoneConfig', '*scpb.Namespace', '*scpb.Owner', '*scpb.PrimaryIndex', '*scpb.RowLevelTTL', '*scpb.SchemaChild', '*scpb.SchemaComment', '*scpb.SchemaParent', '*scpb.SecondaryIndex', '*scpb.SecondaryIndexPartial', '*scpb.SequenceOption', '*scpb.SequenceOwner', '*scpb.TableComment', '*scpb.TableLocalityGlobal', '*scpb.TableLocalityPrimaryRegion', '*scpb.TableLocalityRegionalByRow', '*scpb.TableLocalitySecondaryRegion', '*scpb.TablePartitioning', '*scpb.TableSchemaLocked', '*scpb.TableZoneConfig', '*scpb.TemporaryIndex', '*scpb.TypeComment', '*scpb.UniqueWithoutIndexConstraint', '*scpb.UniqueWithoutIndexConstraintUnvalidated', '*scpb.UserPrivileges'] + - $dependent[Type] IN ['*scpb.CheckConstraint', '*scpb.CheckConstraintUnvalidated', '*scpb.Column', '*scpb.ColumnComment', '*scpb.ColumnComputeExpression', '*scpb.ColumnDefaultExpression', '*scpb.ColumnFamily', '*scpb.ColumnName', '*scpb.ColumnNotNull', '*scpb.ColumnOnUpdateExpression', '*scpb.ColumnType', '*scpb.CompositeTypeAttrName', '*scpb.CompositeTypeAttrType', '*scpb.ConstraintComment', '*scpb.ConstraintWithoutIndexName', '*scpb.DatabaseComment', '*scpb.DatabaseRegionConfig', '*scpb.DatabaseRoleSetting', '*scpb.DatabaseZoneConfig', '*scpb.EnumTypeValue', '*scpb.ForeignKeyConstraint', '*scpb.ForeignKeyConstraintUnvalidated', '*scpb.FunctionBody', '*scpb.FunctionLeakProof', '*scpb.FunctionName', '*scpb.FunctionNullInputBehavior', '*scpb.FunctionSecurity', '*scpb.FunctionVolatility', '*scpb.IndexColumn', '*scpb.IndexComment', '*scpb.IndexName', '*scpb.IndexPartitioning', '*scpb.IndexZoneConfig', '*scpb.Namespace', '*scpb.Owner', '*scpb.PrimaryIndex', '*scpb.RowLevelTTL', '*scpb.SchemaChild', '*scpb.SchemaComment', '*scpb.SchemaParent', '*scpb.SecondaryIndex', '*scpb.SecondaryIndexPartial', '*scpb.SequenceOption', '*scpb.SequenceOwner', '*scpb.TableComment', '*scpb.TableLocalityGlobal', '*scpb.TableLocalityPrimaryRegion', '*scpb.TableLocalityRegionalByRow', '*scpb.TableLocalitySecondaryRegion', '*scpb.TablePartitioning', '*scpb.TableSchemaLocked', '*scpb.TableZoneConfig', '*scpb.TemporaryIndex', '*scpb.TypeComment', '*scpb.UniqueWithoutIndexConstraint', '*scpb.UniqueWithoutIndexConstraintUnvalidated', '*scpb.UserPrivileges'] - $relation[Type] IN ['*scpb.AliasType', '*scpb.CompositeType', '*scpb.Database', '*scpb.EnumType', '*scpb.Function', '*scpb.Schema', '*scpb.Sequence', '*scpb.Table', '*scpb.View'] - joinOnDescID($dependent, $relation, $relation-id) - ToPublicOrTransient($dependent-Target, $relation-Target) @@ -7511,7 +7511,7 @@ deprules to: referencing-via-attr-Node query: - $referenced-descriptor[Type] IN ['*scpb.AliasType', '*scpb.CompositeType', '*scpb.Database', '*scpb.EnumType', '*scpb.Function', '*scpb.Schema', '*scpb.Sequence', '*scpb.Table', '*scpb.View'] - - $referencing-via-attr[Type] IN ['*scpb.CheckConstraintUnvalidated', '*scpb.ColumnComment', '*scpb.ColumnComputeExpression', '*scpb.ColumnDefaultExpression', '*scpb.ColumnFamily', '*scpb.ColumnName', '*scpb.ColumnOnUpdateExpression', '*scpb.ColumnType', '*scpb.CompositeTypeAttrName', '*scpb.CompositeTypeAttrType', '*scpb.ConstraintComment', '*scpb.ConstraintWithoutIndexName', '*scpb.DatabaseComment', '*scpb.DatabaseRegionConfig', '*scpb.DatabaseRoleSetting', '*scpb.DatabaseZoneConfig', '*scpb.EnumTypeValue', '*scpb.ForeignKeyConstraintUnvalidated', '*scpb.FunctionBody', '*scpb.FunctionLeakProof', '*scpb.FunctionName', '*scpb.FunctionNullInputBehavior', '*scpb.FunctionVolatility', '*scpb.IndexColumn', '*scpb.IndexComment', '*scpb.IndexName', '*scpb.IndexPartitioning', '*scpb.IndexZoneConfig', '*scpb.Namespace', '*scpb.Owner', '*scpb.RowLevelTTL', '*scpb.SchemaComment', '*scpb.SecondaryIndexPartial', '*scpb.SequenceOption', '*scpb.SequenceOwner', '*scpb.TableComment', '*scpb.TableLocalityGlobal', '*scpb.TableLocalityPrimaryRegion', '*scpb.TableLocalityRegionalByRow', '*scpb.TableLocalitySecondaryRegion', '*scpb.TablePartitioning', '*scpb.TableSchemaLocked', '*scpb.TableZoneConfig', '*scpb.TypeComment', '*scpb.UniqueWithoutIndexConstraintUnvalidated', '*scpb.UserPrivileges'] + - $referencing-via-attr[Type] IN ['*scpb.CheckConstraintUnvalidated', '*scpb.ColumnComment', '*scpb.ColumnComputeExpression', '*scpb.ColumnDefaultExpression', '*scpb.ColumnFamily', '*scpb.ColumnName', '*scpb.ColumnOnUpdateExpression', '*scpb.ColumnType', '*scpb.CompositeTypeAttrName', '*scpb.CompositeTypeAttrType', '*scpb.ConstraintComment', '*scpb.ConstraintWithoutIndexName', '*scpb.DatabaseComment', '*scpb.DatabaseRegionConfig', '*scpb.DatabaseRoleSetting', '*scpb.DatabaseZoneConfig', '*scpb.EnumTypeValue', '*scpb.ForeignKeyConstraintUnvalidated', '*scpb.FunctionBody', '*scpb.FunctionLeakProof', '*scpb.FunctionName', '*scpb.FunctionNullInputBehavior', '*scpb.FunctionSecurity', '*scpb.FunctionVolatility', '*scpb.IndexColumn', '*scpb.IndexComment', '*scpb.IndexName', '*scpb.IndexPartitioning', '*scpb.IndexZoneConfig', '*scpb.Namespace', '*scpb.Owner', '*scpb.RowLevelTTL', '*scpb.SchemaComment', '*scpb.SecondaryIndexPartial', '*scpb.SequenceOption', '*scpb.SequenceOwner', '*scpb.TableComment', '*scpb.TableLocalityGlobal', '*scpb.TableLocalityPrimaryRegion', '*scpb.TableLocalityRegionalByRow', '*scpb.TableLocalitySecondaryRegion', '*scpb.TablePartitioning', '*scpb.TableSchemaLocked', '*scpb.TableZoneConfig', '*scpb.TypeComment', '*scpb.UniqueWithoutIndexConstraintUnvalidated', '*scpb.UserPrivileges'] - joinReferencedDescID($referencing-via-attr, $referenced-descriptor, $desc-id) - toAbsent($referenced-descriptor-Target, $referencing-via-attr-Target) - $referenced-descriptor-Node[CurrentStatus] = DROPPED @@ -7567,7 +7567,7 @@ deprules to: dependent-Node query: - $descriptor[Type] IN ['*scpb.AliasType', '*scpb.CompositeType', '*scpb.Database', '*scpb.EnumType', '*scpb.Function', '*scpb.Schema', '*scpb.Sequence', '*scpb.Table', '*scpb.View'] - - $dependent[Type] IN ['*scpb.CheckConstraintUnvalidated', '*scpb.ColumnComment', '*scpb.ColumnComputeExpression', '*scpb.ColumnDefaultExpression', '*scpb.ColumnFamily', '*scpb.ColumnName', '*scpb.ColumnOnUpdateExpression', '*scpb.ColumnType', '*scpb.CompositeTypeAttrName', '*scpb.CompositeTypeAttrType', '*scpb.DatabaseComment', '*scpb.DatabaseRegionConfig', '*scpb.DatabaseRoleSetting', '*scpb.DatabaseZoneConfig', '*scpb.EnumTypeValue', '*scpb.ForeignKeyConstraintUnvalidated', '*scpb.FunctionBody', '*scpb.FunctionLeakProof', '*scpb.FunctionName', '*scpb.FunctionNullInputBehavior', '*scpb.FunctionVolatility', '*scpb.IndexColumn', '*scpb.IndexComment', '*scpb.IndexName', '*scpb.IndexPartitioning', '*scpb.IndexZoneConfig', '*scpb.Namespace', '*scpb.Owner', '*scpb.RowLevelTTL', '*scpb.SchemaChild', '*scpb.SchemaComment', '*scpb.SchemaParent', '*scpb.SecondaryIndexPartial', '*scpb.SequenceOption', '*scpb.SequenceOwner', '*scpb.TableComment', '*scpb.TableLocalityGlobal', '*scpb.TableLocalityPrimaryRegion', '*scpb.TableLocalityRegionalByRow', '*scpb.TableLocalitySecondaryRegion', '*scpb.TablePartitioning', '*scpb.TableSchemaLocked', '*scpb.TableZoneConfig', '*scpb.TypeComment', '*scpb.UniqueWithoutIndexConstraintUnvalidated', '*scpb.UserPrivileges'] + - $dependent[Type] IN ['*scpb.CheckConstraintUnvalidated', '*scpb.ColumnComment', '*scpb.ColumnComputeExpression', '*scpb.ColumnDefaultExpression', '*scpb.ColumnFamily', '*scpb.ColumnName', '*scpb.ColumnOnUpdateExpression', '*scpb.ColumnType', '*scpb.CompositeTypeAttrName', '*scpb.CompositeTypeAttrType', '*scpb.DatabaseComment', '*scpb.DatabaseRegionConfig', '*scpb.DatabaseRoleSetting', '*scpb.DatabaseZoneConfig', '*scpb.EnumTypeValue', '*scpb.ForeignKeyConstraintUnvalidated', '*scpb.FunctionBody', '*scpb.FunctionLeakProof', '*scpb.FunctionName', '*scpb.FunctionNullInputBehavior', '*scpb.FunctionSecurity', '*scpb.FunctionVolatility', '*scpb.IndexColumn', '*scpb.IndexComment', '*scpb.IndexName', '*scpb.IndexPartitioning', '*scpb.IndexZoneConfig', '*scpb.Namespace', '*scpb.Owner', '*scpb.RowLevelTTL', '*scpb.SchemaChild', '*scpb.SchemaComment', '*scpb.SchemaParent', '*scpb.SecondaryIndexPartial', '*scpb.SequenceOption', '*scpb.SequenceOwner', '*scpb.TableComment', '*scpb.TableLocalityGlobal', '*scpb.TableLocalityPrimaryRegion', '*scpb.TableLocalityRegionalByRow', '*scpb.TableLocalitySecondaryRegion', '*scpb.TablePartitioning', '*scpb.TableSchemaLocked', '*scpb.TableZoneConfig', '*scpb.TypeComment', '*scpb.UniqueWithoutIndexConstraintUnvalidated', '*scpb.UserPrivileges'] - joinOnDescID($descriptor, $dependent, $desc-id) - toAbsent($descriptor-Target, $dependent-Target) - $descriptor-Node[CurrentStatus] = DROPPED @@ -7606,7 +7606,7 @@ deprules to: dependent-Node query: - $relation[Type] IN ['*scpb.AliasType', '*scpb.CompositeType', '*scpb.Database', '*scpb.EnumType', '*scpb.Function', '*scpb.Schema', '*scpb.Sequence', '*scpb.Table', '*scpb.View'] - - $dependent[Type] IN ['*scpb.CheckConstraint', '*scpb.CheckConstraintUnvalidated', '*scpb.Column', '*scpb.ColumnComment', '*scpb.ColumnComputeExpression', '*scpb.ColumnDefaultExpression', '*scpb.ColumnFamily', '*scpb.ColumnName', '*scpb.ColumnNotNull', '*scpb.ColumnOnUpdateExpression', '*scpb.ColumnType', '*scpb.CompositeTypeAttrName', '*scpb.CompositeTypeAttrType', '*scpb.ConstraintComment', '*scpb.ConstraintWithoutIndexName', '*scpb.DatabaseComment', '*scpb.DatabaseData', '*scpb.DatabaseRegionConfig', '*scpb.DatabaseRoleSetting', '*scpb.DatabaseZoneConfig', '*scpb.EnumTypeValue', '*scpb.ForeignKeyConstraint', '*scpb.ForeignKeyConstraintUnvalidated', '*scpb.FunctionBody', '*scpb.FunctionLeakProof', '*scpb.FunctionName', '*scpb.FunctionNullInputBehavior', '*scpb.FunctionVolatility', '*scpb.IndexColumn', '*scpb.IndexComment', '*scpb.IndexData', '*scpb.IndexName', '*scpb.IndexPartitioning', '*scpb.IndexZoneConfig', '*scpb.Namespace', '*scpb.Owner', '*scpb.PrimaryIndex', '*scpb.RowLevelTTL', '*scpb.SchemaChild', '*scpb.SchemaComment', '*scpb.SchemaParent', '*scpb.SecondaryIndex', '*scpb.SecondaryIndexPartial', '*scpb.SequenceOption', '*scpb.SequenceOwner', '*scpb.TableComment', '*scpb.TableData', '*scpb.TableLocalityGlobal', '*scpb.TableLocalityPrimaryRegion', '*scpb.TableLocalityRegionalByRow', '*scpb.TableLocalitySecondaryRegion', '*scpb.TablePartitioning', '*scpb.TableSchemaLocked', '*scpb.TableZoneConfig', '*scpb.TemporaryIndex', '*scpb.TypeComment', '*scpb.UniqueWithoutIndexConstraint', '*scpb.UniqueWithoutIndexConstraintUnvalidated', '*scpb.UserPrivileges'] + - $dependent[Type] IN ['*scpb.CheckConstraint', '*scpb.CheckConstraintUnvalidated', '*scpb.Column', '*scpb.ColumnComment', '*scpb.ColumnComputeExpression', '*scpb.ColumnDefaultExpression', '*scpb.ColumnFamily', '*scpb.ColumnName', '*scpb.ColumnNotNull', '*scpb.ColumnOnUpdateExpression', '*scpb.ColumnType', '*scpb.CompositeTypeAttrName', '*scpb.CompositeTypeAttrType', '*scpb.ConstraintComment', '*scpb.ConstraintWithoutIndexName', '*scpb.DatabaseComment', '*scpb.DatabaseData', '*scpb.DatabaseRegionConfig', '*scpb.DatabaseRoleSetting', '*scpb.DatabaseZoneConfig', '*scpb.EnumTypeValue', '*scpb.ForeignKeyConstraint', '*scpb.ForeignKeyConstraintUnvalidated', '*scpb.FunctionBody', '*scpb.FunctionLeakProof', '*scpb.FunctionName', '*scpb.FunctionNullInputBehavior', '*scpb.FunctionSecurity', '*scpb.FunctionVolatility', '*scpb.IndexColumn', '*scpb.IndexComment', '*scpb.IndexData', '*scpb.IndexName', '*scpb.IndexPartitioning', '*scpb.IndexZoneConfig', '*scpb.Namespace', '*scpb.Owner', '*scpb.PrimaryIndex', '*scpb.RowLevelTTL', '*scpb.SchemaChild', '*scpb.SchemaComment', '*scpb.SchemaParent', '*scpb.SecondaryIndex', '*scpb.SecondaryIndexPartial', '*scpb.SequenceOption', '*scpb.SequenceOwner', '*scpb.TableComment', '*scpb.TableData', '*scpb.TableLocalityGlobal', '*scpb.TableLocalityPrimaryRegion', '*scpb.TableLocalityRegionalByRow', '*scpb.TableLocalitySecondaryRegion', '*scpb.TablePartitioning', '*scpb.TableSchemaLocked', '*scpb.TableZoneConfig', '*scpb.TemporaryIndex', '*scpb.TypeComment', '*scpb.UniqueWithoutIndexConstraint', '*scpb.UniqueWithoutIndexConstraintUnvalidated', '*scpb.UserPrivileges'] - joinOnDescID($relation, $dependent, $relation-id) - ToPublicOrTransient($relation-Target, $dependent-Target) - $relation-Node[CurrentStatus] = DESCRIPTOR_ADDED @@ -8047,7 +8047,7 @@ deprules kind: Precedence to: descriptor-Node query: - - $dependent[Type] IN ['*scpb.CheckConstraint', '*scpb.CheckConstraintUnvalidated', '*scpb.Column', '*scpb.ColumnComment', '*scpb.ColumnComputeExpression', '*scpb.ColumnDefaultExpression', '*scpb.ColumnFamily', '*scpb.ColumnName', '*scpb.ColumnNotNull', '*scpb.ColumnOnUpdateExpression', '*scpb.ColumnType', '*scpb.CompositeTypeAttrName', '*scpb.CompositeTypeAttrType', '*scpb.ConstraintComment', '*scpb.ConstraintWithoutIndexName', '*scpb.DatabaseComment', '*scpb.DatabaseRegionConfig', '*scpb.DatabaseRoleSetting', '*scpb.DatabaseZoneConfig', '*scpb.EnumTypeValue', '*scpb.ForeignKeyConstraint', '*scpb.ForeignKeyConstraintUnvalidated', '*scpb.FunctionBody', '*scpb.FunctionLeakProof', '*scpb.FunctionName', '*scpb.FunctionNullInputBehavior', '*scpb.FunctionVolatility', '*scpb.IndexColumn', '*scpb.IndexComment', '*scpb.IndexName', '*scpb.IndexPartitioning', '*scpb.IndexZoneConfig', '*scpb.Namespace', '*scpb.Owner', '*scpb.PrimaryIndex', '*scpb.RowLevelTTL', '*scpb.SchemaChild', '*scpb.SchemaComment', '*scpb.SchemaParent', '*scpb.SecondaryIndex', '*scpb.SecondaryIndexPartial', '*scpb.SequenceOption', '*scpb.SequenceOwner', '*scpb.TableComment', '*scpb.TableLocalityGlobal', '*scpb.TableLocalityPrimaryRegion', '*scpb.TableLocalityRegionalByRow', '*scpb.TableLocalitySecondaryRegion', '*scpb.TablePartitioning', '*scpb.TableSchemaLocked', '*scpb.TableZoneConfig', '*scpb.TemporaryIndex', '*scpb.TypeComment', '*scpb.UniqueWithoutIndexConstraint', '*scpb.UniqueWithoutIndexConstraintUnvalidated', '*scpb.UserPrivileges'] + - $dependent[Type] IN ['*scpb.CheckConstraint', '*scpb.CheckConstraintUnvalidated', '*scpb.Column', '*scpb.ColumnComment', '*scpb.ColumnComputeExpression', '*scpb.ColumnDefaultExpression', '*scpb.ColumnFamily', '*scpb.ColumnName', '*scpb.ColumnNotNull', '*scpb.ColumnOnUpdateExpression', '*scpb.ColumnType', '*scpb.CompositeTypeAttrName', '*scpb.CompositeTypeAttrType', '*scpb.ConstraintComment', '*scpb.ConstraintWithoutIndexName', '*scpb.DatabaseComment', '*scpb.DatabaseRegionConfig', '*scpb.DatabaseRoleSetting', '*scpb.DatabaseZoneConfig', '*scpb.EnumTypeValue', '*scpb.ForeignKeyConstraint', '*scpb.ForeignKeyConstraintUnvalidated', '*scpb.FunctionBody', '*scpb.FunctionLeakProof', '*scpb.FunctionName', '*scpb.FunctionNullInputBehavior', '*scpb.FunctionSecurity', '*scpb.FunctionVolatility', '*scpb.IndexColumn', '*scpb.IndexComment', '*scpb.IndexName', '*scpb.IndexPartitioning', '*scpb.IndexZoneConfig', '*scpb.Namespace', '*scpb.Owner', '*scpb.PrimaryIndex', '*scpb.RowLevelTTL', '*scpb.SchemaChild', '*scpb.SchemaComment', '*scpb.SchemaParent', '*scpb.SecondaryIndex', '*scpb.SecondaryIndexPartial', '*scpb.SequenceOption', '*scpb.SequenceOwner', '*scpb.TableComment', '*scpb.TableLocalityGlobal', '*scpb.TableLocalityPrimaryRegion', '*scpb.TableLocalityRegionalByRow', '*scpb.TableLocalitySecondaryRegion', '*scpb.TablePartitioning', '*scpb.TableSchemaLocked', '*scpb.TableZoneConfig', '*scpb.TemporaryIndex', '*scpb.TypeComment', '*scpb.UniqueWithoutIndexConstraint', '*scpb.UniqueWithoutIndexConstraintUnvalidated', '*scpb.UserPrivileges'] - $descriptor[Type] IN ['*scpb.AliasType', '*scpb.CompositeType', '*scpb.Database', '*scpb.EnumType', '*scpb.Function', '*scpb.Schema', '*scpb.Sequence', '*scpb.Table', '*scpb.View'] - joinOnDescID($dependent, $descriptor, $desc-id) - toAbsent($dependent-Target, $descriptor-Target) diff --git a/pkg/sql/schemachanger/scplan/testdata/drop_function b/pkg/sql/schemachanger/scplan/testdata/drop_function index 9ae99aa455b3..d8b6dabfb590 100644 --- a/pkg/sql/schemachanger/scplan/testdata/drop_function +++ b/pkg/sql/schemachanger/scplan/testdata/drop_function @@ -21,7 +21,7 @@ $$; ops DROP FUNCTION f; ---- -StatementPhase stage 1 of 1 with 13 MutationType ops +StatementPhase stage 1 of 1 with 14 MutationType ops transitions: [[Owner:{DescID: 109}, ABSENT], PUBLIC] -> ABSENT [[UserPrivileges:{DescID: 109, Name: admin}, ABSENT], PUBLIC] -> ABSENT @@ -33,6 +33,7 @@ StatementPhase stage 1 of 1 with 13 MutationType ops [[FunctionVolatility:{DescID: 109}, ABSENT], PUBLIC] -> ABSENT [[FunctionLeakProof:{DescID: 109}, ABSENT], PUBLIC] -> ABSENT [[FunctionNullInputBehavior:{DescID: 109}, ABSENT], PUBLIC] -> ABSENT + [[FunctionSecurity:{DescID: 109}, ABSENT], PUBLIC] -> ABSENT [[FunctionBody:{DescID: 109}, ABSENT], PUBLIC] -> ABSENT ops: *scop.MarkDescriptorAsDropped @@ -52,6 +53,9 @@ StatementPhase stage 1 of 1 with 13 MutationType ops *scop.NotImplementedForPublicObjects DescID: 109 ElementType: scpb.FunctionNullInputBehavior + *scop.NotImplementedForPublicObjects + DescID: 109 + ElementType: scpb.FunctionSecurity *scop.RemoveBackReferenceInTypes BackReferencedDescriptorID: 109 TypeIDs: @@ -91,11 +95,12 @@ PreCommitPhase stage 1 of 2 with 1 MutationType op [[FunctionVolatility:{DescID: 109}, ABSENT], ABSENT] -> PUBLIC [[FunctionLeakProof:{DescID: 109}, ABSENT], ABSENT] -> PUBLIC [[FunctionNullInputBehavior:{DescID: 109}, ABSENT], ABSENT] -> PUBLIC + [[FunctionSecurity:{DescID: 109}, ABSENT], ABSENT] -> PUBLIC [[FunctionBody:{DescID: 109}, ABSENT], ABSENT] -> PUBLIC ops: *scop.UndoAllInTxnImmediateMutationOpSideEffects {} -PreCommitPhase stage 2 of 2 with 20 MutationType ops +PreCommitPhase stage 2 of 2 with 21 MutationType ops transitions: [[Owner:{DescID: 109}, ABSENT], PUBLIC] -> ABSENT [[UserPrivileges:{DescID: 109, Name: admin}, ABSENT], PUBLIC] -> ABSENT @@ -107,6 +112,7 @@ PreCommitPhase stage 2 of 2 with 20 MutationType ops [[FunctionVolatility:{DescID: 109}, ABSENT], PUBLIC] -> ABSENT [[FunctionLeakProof:{DescID: 109}, ABSENT], PUBLIC] -> ABSENT [[FunctionNullInputBehavior:{DescID: 109}, ABSENT], PUBLIC] -> ABSENT + [[FunctionSecurity:{DescID: 109}, ABSENT], PUBLIC] -> ABSENT [[FunctionBody:{DescID: 109}, ABSENT], PUBLIC] -> ABSENT ops: *scop.MarkDescriptorAsDropped @@ -126,6 +132,9 @@ PreCommitPhase stage 2 of 2 with 20 MutationType ops *scop.NotImplementedForPublicObjects DescID: 109 ElementType: scpb.FunctionNullInputBehavior + *scop.NotImplementedForPublicObjects + DescID: 109 + ElementType: scpb.FunctionSecurity *scop.RemoveBackReferenceInTypes BackReferencedDescriptorID: 109 TypeIDs: diff --git a/pkg/sql/schemachanger/screl/attr.go b/pkg/sql/schemachanger/screl/attr.go index dfdeed1e2c6c..16a3c93b9a32 100644 --- a/pkg/sql/schemachanger/screl/attr.go +++ b/pkg/sql/schemachanger/screl/attr.go @@ -435,6 +435,9 @@ var elementSchemaOptions = []rel.SchemaOption{ rel.EntityMapping(t((*scpb.FunctionBody)(nil)), rel.EntityAttr(DescID, "FunctionID"), ), + rel.EntityMapping(t((*scpb.FunctionSecurity)(nil)), + rel.EntityAttr(DescID, "FunctionID"), + ), } // Schema is the schema exported by this package covering the elements of scpb. diff --git a/pkg/sql/schemachanger/screl/scalars.go b/pkg/sql/schemachanger/screl/scalars.go index c57bfb294427..dd6b7220695d 100644 --- a/pkg/sql/schemachanger/screl/scalars.go +++ b/pkg/sql/schemachanger/screl/scalars.go @@ -127,7 +127,7 @@ func VersionSupportsElementUse(el scpb.Element, version clusterversion.ClusterVe return true case *scpb.TypeComment, *scpb.DatabaseZoneConfig: return version.IsActive(clusterversion.V24_2) - case *scpb.ColumnComputeExpression: + case *scpb.ColumnComputeExpression, *scpb.FunctionSecurity: return version.IsActive(clusterversion.V24_3) default: panic(errors.AssertionFailedf("unknown element %T", el)) diff --git a/pkg/sql/schemachanger/testdata/end_to_end/drop_function/drop_function.explain b/pkg/sql/schemachanger/testdata/end_to_end/drop_function/drop_function.explain index d91d6761a2f1..dac3d19e5d9e 100644 --- a/pkg/sql/schemachanger/testdata/end_to_end/drop_function/drop_function.explain +++ b/pkg/sql/schemachanger/testdata/end_to_end/drop_function/drop_function.explain @@ -24,7 +24,7 @@ EXPLAIN (DDL) DROP FUNCTION f; Schema change plan for DROP FUNCTION ‹""›.‹""›.‹f›; ├── StatementPhase │ └── Stage 1 of 1 in StatementPhase - │ ├── 11 elements transitioning toward ABSENT + │ ├── 12 elements transitioning toward ABSENT │ │ ├── PUBLIC → ABSENT Owner:{DescID: 109 (f-)} │ │ ├── PUBLIC → ABSENT UserPrivileges:{DescID: 109 (f-), Name: "admin"} │ │ ├── PUBLIC → ABSENT UserPrivileges:{DescID: 109 (f-), Name: "public"} @@ -35,14 +35,16 @@ Schema change plan for DROP FUNCTION ‹""›.‹""›.‹f›; │ │ ├── PUBLIC → ABSENT FunctionVolatility:{DescID: 109 (f-)} │ │ ├── PUBLIC → ABSENT FunctionLeakProof:{DescID: 109 (f-)} │ │ ├── PUBLIC → ABSENT FunctionNullInputBehavior:{DescID: 109 (f-)} + │ │ ├── PUBLIC → ABSENT FunctionSecurity:{DescID: 109 (f-)} │ │ └── PUBLIC → ABSENT FunctionBody:{DescID: 109 (f-)} - │ └── 13 Mutation operations + │ └── 14 Mutation operations │ ├── MarkDescriptorAsDropped {"DescriptorID":109} │ ├── RemoveObjectParent {"ObjectID":109,"ParentSchemaID":101} │ ├── NotImplementedForPublicObjects {"DescID":109,"ElementType":"scpb.FunctionNam..."} │ ├── NotImplementedForPublicObjects {"DescID":109,"ElementType":"scpb.FunctionVol..."} │ ├── NotImplementedForPublicObjects {"DescID":109,"ElementType":"scpb.FunctionLea..."} │ ├── NotImplementedForPublicObjects {"DescID":109,"ElementType":"scpb.FunctionNul..."} + │ ├── NotImplementedForPublicObjects {"DescID":109,"ElementType":"scpb.FunctionSec..."} │ ├── RemoveBackReferenceInTypes {"BackReferencedDescriptorID":109} │ ├── RemoveBackReferencesInRelations {"BackReferencedID":109} │ ├── RemoveBackReferenceInFunctions {"BackReferencedDescriptorID":109} @@ -52,7 +54,7 @@ Schema change plan for DROP FUNCTION ‹""›.‹""›.‹f›; │ └── RemoveUserPrivileges {"DescriptorID":109,"User":"root"} ├── PreCommitPhase │ ├── Stage 1 of 2 in PreCommitPhase - │ │ ├── 11 elements transitioning toward ABSENT + │ │ ├── 12 elements transitioning toward ABSENT │ │ │ ├── ABSENT → PUBLIC Owner:{DescID: 109 (f-)} │ │ │ ├── ABSENT → PUBLIC UserPrivileges:{DescID: 109 (f-), Name: "admin"} │ │ │ ├── ABSENT → PUBLIC UserPrivileges:{DescID: 109 (f-), Name: "public"} @@ -63,11 +65,12 @@ Schema change plan for DROP FUNCTION ‹""›.‹""›.‹f›; │ │ │ ├── ABSENT → PUBLIC FunctionVolatility:{DescID: 109 (f-)} │ │ │ ├── ABSENT → PUBLIC FunctionLeakProof:{DescID: 109 (f-)} │ │ │ ├── ABSENT → PUBLIC FunctionNullInputBehavior:{DescID: 109 (f-)} + │ │ │ ├── ABSENT → PUBLIC FunctionSecurity:{DescID: 109 (f-)} │ │ │ └── ABSENT → PUBLIC FunctionBody:{DescID: 109 (f-)} │ │ └── 1 Mutation operation │ │ └── UndoAllInTxnImmediateMutationOpSideEffects │ └── Stage 2 of 2 in PreCommitPhase - │ ├── 11 elements transitioning toward ABSENT + │ ├── 12 elements transitioning toward ABSENT │ │ ├── PUBLIC → ABSENT Owner:{DescID: 109 (f-)} │ │ ├── PUBLIC → ABSENT UserPrivileges:{DescID: 109 (f-), Name: "admin"} │ │ ├── PUBLIC → ABSENT UserPrivileges:{DescID: 109 (f-), Name: "public"} @@ -78,14 +81,16 @@ Schema change plan for DROP FUNCTION ‹""›.‹""›.‹f›; │ │ ├── PUBLIC → ABSENT FunctionVolatility:{DescID: 109 (f-)} │ │ ├── PUBLIC → ABSENT FunctionLeakProof:{DescID: 109 (f-)} │ │ ├── PUBLIC → ABSENT FunctionNullInputBehavior:{DescID: 109 (f-)} + │ │ ├── PUBLIC → ABSENT FunctionSecurity:{DescID: 109 (f-)} │ │ └── PUBLIC → ABSENT FunctionBody:{DescID: 109 (f-)} - │ └── 20 Mutation operations + │ └── 21 Mutation operations │ ├── MarkDescriptorAsDropped {"DescriptorID":109} │ ├── RemoveObjectParent {"ObjectID":109,"ParentSchemaID":101} │ ├── NotImplementedForPublicObjects {"DescID":109,"ElementType":"scpb.FunctionNam..."} │ ├── NotImplementedForPublicObjects {"DescID":109,"ElementType":"scpb.FunctionVol..."} │ ├── NotImplementedForPublicObjects {"DescID":109,"ElementType":"scpb.FunctionLea..."} │ ├── NotImplementedForPublicObjects {"DescID":109,"ElementType":"scpb.FunctionNul..."} + │ ├── NotImplementedForPublicObjects {"DescID":109,"ElementType":"scpb.FunctionSec..."} │ ├── RemoveBackReferenceInTypes {"BackReferencedDescriptorID":109} │ ├── RemoveBackReferencesInRelations {"BackReferencedID":109} │ ├── RemoveBackReferenceInFunctions {"BackReferencedDescriptorID":109} diff --git a/pkg/sql/schemachanger/testdata/end_to_end/drop_function/drop_function.side_effects b/pkg/sql/schemachanger/testdata/end_to_end/drop_function/drop_function.side_effects index 894e640e8773..1f0cc65c1115 100644 --- a/pkg/sql/schemachanger/testdata/end_to_end/drop_function/drop_function.side_effects +++ b/pkg/sql/schemachanger/testdata/end_to_end/drop_function/drop_function.side_effects @@ -40,7 +40,7 @@ write *eventpb.DropFunction to event log: statement: DROP FUNCTION ‹""›.‹""›.‹f› tag: DROP FUNCTION user: root -## StatementPhase stage 1 of 1 with 13 MutationType ops +## StatementPhase stage 1 of 1 with 14 MutationType ops upsert descriptor #101 schema: - functions: @@ -144,7 +144,7 @@ upsert descriptor #109 ## PreCommitPhase stage 1 of 2 with 1 MutationType op undo all catalog changes within txn #1 persist all catalog changes to storage -## PreCommitPhase stage 2 of 2 with 20 MutationType ops +## PreCommitPhase stage 2 of 2 with 21 MutationType ops upsert descriptor #101 schema: - functions: diff --git a/pkg/sql/sem/tree/create_routine.go b/pkg/sql/sem/tree/create_routine.go index 7d1660924f77..602023c06199 100644 --- a/pkg/sql/sem/tree/create_routine.go +++ b/pkg/sql/sem/tree/create_routine.go @@ -203,6 +203,7 @@ func (RoutineVolatility) routineOption() {} func (RoutineLeakproof) routineOption() {} func (RoutineBodyStr) routineOption() {} func (RoutineLanguage) routineOption() {} +func (RoutineSecurity) routineOption() {} // RoutineNullInputBehavior represent the UDF property on null parameters. type RoutineNullInputBehavior int @@ -310,6 +311,33 @@ func AsRoutineLanguage(lang string) (RoutineLanguage, error) { return RoutineLanguage(lang), nil } +// RoutineSecurity indicates the mode of security that the routine will +// be executed with. +type RoutineSecurity int + +const ( + // RoutineInvoker indicates that the routine is run with the privileges of + // the user invoking it. This is the default security mode if none is + // provided. + RoutineInvoker RoutineSecurity = iota + // RoutineDefiner indicates that the routine is run with the privileges of + // the user who defined it. + RoutineDefiner +) + +// Format implements the NodeFormatter interface. +func (node RoutineSecurity) Format(ctx *FmtCtx) { + ctx.WriteString("SECURITY ") + switch node { + case RoutineInvoker: + ctx.WriteString("INVOKER") + case RoutineDefiner: + ctx.WriteString("DEFINER") + default: + panic(pgerror.New(pgcode.InvalidParameterValue, "unknown routine option")) + } +} + // RoutineBodyStr is a string containing all statements in a UDF body. type RoutineBodyStr string @@ -640,7 +668,7 @@ func ComputedColumnExprContext(isVirtual bool) SchemaExprContext { // ValidateRoutineOptions checks whether there are conflicting or redundant // routine options in the given slice. func ValidateRoutineOptions(options RoutineOptions, isProc bool) error { - var hasLang, hasBody, hasLeakProof, hasVolatility, hasNullInputBehavior bool + var hasLang, hasBody, hasLeakProof, hasVolatility, hasNullInputBehavior, hasSecurity bool conflictingErr := func(opt RoutineOption) error { return errors.Wrapf(ErrConflictingRoutineOption, "%s", AsString(opt)) } @@ -680,6 +708,11 @@ func ValidateRoutineOptions(options RoutineOptions, isProc bool) error { return conflictingErr(option) } hasNullInputBehavior = true + case RoutineSecurity: + if hasSecurity { + return conflictingErr(option) + } + hasSecurity = true default: return pgerror.Newf(pgcode.InvalidParameterValue, "unknown function option: ", AsString(option)) }