Nej, du behöver inte casten för att regclass
när du anropar en funktion som nextval
som accepterar en regclass
parameter, eftersom det finns en implicerad cast från text
till regclass
. I vissa andra sammanhang en explicit cast till regclass
kan krävas.
Förklaring:
::regclass
är en cast, som ::integer
.
regclass
är en "magisk" datatyp; det är faktiskt ett alias för oid
, eller "objektidentifierare". Se typer av objektidentifierare
i dokumentationen. Castar till regclass
är ett genvägssätt att säga "det här är namnet på en relation, vänligen konvertera den till oiden av den relationen". Castar till regclass
är medvetna om search_path
, till skillnad från att fråga pg_class
för en relations oid
direkt, så att casta till regclass är inte exakt likvärdigt med att undersöka pg_class
.
Tabeller är relationer. Så är sekvenser och vyer. Så du kan få id av en vy eller sekvens genom att kasta till regklass också.
Det finns implicita casts definierade för text
till regclass
, så om du utelämnar den explicita casten och du anropar en funktion som accepterar regclass
gjutningen görs automatiskt. Så du gör inte behöver det i till exempel nextval
samtal.
Det finns andra ställen där du kan. Du kan till exempel inte jämföra text
direkt med oid
; så du kan göra detta:
regress=> select * from pg_class where oid = 'table1'::regclass;
men inte detta:
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';
Bara för skojs skull försökte jag skriva en fråga som utförde motsvarande operation för att casta till regclass
. Använd det inte, det är mest för skojs skull, och som ett försök att demonstrera vad som faktiskt händer. Om du inte är riktigt intresserad av hur Pg:s mage fungerar kan du sluta läsa här.
Som jag förstår det, 'sequence_name'::regclass::oid
motsvarar ungefär följande fråga:
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;
förutom att det är mycket kortare och mycket snabbare. Se Systeminformationsfunktioner
för definitionen av current_schemas(...)
osv.
Med andra ord:
- Få en ab-matris som listar alla scheman vi har tillgång till och koppla ihop varje post med ett ordningsnummer för dess position i matrisen
- Sök i
pg_class
för relationer med matchande namn och associera var och en med dess namnområde (schema) - Sortera listan över återstående relationer efter den ordning som deras scheman visades i
search_path
- och välj den första matchningen