SET client_min_messages = WARNING; CREATE OR REPLACE FUNCTION null_count( VARIADIC argument anyarray ) RETURNS bigint LANGUAGE sql IMMUTABLE AS $body$ SELECT sum( CASE WHEN a IS NULL THEN 1 ELSE 0 END ) FROM unnest( $1 ) a $body$; CREATE OR REPLACE FUNCTION null_count( argument json ) RETURNS bigint LANGUAGE sql IMMUTABLE AS $body$ SELECT count(*) FROM json_each_text( $1 ) a WHERE value IS NULL $body$; CREATE OR REPLACE FUNCTION null_count_trigger( ) RETURNS trigger LANGUAGE plpgsql IMMUTABLE AS $body$ DECLARE c_msg CONSTANT text := coalesce( nullif( TG_ARGV[1], 'null' ) , format( '%s must contain %s NULL fields', TG_RELID::regclass, TG_ARGV[0] ) ); BEGIN IF TG_NARGS NOT BETWEEN 1 AND 2 THEN RAISE '% usage: number of NULL columns[, error message]', TG_NAME; END IF; -- Casing intentional for cut/paste/replace/ IF nullif(TG_ARGV[0], 'null') IS null THEN RAISE '%: first argument must not be null', TG_NAME; END IF; IF null_count( row_to_json(NEW) ) <> TG_ARGV[0]::int THEN RAISE '%', c_msg; END IF; RETURN NEW; END $body$; CREATE OR REPLACE FUNCTION not_null_count( VARIADIC argument anyarray ) RETURNS bigint LANGUAGE sql IMMUTABLE AS $body$ SELECT sum( CASE WHEN a IS NOT NULL THEN 1 ELSE 0 END ) FROM unnest( $1 ) a $body$; CREATE OR REPLACE FUNCTION not_null_count( argument json ) RETURNS bigint LANGUAGE sql IMMUTABLE AS $body$ SELECT count(*) FROM json_each_text( $1 ) a WHERE value IS NOT NULL $body$; CREATE OR REPLACE FUNCTION not_null_count_trigger( ) RETURNS trigger LANGUAGE plpgsql IMMUTABLE AS $body$ DECLARE c_msg CONSTANT text := coalesce( nullif( TG_ARGV[1], 'null' ) , format( '%s must contain %s NOT NULL fields', TG_RELID::regclass, TG_ARGV[0] ) ); BEGIN IF TG_NARGS NOT BETWEEN 1 AND 2 THEN RAISE '% usage: number of NOT NULL columns[, error message]', TG_NAME; END IF; -- Casing intentional for cut/paste/replace/ IF nullif(TG_ARGV[0], 'null') IS null THEN RAISE '%: first argument must not be null', TG_NAME; END IF; IF not_null_count( row_to_json(NEW) ) <> TG_ARGV[0]::int THEN RAISE '%', c_msg; END IF; RETURN NEW; END $body$; -- vi: expandtab sw=2 ts=2