Du förvirrar abstraktionsnivåer. Som andra svar redan påpekar, CREATE TYPE registrerar endast en (sammansatt/rad) typ i systemet. Medan en ROW konstruktorn returnerar faktiskt en rad.
En radtyp skapad med ROW konstruktorn bevarar inte kolumnnamn, vilket blir uppenbart när du försöker konvertera raden till JSON.
Medan du håller på, ROW är bara ett brusord för det mesta. Dokumentationen:
Demo:
SELECT t AS r1, row_to_json(t) AS j1
, ROW(1, 'x', NUMERIC '42.1') AS r2, row_to_json(ROW(1, 'x', NUMERIC '42.1')) AS j2
, (1, 'x', NUMERIC '42.1') AS r3, row_to_json( (1, 'x', NUMERIC '42.1')) AS j3
, (1, 'x', '42.1')::myrowtype AS r4, row_to_json((1, 'x', '42.1')::myrowtype) AS j4
FROM (SELECT 1, 'x', NUMERIC '42.1') t;
r1 och j1 bevara ursprungliga kolumnnamn.r2 och j2 gör inte.r3 och j3 är samma; för att visa hur ROW är bara brus.r4 och j4 bär kolumnnamnen av den registrerade typen.
Du kan kasta raden (rekord) till en registrerad radtyp om nummer och datatyper av elementen matchar radtypen - namn inmatningsfält ignoreras.