Error message
For the record, your superficial error:
ERROR: could not find array type for data type text[]
.. would go away with an explicit cast. Like:
...
WHERE column_name = any('{{"one", "two"}, {"one", "more"}, {"two", "five"}}'::varchar[])
But that would not solve the underlying problem:
ERROR: operator does not exist: character varying[] = character varying
Explanation
Postgres support for multi-dimensional arrays can be confusing. In fact, varchar(255)[]
resolves to the exact same data type as varchar(255)[][]
internally.
The element type of each of these array values is varchar
(not varchar[]
). The ANY
construct effectively ignores array dimensions.
The manual:
Array comparisons compare the array contents element-by-element
Solution
To achieve what you want, you need to unnest 2D-arrays to 1D-arrays. Create this function once per database:
CREATE OR REPLACE FUNCTION unnest_2d_1d(ANYARRAY, OUT a ANYARRAY)
RETURNS SETOF ANYARRAY AS
$func$
BEGIN
FOREACH a SLICE 1 IN ARRAY $1 LOOP
RETURN NEXT;
END LOOP;
END
$func$ LANGUAGE plpgsql IMMUTABLE STRICT;
Further reading:
Now, all of these queries work:
SELECT t.*
FROM unnest_2d_1d('{{"one", "two"}, {"one", "more"}, {"two", "five"}}'::varchar[]) a(column_name)
JOIN new_table t USING (column_name);
Or:
SELECT t.*
FROM new_table t
WHERE column_name = ANY ((SELECT unnest_2d_1d('{{"one", "two"}, {"one", "more"}, {"two", "five"}}'::varchar[])));
Or:
...
WHERE column_name IN ((SELECT unnest_2d_1d('{{"one", "two"}, {"one", "more"}, {"two", "five"}}'::varchar[])));
dbfiddle here
Related:
Asides
This is one of the rare cases where a btree index on an array column might be useful:
CREATE INDEX ON new_table(column_name);
There is nothing special about varchar(255)
in Postgres. I mostly just use text
. See: