Co to jest „tabela przejściowa” w Postgres?

12

Strona opisująca nowości w Postgres 10 wspomina o „tabelach przejścia dla wyzwalaczy”.

Tabele przejściowe dla wyzwalaczy

Ta funkcja sprawia, że AFTER STATEMENTwyzwalacze są zarówno użyteczne, jak i wydajne, narażając, odpowiednio, stare i nowe wiersze na zapytania. Przed tą funkcją AFTER STATEMENTwyzwalacze nie miały do ​​nich bezpośredniego dostępu, a obejścia były bizantyńskie i miały niską wydajność. Można teraz napisać wiele logiki wyzwalania AFTER STATEMENT, unikając konieczności wykonywania kosztownych przełączników kontekstu w każdym wierszu, które są wymagane dla KAŻDEGO wyzwalacza WIERSZ.

Co to jest tabela przejściowa?

Basil Bourque
źródło

Odpowiedzi:

12

Wiesz, jak istnieją OLDi NEWrejestrują zmienne dla FOR EACH ROWwyzwalaczy?

Tabele przejścia są FOR EACH STATEMENTodpowiednikami. Są to tabele ze starymi i nowymi krotkami, więc twoje wyzwalacze mogą zobaczyć, co się zmieniło.

Craig Ringer
źródło
9

Bardzo podoba mi się wyjaśnienie Craiga dotyczące tej funkcji. Specyfikacja SQL-2011 definiuje je w kontekście wyzwalacza jako „zbiór wierszy usuwanych, wstawianych lub zastępowanych jest nazywany tabelą przejściową”. Podobne wyjaśnienie jest w docs,

Podczas gdy tabele przejścia dla AFTERwyzwalaczy są określone przy użyciu REFERENCINGklauzuli w standardowy sposób, zmienne wierszy używane w FOR EACH ROWwyzwalaczach mogą nie być określone w REFERENCINGklauzuli. Są one dostępne w sposób zależny od języka, w którym napisana jest funkcja wyzwalacza. Niektóre języki zachowują się tak, jakby REFERENCINGzawierała je klauzulaOLD ROW AS OLD NEW ROW AS NEW.

Zasadniczo udostępniają ci wszystkie zmiany wyciągu, co jest bardzo przydatne. Dla porównania, DDL przy tworzeniu wyzwalacza wygląda tak z tabelami przejść

REFERENCING OLD TABLE AS oldtable NEW TABLE AS newtable

Możesz zobaczyć przykład tutaj , a tutaj jest jeden z zestawu testów ,

CREATE TABLE transition_table_base (id int PRIMARY KEY, val text);

CREATE FUNCTION transition_table_base_ins_func()
  RETURNS trigger
  LANGUAGE plpgsql
AS $$
DECLARE
  t text;
  l text;
BEGIN
  t = '';
  FOR l IN EXECUTE
           $q$
             EXPLAIN (TIMING off, COSTS off, VERBOSE on)
             SELECT * FROM newtable
           $q$ LOOP
    t = t || l || E'\n';
  END LOOP;

  RAISE INFO '%', t;
  RETURN new;
END;
$$;

CREATE TRIGGER transition_table_base_ins_trig
  AFTER INSERT ON transition_table_base
  REFERENCING OLD TABLE AS oldtable NEW TABLE AS newtable
  FOR EACH STATEMENT
  EXECUTE PROCEDURE transition_table_base_ins_func();

Kilka dodatkowych uwag

  1. Są dostępne tylko w przypadku AFTERwyzwalaczy.
  2. Biorą pod uwagę takie rzeczy jak ON CONFLICT.

Ważne jest, aby zaznaczyć, że nie do końca będzie dostępny w PG 10 . Istnieje wiele otwartych problemów z tabelami przejścia . Większość ma łatki. Są pewne walki wewnętrzne, które są rodzajem rutyny. Wygląda na to, że ciężkie podnoszenie zostało podjęte przez kogoś innego. Nić oznacza, że dowiemy się wkrótce.

Autor odpowiedział - wydaje się, że znów idzie dobrze.

Evan Carroll
źródło