1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-02 09:02:37 +03:00

Add num_nulls() and num_nonnulls() to count NULL arguments.

An example use-case is "CHECK(num_nonnulls(a,b,c) = 1)" to assert that
exactly one of a,b,c isn't NULL.  The functions are variadic, so they
can also be pressed into service to count the number of null or nonnull
elements in an array.

Marko Tiikkaja, reviewed by Pavel Stehule
This commit is contained in:
Tom Lane
2016-02-04 23:03:10 -05:00
parent d0cd7bda97
commit 6819514fca
9 changed files with 347 additions and 8 deletions

View File

@ -0,0 +1,135 @@
--
-- num_nulls()
--
SELECT num_nonnulls(NULL);
num_nonnulls
--------------
0
(1 row)
SELECT num_nonnulls('1');
num_nonnulls
--------------
1
(1 row)
SELECT num_nonnulls(NULL::text);
num_nonnulls
--------------
0
(1 row)
SELECT num_nonnulls(NULL::text, NULL::int);
num_nonnulls
--------------
0
(1 row)
SELECT num_nonnulls(1, 2, NULL::text, NULL::point, '', int8 '9', 1.0 / NULL);
num_nonnulls
--------------
4
(1 row)
SELECT num_nonnulls(VARIADIC '{1,2,NULL,3}'::int[]);
num_nonnulls
--------------
3
(1 row)
SELECT num_nonnulls(VARIADIC '{"1","2","3","4"}'::text[]);
num_nonnulls
--------------
4
(1 row)
SELECT num_nonnulls(VARIADIC ARRAY(SELECT CASE WHEN i <> 40 THEN i END FROM generate_series(1, 100) i));
num_nonnulls
--------------
99
(1 row)
SELECT num_nulls(NULL);
num_nulls
-----------
1
(1 row)
SELECT num_nulls('1');
num_nulls
-----------
0
(1 row)
SELECT num_nulls(NULL::text);
num_nulls
-----------
1
(1 row)
SELECT num_nulls(NULL::text, NULL::int);
num_nulls
-----------
2
(1 row)
SELECT num_nulls(1, 2, NULL::text, NULL::point, '', int8 '9', 1.0 / NULL);
num_nulls
-----------
3
(1 row)
SELECT num_nulls(VARIADIC '{1,2,NULL,3}'::int[]);
num_nulls
-----------
1
(1 row)
SELECT num_nulls(VARIADIC '{"1","2","3","4"}'::text[]);
num_nulls
-----------
0
(1 row)
SELECT num_nulls(VARIADIC ARRAY(SELECT CASE WHEN i <> 40 THEN i END FROM generate_series(1, 100) i));
num_nulls
-----------
1
(1 row)
-- special cases
SELECT num_nonnulls(VARIADIC NULL::text[]);
num_nonnulls
--------------
(1 row)
SELECT num_nonnulls(VARIADIC '{}'::int[]);
num_nonnulls
--------------
0
(1 row)
SELECT num_nulls(VARIADIC NULL::text[]);
num_nulls
-----------
(1 row)
SELECT num_nulls(VARIADIC '{}'::int[]);
num_nulls
-----------
0
(1 row)
-- should fail, one or more arguments is required
SELECT num_nonnulls();
ERROR: function num_nonnulls() does not exist
LINE 1: SELECT num_nonnulls();
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
SELECT num_nulls();
ERROR: function num_nulls() does not exist
LINE 1: SELECT num_nulls();
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.

View File

@ -89,7 +89,7 @@ test: brin gin gist spgist privileges security_label collate matview lock replic
# ----------
# Another group of parallel tests
# ----------
test: alter_generic alter_operator misc psql async dbsize
test: alter_generic alter_operator misc psql async dbsize misc_functions
# rules cannot run concurrently with any test that creates a view
test: rules

View File

@ -119,6 +119,7 @@ test: misc
test: psql
test: async
test: dbsize
test: misc_functions
test: rules
test: select_views
test: portals_p2

View File

@ -0,0 +1,31 @@
--
-- num_nulls()
--
SELECT num_nonnulls(NULL);
SELECT num_nonnulls('1');
SELECT num_nonnulls(NULL::text);
SELECT num_nonnulls(NULL::text, NULL::int);
SELECT num_nonnulls(1, 2, NULL::text, NULL::point, '', int8 '9', 1.0 / NULL);
SELECT num_nonnulls(VARIADIC '{1,2,NULL,3}'::int[]);
SELECT num_nonnulls(VARIADIC '{"1","2","3","4"}'::text[]);
SELECT num_nonnulls(VARIADIC ARRAY(SELECT CASE WHEN i <> 40 THEN i END FROM generate_series(1, 100) i));
SELECT num_nulls(NULL);
SELECT num_nulls('1');
SELECT num_nulls(NULL::text);
SELECT num_nulls(NULL::text, NULL::int);
SELECT num_nulls(1, 2, NULL::text, NULL::point, '', int8 '9', 1.0 / NULL);
SELECT num_nulls(VARIADIC '{1,2,NULL,3}'::int[]);
SELECT num_nulls(VARIADIC '{"1","2","3","4"}'::text[]);
SELECT num_nulls(VARIADIC ARRAY(SELECT CASE WHEN i <> 40 THEN i END FROM generate_series(1, 100) i));
-- special cases
SELECT num_nonnulls(VARIADIC NULL::text[]);
SELECT num_nonnulls(VARIADIC '{}'::int[]);
SELECT num_nulls(VARIADIC NULL::text[]);
SELECT num_nulls(VARIADIC '{}'::int[]);
-- should fail, one or more arguments is required
SELECT num_nonnulls();
SELECT num_nulls();