Skip to content

Instantly share code, notes, and snippets.

@diraneyya
Last active May 5, 2025 08:14
Show Gist options
  • Save diraneyya/94558c71699e3c6ddc96d2c31c587486 to your computer and use it in GitHub Desktop.
Save diraneyya/94558c71699e3c6ddc96d2c31c587486 to your computer and use it in GitHub Desktop.
`coalesce_equal(...)` is a PostgreSQL function that is similar to `coalesce`, but requires that all non-null arguments be equal for it to return the identical value, when not equal or all arguments are null, it returns null.
create or replace function coalesce_equal(variadic args anycompatiblearray)
returns anycompatible language sql immutable as $$
with all_args(arg) as (select unnest(args)), dist_args(count) as (
select count(distinct arg) filter (where arg is not null) from all_args
)
select arg from all_args, dist_args
where arg is not null and count = 1
limit 1
$$;
-- tests
select coalesce_equal('f', null, 'f', null, 'ff', 'f'); -- gives NULL
select coalesce_equal('f', null, 'f', null, 'f', 'f'); -- gives 'f'
select coalesce_equal(6, null, 7, null, 6, null); -- gives NULL
select coalesce_equal(6, null, 6, null, 6, null); -- gives 6
select coalesce_equal(null, null, null, null, null, null); -- gives NULL
select coalesce_equal('f', null, 6, null, false, 'f'); -- gives ERROR 😱
@diraneyya
Copy link
Author

Currently, this function returns an error when passed values that cannot be promoted to a common type. This is a limitation of PL/PGSQL and the pseudo types in PostgreSQL. Can it be overcome? I think: Yes. It is possible to create a variant that will accept any number of arguments which can be of any type, regardless of whether the types passed are compatible, or not.

... But this would require writing this function using the C programming language, using variadic "any" (in this case: "any" is a type and a keyword in SQL which is why it needs to be double quoted).

Do you want me to write this function in C and create a tutorial on how to compile it and dynamically load it in PostgreSQL?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment