In PostgreSQL, what is the ROW()
function used for?
Specifically what is the difference between
SELECT ROW(t.f1, t.f2, 42) FROM t;
where f1
is of type int
, f2
is of type text
and
CREATE TYPE myrowtype AS (f1 int, f2 text, f3 numeric);
In PostgreSQL, what is the ROW()
function used for?
Specifically what is the difference between
SELECT ROW(t.f1, t.f2, 42) FROM t;
where f1
is of type int
, f2
is of type text
and
CREATE TYPE myrowtype AS (f1 int, f2 text, f3 numeric);
You're asking about the difference between a value and a type.
It's about the same difference than between an object and a class in an OO language.
In the first case you're building a value which could be used in comparisons, in row writing, or to be passed to functions accepting composite parameters.
In the second case you're defining a type that can be used for example in a function or table definition.
Row constructors can be used to build composite values to be stored in a composite-type table column, or to be passed to a function that accepts a composite parameter. Also, it is possible to compare two row values or test a row with IS NULL or IS NOT NULL.
4.2.13. Row Constructors
Example:
ROW(...)
is not a function. It's SQL syntax, more like theARRAY[...]
constructor than like a function.The
ROW
constructor is primarily used to form anonymous records. This can be useful when you need to keep a collection of fields together, but they don't correspond to an existing table type or composite data type.These two are equivalent in PostgreSQL:
in that both create an anonymous record:
The records created by
ROW
can correspond to existing types, for when you're passing composite types to a function, e.g given:you can create a
myrowtype
with:You are confusing levels of abstraction. As other answers already point out,
CREATE TYPE
only registers a (composite / row) type in the system. While aROW
constructor actually returns a row.A row type created with the
ROW
constructor does not preserve column names, which becomes evident when you try to convert the row to JSON.While being at it,
ROW
is just a noise word most of the time. The documentation:The first expression preserves original column names, while the second or third forms do not. Consider this demo:
db<>fiddle here
SQL Fiddle
r3
andj3
demonstrate howROW
is just noise word to clarify things.You can cast the row (record) to a registered row type if number and data types of the elements match the row type - names of input fields are ignored.