Add error_on_null(), checking if the input is the null value
authorMichael Paquier <michael@paquier.xyz>
Wed, 22 Oct 2025 00:55:17 +0000 (09:55 +0900)
committerMichael Paquier <michael@paquier.xyz>
Wed, 22 Oct 2025 00:55:17 +0000 (09:55 +0900)
This polymorphic function produces an error if the input value is
detected as being the null value; otherwise it returns the input value
unchanged.

This function can for example become handy in SQL function bodies, to
enforce that exactly one row was returned.

Author: Joel Jacobson <joel@compiler.org>
Reviewed-by: Vik Fearing <vik@postgresfriends.org>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/ece8c6d1-2ab1-45d5-ba12-8dec96fc8886@app.fastmail.com
Discussion: https://postgr.es/m/de94808d-ed58-4536-9e28-e79b09a534c7@app.fastmail.com

doc/src/sgml/func/func-comparison.sgml
src/backend/utils/adt/misc.c
src/include/catalog/pg_proc.dat
src/test/regress/expected/misc_functions.out
src/test/regress/sql/misc_functions.sql

index c1205983f8bac33802b640275677267afb01da13..ecb1d89463a1eefd3d9797fd432f43e60c0fd2b1 100644 (file)
@@ -599,6 +599,28 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in
      </thead>
 
      <tbody>
+      <row>
+       <entry role="func_table_entry"><para role="func_signature">
+        <indexterm>
+         <primary>error_on_null</primary>
+        </indexterm>
+        <function>error_on_null</function> ( <type>anyelement</type> )
+        <returnvalue>anyelement</returnvalue>
+       </para>
+       <para>
+        Checks if the input is the null value, generating an error if so;
+        otherwise, returns the input.
+       </para>
+       <para>
+        <literal>error_on_null(42)</literal>
+        <returnvalue>42</returnvalue>
+       </para>
+       <para>
+        <literal>error_on_null(row(null,null))</literal>
+        <returnvalue>(,)</returnvalue>
+       </para></entry>
+      </row>
+
       <row>
        <entry role="func_table_entry"><para role="func_signature">
         <indexterm>
index 7cb7716e58b49deddf267addb63e72252a2375ab..fa1cb67502735b25e3248ae28e5e71554d3aa159 100644 (file)
@@ -186,6 +186,20 @@ pg_num_nonnulls(PG_FUNCTION_ARGS)
    PG_RETURN_INT32(nargs - nulls);
 }
 
+/*
+ * error_on_null()
+ * Check if the input is the NULL value
+ */
+Datum
+pg_error_on_null(PG_FUNCTION_ARGS)
+{
+   if (PG_ARGISNULL(0))
+       ereport(ERROR,
+               (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
+                errmsg("null value not allowed")));
+
+   PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
 
 /*
  * current_database()
index b51d2b17379f1f894b503d41856aab9c0873bd86..eecb43ec6f0fb6b57412bd9f0430878f5a255495 100644 (file)
 { oid => '6292', descr => 'aggregate transition function',
   proname => 'any_value_transfn', prorettype => 'anyelement',
   proargtypes => 'anyelement anyelement', prosrc => 'any_value_transfn' },
+{ oid => '8488', descr => 'check if input is the null value',
+  proname => 'error_on_null', proisstrict => 'f', prorettype => 'anyelement',
+  proargtypes => 'anyelement', prosrc => 'pg_error_on_null' },
 
 { oid => '6321', descr => 'list of available WAL summary files',
   proname => 'pg_available_wal_summaries', prorows => '100', proretset => 't',
index 36164a99c83208179ec4440af1bb9647dffcf4bf..e76e28b95ce68f9bb0c36a711662a14ef44a58fc 100644 (file)
@@ -177,6 +177,37 @@ ERROR:  function num_nulls() does not exist
 LINE 1: SELECT num_nulls();
                ^
 DETAIL:  No function of that name accepts the given number of arguments.
+--
+-- error_on_null()
+--
+SELECT error_on_null(1);
+ error_on_null 
+---------------
+             1
+(1 row)
+
+SELECT error_on_null(NULL::int);
+ERROR:  null value not allowed
+SELECT error_on_null(NULL::int[]);
+ERROR:  null value not allowed
+SELECT error_on_null('{1,2,NULL,3}'::int[]);
+ error_on_null 
+---------------
+ {1,2,NULL,3}
+(1 row)
+
+SELECT error_on_null(ROW(1,NULL::int));
+ error_on_null 
+---------------
+ (1,)
+(1 row)
+
+SELECT error_on_null(ROW(NULL,NULL));
+ error_on_null 
+---------------
+ (,)
+(1 row)
+
 --
 -- canonicalize_path()
 --
index 23792c4132a10e62b93084f3d48b970c97354714..220472d5ad19e7588fc9b04d7bfbd9bfcd859805 100644 (file)
@@ -77,6 +77,17 @@ SELECT num_nulls(VARIADIC '{}'::int[]);
 SELECT num_nonnulls();
 SELECT num_nulls();
 
+--
+-- error_on_null()
+--
+
+SELECT error_on_null(1);
+SELECT error_on_null(NULL::int);
+SELECT error_on_null(NULL::int[]);
+SELECT error_on_null('{1,2,NULL,3}'::int[]);
+SELECT error_on_null(ROW(1,NULL::int));
+SELECT error_on_null(ROW(NULL,NULL));
+
 --
 -- canonicalize_path()
 --