Проблема заключается в том, что типы данных text[]
и text[][]
внутренне являются одинаковыми.Массив имеет базовый тип и размеры, и оператор ANY
всегда извлекает базовый тип для сравнения, который всегда будет text
, а не text[]
.Не помогает то, что многомерные массивы требуют, чтобы каждый подэлемент имел ту же длину, что и каждый другой.Вы можете иметь ARRAY[ARRAY['A','C'],ARRAY['B','N']]
, но не ARRAY[ARRAY[2,3],ARRAY[1]]
.
Короче говоря, не существует прямого способа заставить этот конкретный запрос работать. Я пытался создать функцию и оператор дляэто также, и это не работает, по разным причинам.Посмотрите, как это произошло:
CREATE OR REPLACE FUNCTION check_tag_matches(
IN leftside text[],
IN rightside text)
RETURNS BOOLEAN AS
$BODY$
DECLARE rightarr text[];
BEGIN
SELECT CAST(rightside as text[]) INTO rightarr;
RETURN SELECT leftside @> rightarr;
END;
$BODY$
LANGUAGE plpgsql STABLE;
CREATE OPERATOR public.>>(
PROCEDURE = check_tag_matches,
LEFTARG = text[],
RIGHTARG = text,
COMMUTATOR = >>);
Затем при тестировании:
test=# SELECT * FROM inherited_tags WHERE
tags >> ANY(ARRAY[ARRAY['A','M'], ARRAY['F','E'], ARRAY['E','R']]::text[][]);
ERROR: malformed array literal: "A"
DETAIL: Array value must start with "{" or dimension information.
CONTEXT: SQL statement "SELECT CAST(rightside as text[])"
PL/pgSQL function check_tag_matches(text[],text) line 4 at SQL statement
Кажется, что при попытке использовать многомерный массив, такой как ARRAY[ARRAY['A','M'], ARRAY['F','E'], ARRAY['E','R']]::text[][]
в ANY()
, он не повторяетсяболее ARRAY['A','M']
, затем ARRAY['F','E']
, затем ARRAY['E','R']
, но более 'A','M','F','E','E','R'
.То же самое происходит, когда с unnest
.
test=# SELECT unnest(ARRAY[ARRAY['A','M'], ARRAY['F','E'], ARRAY['E','R']]::text[][]);
unnest
--------
A
M
F
E
E
R
(6 rows)
Остальные опции должны определить функцию, которая будет читать array_length(rightside,1)
и array_length(rightside,2)
, и использовать вложенные циклы для проверки всего этого, или вы можете отправитьнесколько запросов, чтобы получить унаследованные теги для каждого тега или каким-либо образом реструктурировать ваши данные.И вы даже не можете получить доступ к элементу ARRAY['A','M']
, используя rightside[1]
для его итерации, вы вынуждены перейти на самый глубокий уровень.