From 5f21f5292c0856536ac0724974a8bc6b296b9ef6 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Wed, 5 Apr 2017 12:17:03 -0400 Subject: [PATCH] Mark immutable functions in information schema as parallel safe Also add opr_sanity check that all preloaded immutable functions are parallel safe. (Per discussion, this does not necessarily have to be true for all possible such functions, but deviations would be unlikely enough that maintaining such a test is reasonable.) Reported-by: David Rowley Reviewed-by: Robert Haas Reviewed-by: Tom Lane --- src/backend/catalog/information_schema.sql | 13 +++++++++++-- src/include/catalog/catversion.h | 2 +- src/test/regress/expected/opr_sanity.out | 8 ++++++++ src/test/regress/sql/opr_sanity.sql | 5 +++++ 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/backend/catalog/information_schema.sql b/src/backend/catalog/information_schema.sql index 2185734b48..cbcd6cfbc1 100644 --- a/src/backend/catalog/information_schema.sql +++ b/src/backend/catalog/information_schema.sql @@ -42,14 +42,14 @@ SET search_path TO information_schema; /* Expand any 1-D array into a set with integers 1..N */ CREATE FUNCTION _pg_expandarray(IN anyarray, OUT x anyelement, OUT n int) RETURNS SETOF RECORD - LANGUAGE sql STRICT IMMUTABLE + LANGUAGE sql STRICT IMMUTABLE PARALLEL SAFE AS 'select $1[s], s - pg_catalog.array_lower($1,1) + 1 from pg_catalog.generate_series(pg_catalog.array_lower($1,1), pg_catalog.array_upper($1,1), 1) as g(s)'; CREATE FUNCTION _pg_keysequal(smallint[], smallint[]) RETURNS boolean - LANGUAGE sql IMMUTABLE -- intentionally not STRICT, to allow inlining + LANGUAGE sql IMMUTABLE PARALLEL SAFE -- intentionally not STRICT, to allow inlining AS 'select $1 operator(pg_catalog.<@) $2 and $2 operator(pg_catalog.<@) $1'; /* Given an index's OID and an underlying-table column number, return the @@ -66,6 +66,7 @@ $$; CREATE FUNCTION _pg_truetypid(pg_attribute, pg_type) RETURNS oid LANGUAGE sql IMMUTABLE + PARALLEL SAFE RETURNS NULL ON NULL INPUT AS $$SELECT CASE WHEN $2.typtype = 'd' THEN $2.typbasetype ELSE $1.atttypid END$$; @@ -73,6 +74,7 @@ $$SELECT CASE WHEN $2.typtype = 'd' THEN $2.typbasetype ELSE $1.atttypid END$$; CREATE FUNCTION _pg_truetypmod(pg_attribute, pg_type) RETURNS int4 LANGUAGE sql IMMUTABLE + PARALLEL SAFE RETURNS NULL ON NULL INPUT AS $$SELECT CASE WHEN $2.typtype = 'd' THEN $2.typtypmod ELSE $1.atttypmod END$$; @@ -82,6 +84,7 @@ $$SELECT CASE WHEN $2.typtype = 'd' THEN $2.typtypmod ELSE $1.atttypmod END$$; CREATE FUNCTION _pg_char_max_length(typid oid, typmod int4) RETURNS integer LANGUAGE sql IMMUTABLE + PARALLEL SAFE RETURNS NULL ON NULL INPUT AS $$SELECT @@ -97,6 +100,7 @@ $$SELECT CREATE FUNCTION _pg_char_octet_length(typid oid, typmod int4) RETURNS integer LANGUAGE sql IMMUTABLE + PARALLEL SAFE RETURNS NULL ON NULL INPUT AS $$SELECT @@ -112,6 +116,7 @@ $$SELECT CREATE FUNCTION _pg_numeric_precision(typid oid, typmod int4) RETURNS integer LANGUAGE sql IMMUTABLE + PARALLEL SAFE RETURNS NULL ON NULL INPUT AS $$SELECT @@ -132,6 +137,7 @@ $$SELECT CREATE FUNCTION _pg_numeric_precision_radix(typid oid, typmod int4) RETURNS integer LANGUAGE sql IMMUTABLE + PARALLEL SAFE RETURNS NULL ON NULL INPUT AS $$SELECT @@ -143,6 +149,7 @@ $$SELECT CREATE FUNCTION _pg_numeric_scale(typid oid, typmod int4) RETURNS integer LANGUAGE sql IMMUTABLE + PARALLEL SAFE RETURNS NULL ON NULL INPUT AS $$SELECT @@ -158,6 +165,7 @@ $$SELECT CREATE FUNCTION _pg_datetime_precision(typid oid, typmod int4) RETURNS integer LANGUAGE sql IMMUTABLE + PARALLEL SAFE RETURNS NULL ON NULL INPUT AS $$SELECT @@ -173,6 +181,7 @@ $$SELECT CREATE FUNCTION _pg_interval_type(typid oid, mod int4) RETURNS text LANGUAGE sql IMMUTABLE + PARALLEL SAFE RETURNS NULL ON NULL INPUT AS $$SELECT diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 4dd571a2e2..0f118dfffb 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 201704061 +#define CATALOG_VERSION_NO 201704062 #endif diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out index d23f8764ba..ad52735207 100644 --- a/src/test/regress/expected/opr_sanity.out +++ b/src/test/regress/expected/opr_sanity.out @@ -733,6 +733,14 @@ order by 1; lowrite | 955 (13 rows) +-- Check that all immutable functions are marked parallel safe +SELECT p1.oid, p1.proname +FROM pg_proc AS p1 +WHERE provolatile = 'i' AND proparallel = 'u'; + oid | proname +-----+--------- +(0 rows) + -- **************** pg_cast **************** -- Catch bogus values in pg_cast columns (other than cases detected by -- oidjoins test). diff --git a/src/test/regress/sql/opr_sanity.sql b/src/test/regress/sql/opr_sanity.sql index bb9b6bb3b8..123e3bb5c1 100644 --- a/src/test/regress/sql/opr_sanity.sql +++ b/src/test/regress/sql/opr_sanity.sql @@ -381,6 +381,11 @@ and pronamespace = (select oid from pg_catalog.pg_namespace where nspname = 'pg_catalog') order by 1; +-- Check that all immutable functions are marked parallel safe +SELECT p1.oid, p1.proname +FROM pg_proc AS p1 +WHERE provolatile = 'i' AND proparallel = 'u'; + -- **************** pg_cast **************** -- 2.40.0