This legal(!) CASE
construct returns a JSON datatype:
SELECT CASE WHEN true THEN to_json(1) ELSE to_json('hello') END;
but:
ERROR: could not determine polymorphic type because input has type "unknown"
It is not "polymorphic", it is JSON.
... So, as bad workaround (lost number/string JSON representations),
SELECT to_json(CASE WHEN true THEN 1::text ELSE 'hello' END);
Is there a better way to do this SQL-to-JSON cast?
Do it the other way round:
SELECT CASE WHEN true THEN to_json(1) ELSE to_json(text 'hello') END;
Declare 'hello' as type text
.
This way you retain 1
as number and 'hello'
as string.
The explicit cast 'hello'::text
is equivalent.
The reason is the Postgres type system. An unquoted 1
is a legal numeric constant and defaults to the Postgres data type integer
. But 'hello'
(with single quotes) is a string literal that starts out as type unknown
. The function to_json()
is polymorphic, its input parameter is defined as ANYELEMENT
. The output depends on the input data type. And it does not know what to do with data type unknown
. Hence the error message.
The result data type is json
in either case (which is a regular Postgres data type), but that is orthogonal to the problem.
Related: