简体   繁体   中英

Unneccesary postgres array casting required?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM