/ / Zapytanie rekurencyjne w greenplum - greenplum

Zapytanie rekurencyjne w greenplum - greenplum

Muszę utworzyć pole nawigacyjne w tabeli dziecko / ojciec w MPP greenplum

Oryginalna tabela ma 2 pola: ojciec, dziecko Muszę wyodrębnić widok za pomocą ścieżki nawigacyjnej

Na przykład posiadanie tych rekordów

1, 2
1, 3
2, 4
4, 5

Muszę wyodrębnić:

1/2
1/3
1/2/4
1/2/4/5

i tak dalej

Greenplum to mechanizm przetwarzania MPP oparty na postgresql 8.2. Zasadniczo jest to postgres ale podając wersję, nie obsługuje ona funkcji „z rekurencyjnym” postgresql z 8.3.

Ponadto, jeśli spróbuję utworzyć funkcję do wykonania zadania, napotykam inne ograniczenia GP

Na przykład, jeśli utworzę funkcję taką jak poniżej


CREATE OR REPLACE FUNCTION   getBreadCrumb(decimal) RETURNS text AS "DECLARE
itemid ALIAS FOR $1;
itemfullname text;
itemrecord RECORD;
BEGIN
SELECT * INTO itemrecord FROM mytable where father=itemid;
itemfullname := coalesce(itemfullname, """") || itemrecord.father::text;
IF itemrecord.child IS NOT NULL  THEN
itemfullname := itemfullname || ""/"" || getBreadCrumb(itemrecord.child)::text ;
RETURN itemfullname;
ELSE
RETURN itemfullname;
END IF;
END"  LANGUAGE "plpgsql"

a następnie spróbuj wybrać z tego, co otrzymam


ERROR:  function cannot execute on segment because it accesses relation "mytable" (functions.c:152)

co wydaje mi się związane z architekturą greenplum „nic wspólnego”.

Jakikolwiek inny pomysł, aby utworzyć ścieżkę nawigacyjną dającą środowisko, które mam?

z góry dziękuję

Odpowiedzi:

1 dla odpowiedzi № 1

Podobny problem miałem z pracą z hierarchiami. Jedyną opcją do rozwiązania jest napisanie funkcji pl / pgsql wykonywanej na urządzeniu głównym, która zaktualizowałaby pole „hierarchii” w takiej pętli:

Zawartość początkowa:

Node_id | Parent_id | Hierarchy
1       | null      | {1}
2       | 1         | {2}
3       | 1         | {3}
4       | 3         | {4}
5       | 3         | {5}
6       | 5         | {6}

Pierwsza iteracja:

Node_id | Parent_id | Hierarchy
1       | null      | {1}
2       | 1         | {2, 1}
3       | 1         | {3, 1}
4       | 3         | {4, 3}
5       | 3         | {5, 3}
6       | 5         | {6, 5}

Druga iteracja:

Node_id | Parent_id | Hierarchy
1       | null      | {1}
2       | 1         | {2, 1}
3       | 1         | {3, 1}
4       | 3         | {4, 3, 1}
5       | 3         | {5, 3, 1}
6       | 5         | {6, 5, 3}

Ostatnia iteracja:

Node_id | Parent_id | Hierarchy
1       | null      | {1}
2       | 1         | {2, 1}
3       | 1         | {3, 1}
4       | 3         | {4, 3, 1}
5       | 3         | {5, 3, 1}
6       | 5         | {6, 5, 3, 1}

Jedną z optymalizacji, którą można zrobić, aby uniknąć pełnego samodzielnego łączenia na każdej iteracji, jest zapisanie dodatkowego pola „poziomu” i zwiększenie go dla zaktualizowanych rekordów (ponieważ tylko rekordy są aktualizowane w iteracji i należy wziąć pod uwagę przy aktualizacji iteracji i+1)

Niestety GPDB nie obsługuje with recursive i wykonywanie zapytań na poziomie segmentu, więc jest to jedyna opcja