You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In PostgreSQL, a reference to a table name (or alias) in a query is effectively a reference to the composite value of the table's current row. For example, if we had a table inventory_item as shown above, we could write:
SELECT c FROM inventory_item c;
In addition, the interpretation of .* can be different in different context:
The composite_value.* syntax results in column expansion of this kind when it appears at the top level of a SELECT output list, a RETURNING list in INSERT/UPDATE/DELETE, a VALUES clause, or a row constructor. In all other contexts (including when nested inside one of those constructs), attaching .* to a composite value does not change the value, since it means “all columns” and so the same composite value is produced again. For example, if somefunc() accepts a composite-valued argument, these queries are the same:
SELECT somefunc(c.*) FROM inventory_item c;
SELECT somefunc(c) FROM inventory_item c;
In practice, builtin functions that accept a composite-valued argument are rare: most are the ones accept any types, for example count.
This results in the following behavior in PostgreSQL:
test=# create table a(a1 int); insert into a values (2), (null), (3);
CREATE TABLE
INSERT 0 3
test=# create table b(b1 int); insert into b values (3), (null);
CREATE TABLE
INSERT 0 2
test=# select count(*), count(b.*), count(b1) from a left join b on a1 = b1;
count | count | count
-------+-------+-------
3 | 1 | 1
(1 row)
test=# select count(*), count(b.*), count(b1) from a left join b on a1 is not distinct from b1;
count | count | count
-------+-------+-------
3 | 2 | 1
(1 row)
test=# select a.*, b.*, a, b, b is null from a left join b on a1 = b1 order by a1;
a1 | b1 | a | b | ?column?
----+----+-----+-----+----------
2 | | (2) | | t
3 | 3 | (3) | (3) | f
| | () | | t
(3 rows)
test=# select a.*, b.*, a, b, b is null from a left join b on a1 is not distinct from b1 order by a1;
a1 | b1 | a | b | ?column?
----+----+-----+-----+----------
2 | | (2) | | t
3 | 3 | (3) | (3) | f
| | () | () | t
(3 rows)
Notes:
count(b.*) is not same as count(*) or count(b1) during outer join.
CockroachDB v22.2.6 and Duckdb v0.7.1 both return 3, 3, 1 for the counts, because their join did not return NULL (but () a struct with a null field) for the composite value b.
https://www.postgresql.org/docs/15/rowtypes.html#ROWTYPES-USAGE
In addition, the interpretation of
.*
can be different in different context:In practice, builtin functions that accept a composite-valued argument are rare: most are the ones accept any types, for example
count
.This results in the following behavior in PostgreSQL:
Notes:
count(b.*)
is not same ascount(*)
orcount(b1)
during outer join.3, 3, 1
for the counts, because their join did not returnNULL
(but()
a struct with a null field) for the composite valueb
.IS NULL
of all-null row/struct #10150Tentatively assigning low priority due to its complexity and rare usage. We do see one query using
count(t.*)
#10838 but it is an inner join.The text was updated successfully, but these errors were encountered: