Jangan gunakan CREATE TYPE untuk mengembalikan hasil polimorfik. Gunakan dan salah gunakan tipe RECORD sebagai gantinya. Lihat ini:
CREATE FUNCTION test_ret(a TEXT, b TEXT) RETURNS RECORD AS $$
DECLARE
ret RECORD;
BEGIN
-- Arbitrary expression to change the first parameter
IF LENGTH(a) < LENGTH(b) THEN
SELECT TRUE, a || b, 'a shorter than b' INTO ret;
ELSE
SELECT FALSE, b || a INTO ret;
END IF;
RETURN ret;
END;$$ LANGUAGE plpgsql;
Perhatikan fakta bahwa itu secara opsional dapat mengembalikan dua atau tiga kolom tergantung pada input.
test=> SELECT test_ret('foo','barbaz');
test_ret
----------------------------------
(t,foobarbaz,"a shorter than b")
(1 row)
test=> SELECT test_ret('barbaz','foo');
test_ret
----------------------------------
(f,foobarbaz)
(1 row)
Ini benar-benar merusak kode, jadi gunakan jumlah kolom yang konsisten, tetapi sangat berguna untuk mengembalikan pesan kesalahan opsional dengan parameter pertama yang mengembalikan keberhasilan operasi. Ditulis ulang menggunakan jumlah kolom yang konsisten:
CREATE FUNCTION test_ret(a TEXT, b TEXT) RETURNS RECORD AS $$
DECLARE
ret RECORD;
BEGIN
-- Note the CASTING being done for the 2nd and 3rd elements of the RECORD
IF LENGTH(a) < LENGTH(b) THEN
ret := (TRUE, (a || b)::TEXT, 'a shorter than b'::TEXT);
ELSE
ret := (FALSE, (b || a)::TEXT, NULL::TEXT);
END IF;
RETURN ret;
END;$$ LANGUAGE plpgsql;
Hampir kepanasan epik:
test=> SELECT test_ret('foobar','bar');
test_ret
----------------
(f,barfoobar,)
(1 row)
test=> SELECT test_ret('foo','barbaz');
test_ret
----------------------------------
(t,foobarbaz,"a shorter than b")
(1 row)
Tetapi bagaimana Anda membaginya menjadi beberapa baris sehingga lapisan ORM pilihan Anda dapat mengonversi nilai ke dalam tipe data asli bahasa pilihan Anda? Panasnya:
test=> SELECT a, b, c FROM test_ret('foo','barbaz') AS (a BOOL, b TEXT, c TEXT);
a | b | c
---+-----------+------------------
t | foobarbaz | a shorter than b
(1 row)
test=> SELECT a, b, c FROM test_ret('foobar','bar') AS (a BOOL, b TEXT, c TEXT);
a | b | c
---+-----------+---
f | barfoobar |
(1 row)
Ini adalah salah satu fitur paling keren dan paling jarang digunakan di PostgreSQL. Tolong sebarkan beritanya.