Having following setup in Postgres 9.3:
CREATE TABLE t (id INTEGER);
INSERT INTO t VALUES (1), (2), (3);
I'm aggregating these values into array (don't ask why, the actual setup is very complex, so I simply need this approach).
Now I need to check whether some integer belongs to the array. Tried this:
SELECT 1=ANY((SELECT array_agg(id) FROM t))
Got error:
ERROR: operator does not exist: integer = integer[]
LINE 1: SELECT 1=ANY((SELECT array_agg(id) FROM t))
^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
After some experimentation found a working solution:
SELECT 1=ANY((SELECT array_agg(id) FROM t)::integer[])
Why does postgres require me to cast integer[] to integer[]? Doesn't make sense.
The result of the inner select ( SELECT array_agg(id) FROM t
) is not a integer[]
it is a resultset containing a single row containing an integer[]
.
You can expose what's going on in two ways.
If you try
SELECT 1=ANY((SELECT array_agg(id) FROM t)::text[]);
the error message is ERROR: operator does not exist: integer = text
Note that the error message does not refer to a text[]
but to a text
.
This is because the equality is comparing the left argument to each element of the right argument. Hence, in your original query, it is a resultset of integer[]
, and it is trying to compare the 1
to each (you only have one) integer[]
.
Another way to see this is to reflect on
select count(*) from (select array_agg(id) from t) as z
This embeds your original subquery as z
-- and it returns 1 row. If you try to cast z
to an integer[]
it won't work -- because the FROM clause needs a resultset, not an integer array.
However, one can cast a resultset containing one row with one column, to an instance of the type of that singleton (in this case, an integer[]
). This disambiguates between "I'm looking in any of the rows of this subquery" to "I'm looking in the array of the single row/column of this subquery".
Hence, the requirement to explicitly cast.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.