Nie, nie potrzebujesz rzutowania na regclass
podczas wywoływania funkcji, takiej jak nextval
który akceptuje regclass
parametr, ponieważ istnieje niejawny rzut z text
do regclass
. W niektórych innych kontekstach jawne rzutowanie na regclass
może być wymagane.
Wyjaśnienie:
::regclass
jest rzutowaniem, jak ::integer
.
regclass
jest „magicznym” typem danych; to właściwie alias dla oid
lub „identyfikator obiektu”. Zobacz Typy identyfikatorów obiektów
w dokumentacji. Przesyłanie do regclass
to skrótowy sposób powiedzenia „to jest nazwa relacji, proszę zamień ją na oid tej relacji”. Przesyła do regclass
są świadomi search_path
, w przeciwieństwie do zapytania pg_class
dla oid
relacji bezpośrednio, więc rzutowanie na regclass nie jest dokładnie równoważne z podzapytaniem pg_class
.
Tabele to relacje. Podobnie sekwencje i widoki. Możesz więc uzyskać oid widoku lub sekwencji, rzutując również na regclass.
Istnieją niejawne rzutowania zdefiniowane dla text
do regclass
, więc jeśli pominiesz jawne rzutowanie i wywołujesz funkcję, która akceptuje regclass
obsada odbywa się automatycznie. Więc nie potrzebujesz go na przykład w nextval
połączeń.
Są inne miejsca, w których możesz. Na przykład nie możesz porównać text
bezpośrednio z oid
; więc możesz to zrobić:
regress=> select * from pg_class where oid = 'table1'::regclass;
ale nie to:
regress=> select * from pg_class where oid = 'table1';
ERROR: invalid input syntax for type oid: "table1"
LINE 1: select * from pg_class where oid = 'table1';
Dla zabawy próbowałem napisać zapytanie, które wykonało równoważną operację rzutowania do regclass
. Nie używaj go, to głównie dla zabawy i jako próba zademonstrowania tego, co się naprawdę dzieje. Jeśli nie jesteś naprawdę zainteresowany tym, jak działają wnętrzności Pg, możesz przestać czytać tutaj.
Jak rozumiem, 'sequence_name'::regclass::oid
jest mniej więcej odpowiednikiem następującego zapytania:
WITH sp(sp_ord, sp_schema) AS (
SELECT
generate_series(1, array_length(current_schemas('t'),1)),
unnest(current_schemas('t'))
)
SELECT c.oid
FROM pg_class c INNER JOIN pg_namespace n ON (c.relnamespace = n.oid)
INNER JOIN sp ON (n.nspname = sp.sp_schema)
WHERE c.relname = 'sequence_name'
ORDER BY sp.sp_ord
LIMIT 1;
poza tym, że jest dużo krótsza i dużo szybsza. Zobacz Funkcje informacji o systemie
dla definicji current_schemas(...)
itp.
Innymi słowy:
- Pobierz tablicę ab zawierającą listę wszystkich schematów, do których mamy dostęp i sparuj każdy wpis z liczbą porządkową określającą jego pozycję w tablicy
- Wyszukaj
pg_class
dla relacji z pasującymi nazwami i skojarz każdą z ich przestrzenią nazw (schematem) - Posortuj listę pozostałych relacji według kolejności, w jakiej ich schematy pojawiły się w
search_path
- i wybierz pierwszy mecz