Hi.
select cast(NULL::text as unknown);
ERROR: failed to find conversion function from unknown to text
I found similar issues in [1] and [2], and both have already been resolved.
Looking at resolveTargetListUnknowns -> coerce_type, it seems it can cope with
transforming a source expression from an Unknown Const to a Text Const. However,
it cannot coerce other Unknown type expressions, such as COERCEVIAIO, to a Text
Const.
It can fail for real table data, not just constant literals, specifically when
you try to cast a text column to an Unknown data type.
While people generally don't do this, it is still possible.
create table t(a text);
select cast(a as unknown) from t;
we don't need to worry about the domain over UNKNOWNOID, since it's not allowed.
seems like coerce_type don't have logic handle targettype as UNKNOWNOID.
in function coerce_type, right above find_coercion_pathway, we can add
if (targetTypeId == UNKNOWNOID)
{
Oid inputBaseTypeId = getBaseType(inputTypeId);
TYPCATEGORY s_typcategory = TypeCategory(inputBaseTypeId);
if (s_typcategory == TYPCATEGORY_STRING)
return node;
}
to solve this issue.
[1]: https://www.postgresql.org/message-id/flat/41E555DA.1060707%40gmail.com
[2]:
https://postgr.es/m/[email protected]
--
jian
https://www.enterprisedb.com/
From a497d39fdd4aca2db190b21153e19093adb3dec7 Mon Sep 17 00:00:00 2001
From: jian he <[email protected]>
Date: Thu, 29 Jan 2026 09:10:02 +0800
Subject: [PATCH v1 1/1] ERROR: failed to find conversion function from
unknown to text
demo:
create table t(a text);
select cast(a as unknown) from t;
discussion: https://postgr.es/m/
---
src/backend/parser/parse_coerce.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c
index 913ca53666f..68ac99e471c 100644
--- a/src/backend/parser/parse_coerce.c
+++ b/src/backend/parser/parse_coerce.c
@@ -411,6 +411,16 @@ coerce_type(ParseState *pstate, Node *node,
}
return result;
}
+
+ if (targetTypeId == UNKNOWNOID)
+ {
+ Oid inputBaseTypeId = getBaseType(inputTypeId);
+ TYPCATEGORY s_typcategory = TypeCategory(inputBaseTypeId);
+
+ if (s_typcategory == TYPCATEGORY_STRING)
+ return node;
+ }
+
pathtype = find_coercion_pathway(targetTypeId, inputTypeId, ccontext,
&funcId);
if (pathtype != COERCION_PATH_NONE)
--
2.34.1