No, non è necessario il cast per regclass
quando si chiama una funzione come nextval
che accetta una regclass
parametro, poiché esiste un cast implicito da text
a regclass
. In altri contesti un cast esplicito a regclass
potrebbe essere richiesto.
Spiegazione:
::regclass
è un cast, come ::integer
.
regclass
è un tipo di dati "magico"; in realtà è un alias per oid
o "identificatore oggetto". Vedi Tipi di identificatore di oggetto
nella documentazione. Trasmetti a regclass
è un modo abbreviato per dire "questo è il nome di una relazione, per favore convertilo nell'oid di quella relazione". Trasmette a regclass
sono a conoscenza del search_path
, a differenza della query su pg_class
per un oid
di una relazione direttamente, quindi trasmettere a regclass non equivale esattamente a sottoquery pg_class
.
Le tabelle sono relazioni. Così sono le sequenze e le viste. Quindi puoi ottenere l'oid di una vista o sequenza eseguendo il cast anche su regclass.
Ci sono cast impliciti definiti per text
a regclass
, quindi se ometti il cast esplicito e stai chiamando una funzione che accetta regclass
il cast viene eseguito automaticamente. Quindi non ne hai bisogno, ad esempio, nextval
chiamate.
Ci sono altri posti dove potresti. Ad esempio non puoi confrontare text
direttamente con oid
; quindi puoi farlo:
regress=> select * from pg_class where oid = 'table1'::regclass;
ma non questo:
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';
Solo per divertimento ho provato a scrivere una query che eseguisse l'operazione equivalente di eseguire il casting su regclass
. Non usarlo, è principalmente per divertimento e come tentativo di dimostrare ciò che sta effettivamente accadendo. A meno che tu non sia veramente interessato a come funzionano le viscere di Pg, puoi smettere di leggere qui.
A quanto ho capito, 'sequence_name'::regclass::oid
è più o meno equivalente alla seguente query:
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;
tranne per il fatto che è molto più breve e molto più veloce. Vedi Funzioni di informazioni di sistema
per la definizione di current_schemas(...)
, ecc.
In altre parole:
- Ottieni un array ab che elenca tutti gli schemi a cui abbiamo accesso e abbina ogni voce a un numero ordinale per la sua posizione nell'array
- Cerca
pg_class
per le relazioni con nomi corrispondenti e associare ciascuna al proprio spazio dei nomi (schema) - Ordina l'elenco delle relazioni rimanenti in base all'ordine in cui i loro schemi sono apparsi in
search_path
- e scegli la prima corrispondenza