PostgreSQL Error 2200G: Most Specific Type Mismatch
PostgreSQL error code 2200G (most_specific_type_mismatch) is a SQL-standard data exception that occurs when a value's type does not match the most specific (most derived) type expected in a context involving type hierarchies, XML schema types, or user-defined structured types. It most commonly appears when working with composite types, domain hierarchies, or XML processing functions where type inheritance or derivation is in play. While relatively rare in everyday CRUD operations, it can be a significant pain point in enterprise applications with complex type systems.
Top 3 Causes and Fixes
1. Composite or Domain Type Hierarchy Mismatch
When a function expects a specific domain or composite type but receives a parent/base type, PostgreSQL raises 2200G. Always cast explicitly to the most specific required type.
-- Define types
CREATE TYPE base_info AS (name TEXT, value INTEGER);
CREATE DOMAIN specific_info AS base_info;
-- Function expecting the specific domain type
CREATE OR REPLACE FUNCTION handle_info(data specific_info)
RETURNS TEXT AS $$
BEGIN
RETURN (data).name || ': ' || (data).value;
END;
$$ LANGUAGE plpgsql;
-- WRONG: passing base type causes mismatch
-- SELECT handle_info(ROW('test', 42)::base_info);
-- CORRECT: explicit cast to the most specific type
SELECT handle_info(ROW('test', 42)::specific_info);
2. XML Type Processing Mismatch
Using XML functions like XMLTABLE or XMLCAST without explicitly matching the expected schema type can trigger this error. Always declare column types explicitly.
-- Correct: explicitly typed columns in XMLTABLE
SELECT *
FROM XMLTABLE(
'//product'
PASSING XMLPARSE(DOCUMENT '
<products>
<product>
<id>1</id>
<price>29.99</price>
</product>
</products>
')
COLUMNS
product_id INTEGER PATH 'id',
price NUMERIC PATH 'price'
);
-- Explicit XMLCAST to resolve type ambiguity
SELECT XMLCAST(
XMLQUERY('//price/text()'
PASSING XMLPARSE(DOCUMENT '<data><price>29.99</price></data>')
RETURNING CONTENT
) AS NUMERIC
);
3. Function Overload Resolution Failure
When multiple overloaded functions exist and PostgreSQL cannot determine the most specific type match, this error (or a related one) is raised. Use explicit casting to force the correct overload.
-- Two overloaded versions
CREATE OR REPLACE FUNCTION process(val INTEGER)
RETURNS TEXT AS $$ BEGIN RETURN 'int:' || val; END; $$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION process(val NUMERIC)
RETURNS TEXT AS $$ BEGIN RETURN 'numeric:' || val; END; $$ LANGUAGE plpgsql;
-- Ambiguous call
-- SELECT process(100); -- may cause issues
-- Explicit cast to select the correct overload
SELECT process(100::INTEGER);
SELECT process(100::NUMERIC);
-- Inspect available overloads for debugging
SELECT proname, pg_get_function_identity_arguments(oid) AS signature
FROM pg_proc
WHERE proname = 'process'
AND pronamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'public');
Quick Fix Checklist
-
Always use explicit casting (
::typeorCAST(val AS type)) when working with domain types or overloaded functions. -
Verify type hierarchies using
pg_typeandpg_castsystem catalogs before deploying complex type-dependent code. -
Use
pg_typeof()during debugging to confirm the actual runtime type of any expression.
-- Helpful debugging queries
SELECT pg_typeof(ROW('test', 42)::specific_info);
SELECT castsource::regtype, casttarget::regtype, castcontext
FROM pg_cast
WHERE castsource = 'base_info'::regtype;
Prevention Tips
Enforce explicit typing in code reviews: Adopt a team convention requiring explicit casts in all SQL involving custom or domain types. Integrate a SQL linter (e.g.,
sqlfluff) into your CI pipeline to catch implicit type reliance early.Audit your type catalog regularly: Run periodic checks against
pg_typeto map out your type hierarchies. Undocumented or forgotten domain chains are a common root cause of 2200G surfacing unexpectedly after schema changes or PostgreSQL version upgrades.
Related Errors
| Code | Name | Notes |
|---|---|---|
22000 |
data_exception |
Parent category of 2200G |
42804 |
datatype_mismatch |
Similar but occurs at DDL/DML level |
42883 |
undefined_function |
Often co-occurs with overload resolution failures |
2200M |
invalid_xml_document |
Related XML processing error |
📖 Want a more detailed guide?
Check out the full in-depth version (Korean) on oraerror.com — includes detailed analysis, additional SQL examples, and prevention tips.
Top comments (0)