-- All objects made in this test are in temp_func_test schema
CREATE USER regress_unpriv_user;
CREATESCHEMA temp_func_test; GRANTALLONSCHEMA temp_func_test TO public;
SET search_path TO temp_func_test, public;
-- -- Make sanity checks on the pg_proc entries created by CREATE FUNCTION --
-- -- ARGUMENT and RETURN TYPES -- CREATE FUNCTION functest_A_1(text, date) RETURNS bool LANGUAGE 'sql' AS'SELECT $1 = ''abcd'' AND $2 > ''2001-01-01'''; CREATE FUNCTION functest_A_2(text[]) RETURNS int LANGUAGE 'sql' AS'SELECT $1[1]::int'; CREATE FUNCTION functest_A_3() RETURNS bool LANGUAGE 'sql' AS'SELECT false'; SELECT proname, prorettype::regtype, proargtypes::regtype[] FROM pg_proc WHERE oid in ('functest_A_1'::regproc, 'functest_A_2'::regproc, 'functest_A_3'::regproc) ORDERBY proname;
-- -- IMMUTABLE | STABLE | VOLATILE -- CREATE FUNCTION functest_B_1(int) RETURNS bool LANGUAGE 'sql' AS'SELECT $1 > 0'; CREATE FUNCTION functest_B_2(int) RETURNS bool LANGUAGE 'sql'
IMMUTABLE AS'SELECT $1 > 0'; CREATE FUNCTION functest_B_3(int) RETURNS bool LANGUAGE 'sql'
STABLE AS'SELECT $1 = 0'; CREATE FUNCTION functest_B_4(int) RETURNS bool LANGUAGE 'sql'
VOLATILE AS'SELECT $1 < 0'; SELECT proname, provolatile FROM pg_proc WHERE oid in ('functest_B_1'::regproc, 'functest_B_2'::regproc, 'functest_B_3'::regproc, 'functest_B_4'::regproc) ORDERBY proname;
ALTER FUNCTION functest_B_2(int) VOLATILE; ALTER FUNCTION functest_B_3(int) COST 100; -- unrelated change, no effect SELECT proname, provolatile FROM pg_proc WHERE oid in ('functest_B_1'::regproc, 'functest_B_2'::regproc, 'functest_B_3'::regproc, 'functest_B_4'::regproc) ORDERBY proname;
-- -- SECURITY DEFINER | INVOKER -- CREATE FUNCTION functest_C_1(int) RETURNS bool LANGUAGE 'sql' AS'SELECT $1 > 0'; CREATE FUNCTION functest_C_2(int) RETURNS bool LANGUAGE 'sql'
SECURITY DEFINER AS'SELECT $1 = 0'; CREATE FUNCTION functest_C_3(int) RETURNS bool LANGUAGE 'sql'
SECURITY INVOKER AS'SELECT $1 < 0'; SELECT proname, prosecdef FROM pg_proc WHERE oid in ('functest_C_1'::regproc, 'functest_C_2'::regproc, 'functest_C_3'::regproc) ORDERBY proname;
ALTER FUNCTION functest_C_1(int) IMMUTABLE; -- unrelated change, no effect ALTER FUNCTION functest_C_2(int) SECURITY INVOKER; ALTER FUNCTION functest_C_3(int) SECURITY DEFINER; SELECT proname, prosecdef FROM pg_proc WHERE oid in ('functest_C_1'::regproc, 'functest_C_2'::regproc, 'functest_C_3'::regproc) ORDERBY proname;
-- -- LEAKPROOF -- CREATE FUNCTION functest_E_1(int) RETURNS bool LANGUAGE 'sql' AS'SELECT $1 > 100'; CREATE FUNCTION functest_E_2(int) RETURNS bool LANGUAGE 'sql'
LEAKPROOF AS'SELECT $1 > 100'; SELECT proname, proleakproof FROM pg_proc WHERE oid in ('functest_E_1'::regproc, 'functest_E_2'::regproc) ORDERBY proname;
ALTER FUNCTION functest_E_1(int) LEAKPROOF; ALTER FUNCTION functest_E_2(int) STABLE; -- unrelated change, no effect SELECT proname, proleakproof FROM pg_proc WHERE oid in ('functest_E_1'::regproc, 'functest_E_2'::regproc) ORDERBY proname;
ALTER FUNCTION functest_E_2(int) NOT LEAKPROOF; -- remove leakproof attribute SELECT proname, proleakproof FROM pg_proc WHERE oid in ('functest_E_1'::regproc, 'functest_E_2'::regproc) ORDERBY proname;
-- it takes superuser privilege to turn on leakproof, but not to turn off ALTER FUNCTION functest_E_1(int) OWNER TO regress_unpriv_user; ALTER FUNCTION functest_E_2(int) OWNER TO regress_unpriv_user;
SET SESSION AUTHORIZATION regress_unpriv_user; SET search_path TO temp_func_test, public; ALTER FUNCTION functest_E_1(int) NOT LEAKPROOF; ALTER FUNCTION functest_E_2(int) LEAKPROOF;
CREATE FUNCTION functest_E_3(int) RETURNS bool LANGUAGE 'sql'
LEAKPROOF AS'SELECT $1 < 200'; -- fail
RESET SESSION AUTHORIZATION;
-- -- CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT -- CREATE FUNCTION functest_F_1(int) RETURNS bool LANGUAGE 'sql' AS'SELECT $1 > 50'; CREATE FUNCTION functest_F_2(int) RETURNS bool LANGUAGE 'sql'
CALLED ONNULL INPUT AS'SELECT $1 = 50'; CREATE FUNCTION functest_F_3(int) RETURNS bool LANGUAGE 'sql'
RETURNS NULLONNULL INPUT AS'SELECT $1 < 50'; CREATE FUNCTION functest_F_4(int) RETURNS bool LANGUAGE 'sql'
STRICT AS'SELECT $1 = 50'; SELECT proname, proisstrict FROM pg_proc WHERE oid in ('functest_F_1'::regproc, 'functest_F_2'::regproc, 'functest_F_3'::regproc, 'functest_F_4'::regproc) ORDERBY proname;
ALTER FUNCTION functest_F_1(int) IMMUTABLE; -- unrelated change, no effect ALTER FUNCTION functest_F_2(int) STRICT; ALTER FUNCTION functest_F_3(int) CALLED ONNULL INPUT; SELECT proname, proisstrict FROM pg_proc WHERE oid in ('functest_F_1'::regproc, 'functest_F_2'::regproc, 'functest_F_3'::regproc, 'functest_F_4'::regproc) ORDERBY proname;
-- -- SQL-standard body -- CREATE FUNCTION functest_S_1(a text, b date) RETURNS boolean
LANGUAGE SQL RETURN a = 'abcd'AND b > '2001-01-01'; CREATE FUNCTION functest_S_2(a text[]) RETURNS int RETURN a[1]::int; CREATE FUNCTION functest_S_3() RETURNS boolean RETURNfalse; CREATE FUNCTION functest_S_3a() RETURNS boolean
BEGIN ATOMIC
;;RETURNfalse;;
END;
CREATE FUNCTION functest_S_10(a text, b date) RETURNS boolean
LANGUAGE SQL
BEGIN ATOMIC SELECT a = 'abcd'AND b > '2001-01-01';
END;
CREATE FUNCTION functest_S_13() RETURNS boolean
BEGIN ATOMIC SELECT1; SELECTfalse;
END;
-- check display of function arguments in sub-SELECT CREATETABLE functest1 (i int); CREATE FUNCTION functest_S_16(a int, b int) RETURNS void
LANGUAGE SQL
BEGIN ATOMIC INSERTINTO functest1 SELECT a + $2;
END;
-- error: duplicate function body CREATE FUNCTION functest_S_xxx(x int) RETURNS int
LANGUAGE SQL AS $$ SELECT x * 2 $$ RETURN x * 3;
-- polymorphic arguments not allowed in this form CREATE FUNCTION functest_S_xx(x anyarray) RETURNS anyelement
LANGUAGE SQL RETURN x[1];
-- check reporting of parse-analysis errors CREATE FUNCTION functest_S_xx(x date) RETURNS boolean
LANGUAGE SQL RETURN x > 1;
-- tricky parsing CREATE FUNCTION functest_S_15(x int) RETURNS boolean
LANGUAGE SQL
BEGIN ATOMIC selectcasewhen x % 2 = 0thentrueelsefalse end;
END;
-- test with views CREATETABLE functest3 (a int); INSERTINTO functest3 VALUES (1), (2); CREATE VIEW functestv3 ASSELECT * FROM functest3;
CREATE FUNCTION functest_S_14() RETURNS bigint RETURN (SELECT count(*) FROM functestv3);
SELECT functest_S_14();
DROPTABLE functest3 CASCADE;
-- information_schema tests
CREATE FUNCTION functest_IS_1(a int, b intdefault1, c text default'foo')
RETURNS int
LANGUAGE SQL AS'SELECT $1 + $2';
CREATE FUNCTION functest_IS_2(out a int, b intdefault1)
RETURNS int
LANGUAGE SQL AS'SELECT $1';
CREATE FUNCTION functest_IS_3(a intdefault1, out b int)
RETURNS int
LANGUAGE SQL AS'SELECT $1';
SELECT routine_name, ordinal_position, parameter_name, parameter_default FROM information_schema.parameters JOIN information_schema.routines USING (specific_schema, specific_name) WHERE routine_schema = 'temp_func_test'AND routine_name ~ '^functest_is_' ORDERBY1, 2;
DROP FUNCTION functest_IS_1(int, int, text), functest_IS_2(int), functest_IS_3(int);
-- routine usage views
CREATE FUNCTION functest_IS_4a() RETURNS int LANGUAGE SQLAS'SELECT 1'; CREATE FUNCTION functest_IS_4b(x intDEFAULT functest_IS_4a()) RETURNS int LANGUAGE SQLAS'SELECT x';
CREATE SEQUENCE functest1; CREATE FUNCTION functest_IS_5(x intDEFAULT nextval('functest1'))
RETURNS int
LANGUAGE SQL AS'SELECT x';
CREATE FUNCTION functest_IS_6()
RETURNS int
LANGUAGE SQL RETURN nextval('functest1');
CREATETABLE functest2 (a int, b int);
CREATE FUNCTION functest_IS_7()
RETURNS int
LANGUAGE SQL RETURN (SELECT count(a) FROM functest2);
SELECT r0.routine_name, r1.routine_name FROM information_schema.routine_routine_usage rru JOIN information_schema.routines r0 ON r0.specific_name = rru.specific_name JOIN information_schema.routines r1 ON r1.specific_name = rru.routine_name WHERE r0.routine_schema = 'temp_func_test'AND
r1.routine_schema = 'temp_func_test' ORDERBY1, 2; SELECT routine_name, sequence_name FROM information_schema.routine_sequence_usage WHERE routine_schema = 'temp_func_test' ORDERBY1, 2; SELECT routine_name, table_name, column_name FROM information_schema.routine_column_usage WHERE routine_schema = 'temp_func_test' ORDERBY1, 2; SELECT routine_name, table_name FROM information_schema.routine_table_usage WHERE routine_schema = 'temp_func_test' ORDERBY1, 2;
DROP FUNCTION functest_IS_4a CASCADE; DROP SEQUENCE functest1 CASCADE; DROPTABLE functest2 CASCADE;
-- overload CREATE FUNCTION functest_B_2(bigint) RETURNS bool LANGUAGE 'sql'
IMMUTABLE AS'SELECT $1 > 0';
DROP FUNCTION functest_b_1; DROP FUNCTION functest_b_1; -- error, not found DROP FUNCTION functest_b_2; -- error, ambiguous
-- CREATE OR REPLACE tests
CREATE FUNCTION functest1(a int) RETURNS int LANGUAGE SQLAS'SELECT $1'; CREATEORREPLACE FUNCTION functest1(a int) RETURNS int LANGUAGE SQL WINDOW AS'SELECT $1'; CREATEORREPLACEPROCEDURE functest1(a int) LANGUAGE SQLAS'SELECT $1'; DROP FUNCTION functest1(a int);
-- early shutdown of set-returning functions
CREATE FUNCTION functest_srf0() RETURNS SETOF int
LANGUAGE SQL AS $$ SELECT i FROM generate_series(1, 100) i $$;
SELECT functest_srf0() LIMIT5;
-- inlining of set-returning functions
CREATETABLE functest3 (a int); INSERTINTO functest3 VALUES (1), (2), (3);
CREATE FUNCTION functest_sri1() RETURNS SETOF int
LANGUAGE SQL
STABLE AS' SELECT * FROM functest3; ';
SELECT * FROM functest_sri1(); EXPLAIN (verbose, costs off) SELECT * FROM functest_sri1();
CREATE FUNCTION functest_sri2() RETURNS SETOF int
LANGUAGE SQL
STABLE
BEGIN ATOMIC SELECT * FROM functest3;
END;
SELECT * FROM functest_sri2(); EXPLAIN (verbose, costs off) SELECT * FROM functest_sri2();
DROPTABLE functest3 CASCADE;
-- Check behavior of VOID-returning SQL functions
CREATE FUNCTION voidtest1(a int) RETURNS VOID LANGUAGE SQLAS
$$ SELECT a + 1 $$; SELECT voidtest1(42);
CREATE FUNCTION voidtest2(a int, b int) RETURNS VOID LANGUAGE SQLAS
$$ SELECT voidtest1(a + b) $$; SELECT voidtest2(11,22);
-- currently, we can inline voidtest2 but not voidtest1 EXPLAIN (verbose, costs off) SELECT voidtest2(11,22);
CREATE TEMP TABLE sometable(f1 int);
CREATE FUNCTION voidtest3(a int) RETURNS VOID LANGUAGE SQLAS
$$ INSERTINTO sometable VALUES(a + 1) $$; SELECT voidtest3(17);
CREATE FUNCTION voidtest4(a int) RETURNS VOID LANGUAGE SQLAS
$$ INSERTINTO sometable VALUES(a - 1) RETURNING f1 $$; SELECT voidtest4(39);
TABLE sometable;
CREATE FUNCTION voidtest5(a int) RETURNS SETOF VOID LANGUAGE SQLAS
$$ SELECT generate_series(1, a) $$ STABLE; SELECT * FROM voidtest5(3);
-- DDL within a SQL function can now affect later statements in the function; -- though that doesn't work if check_function_bodies is on.
SET check_function_bodies TO off;
CREATE FUNCTION create_and_insert() RETURNS VOID LANGUAGE sqlAS $$ createtable ddl_test (f1 int); insertinto ddl_test values (1.2);
$$;
SELECT create_and_insert();
TABLE ddl_test;
CREATE FUNCTION alter_and_insert() RETURNS VOID LANGUAGE sqlAS $$ altertable ddl_test altercolumn f1 type numeric; insertinto ddl_test values (1.2);
$$;
SELECT alter_and_insert();
TABLE ddl_test;
RESET check_function_bodies;
-- Regression tests for bugs:
-- Check that arguments that are R/W expanded datums aren't corrupted by -- multiple uses. This test knows that array_append() returns a R/W datum -- and will modify a R/W array input in-place. We use SETOF to prevent -- inlining of the SQL function. CREATE FUNCTION double_append(anyarray, anyelement) RETURNS SETOF anyarray
LANGUAGE SQL IMMUTABLE AS
$$ SELECT array_append($1, $2) || array_append($1, $2) $$;
SELECT double_append(array_append(ARRAY[q1], q2), q3) FROM (VALUES(1,2,3), (4,5,6)) v(q1,q2,q3);
-- Check that we can re-use a SQLFunctionCache after a run-time error.
-- This function will fail with zero-divide at run time (not plan time). CREATE FUNCTION part_hashint4_error(value int4, seed int8) RETURNS int8
LANGUAGE SQL STRICT IMMUTABLE PARALLEL SAFE AS
$$ SELECT value + seed + random()::int/0 $$;
-- Put it into an operator class so that FmgrInfo will be cached in relcache. CREATE OPERATOR CLASS part_test_int4_ops_bad FOR TYPE int4USING hash AS
FUNCTION 2 part_hashint4_error(int4, int8);
CREATETABLE pt(i int) PARTITION BY hash (i part_test_int4_ops_bad); CREATETABLE p1 PARTITION OF pt FORVALUESWITH (modulus 4, remainder 0);
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL AS'SELECT ''not an integer'';';
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL AS'not even SQL';
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL AS'SELECT 1, 2, 3;';
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL AS'SELECT $2;';
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL AS'a', 'b';
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL AS'';
-- make sure empty-body case is handled at execution time, too SET check_function_bodies = off; CREATE FUNCTION test1 (anyelement) RETURNS anyarray LANGUAGE SQL AS''; SELECT test1(0);
RESET check_function_bodies;
-- Cleanup DROPSCHEMA temp_func_test CASCADE; DROP USER regress_unpriv_user;
RESET search_path;
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet am 2026-08-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.