>From 66d5791deb2ac0434e3e93eded628cd23e3edc33 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
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 immutable functions are parallel
safe.
---
 src/backend/catalog/information_schema.sql | 13 +++++++++++--
 src/test/regress/expected/opr_sanity.out   |  8 ++++++++
 src/test/regress/sql/opr_sanity.sql        |  5 +++++
 3 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/src/backend/catalog/information_schema.sql b/src/backend/catalog/information_schema.sql
index fa2a88fc5c..c8b2bef813 100644
--- a/src/backend/catalog/information_schema.sql
+++ b/src/backend/catalog/information_schema.sql
@@ -42,14 +42,14 @@ CREATE SCHEMA 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_index_position(oid, smallint) RETURNS int
 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 @@ CREATE FUNCTION _pg_truetypid(pg_attribute, pg_type) RETURNS oid
 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 @@ CREATE FUNCTION _pg_truetypmod(pg_attribute, pg_type) RETURNS int4
 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 @@ CREATE FUNCTION _pg_char_max_length(typid oid, typmod int4) RETURNS integer
 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 @@ CREATE FUNCTION _pg_char_octet_length(typid oid, typmod int4) RETURNS integer
 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 @@ CREATE FUNCTION _pg_numeric_precision(typid oid, typmod int4) RETURNS integer
 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 @@ CREATE FUNCTION _pg_numeric_precision_radix(typid oid, typmod int4) RETURNS inte
 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 @@ CREATE FUNCTION _pg_numeric_scale(typid oid, typmod int4) RETURNS integer
 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 @@ CREATE FUNCTION _pg_datetime_precision(typid oid, typmod int4) RETURNS integer
 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/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out
index 262036ac4f..1da5598dc4 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 @@
                     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.12.2

