PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Was bedeutet regclass in Postgresql

Nein, Sie brauchen die Umwandlung in regclass nicht beim Aufruf einer Funktion wie nextval die eine regclass akzeptiert -Parameter, da es eine implizite Umwandlung von text gibt zu regclass . In einigen anderen Kontexten eine explizite Umwandlung in regclass kann erforderlich sein.

Erklärung:

::regclass ist eine Umwandlung, wie ::integer .

regclass ist ein "magischer" Datentyp; es ist eigentlich ein Alias ​​für oid , oder "Objektkennung". Siehe Objektkennungstypen in der Dokumentation. Casting in regclass ist eine Abkürzung für "dies ist der Name einer Relation, bitte wandeln Sie ihn in die oid dieser Relation um". Umwandlung in regclass kennen den search_path , im Gegensatz zur Abfrage von pg_class für den oid einer Relation direkt, daher ist das Casting in Regclass nicht genau gleichbedeutend mit der Unterabfrage von pg_class .

Tabellen sind Relationen. Dasselbe gilt für Sequenzen und Ansichten. Sie können also auch die OID einer Ansicht oder Sequenz erhalten, indem Sie sie in die reguläre Klasse umwandeln.

Für text sind implizite Umwandlungen definiert zu regclass , wenn Sie also die explizite Umwandlung weglassen und eine Funktion aufrufen, die regclass akzeptiert die Besetzung erfolgt automatisch. Also nicht brauchen es zum Beispiel in nextval Anrufe.

Es gibt andere Orte, wo Sie können. Zum Beispiel können Sie text nicht vergleichen direkt mit oid; so können Sie dies tun:

regress=> select * from pg_class where oid = 'table1'::regclass;

aber nicht das:

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';

Nur zum Spaß habe ich versucht, eine Abfrage zu schreiben, die die äquivalente Operation des Castings in regclass durchführt . Verwenden Sie es nicht, es ist hauptsächlich zum Spaß und als Versuch zu demonstrieren, was tatsächlich passiert. Wenn Sie nicht wirklich daran interessiert sind, wie Pgs Eingeweide funktionieren, können Sie hier aufhören zu lesen.

So wie ich es verstehe, 'sequence_name'::regclass::oid entspricht in etwa der folgenden Abfrage:

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;

außer dass es viel kürzer und viel schneller ist. Siehe Systeminformationsfunktionen für die Definition von current_schemas(...) usw.

Mit anderen Worten:

  • Erhalten Sie ein ab-Array, das alle Schemas auflistet, auf die wir Zugriff haben, und verknüpfen Sie jeden Eintrag mit einer Ordnungszahl für seine Position im Array
  • Suchen Sie pg_class nach Relationen mit übereinstimmenden Namen suchen und jede mit ihrem Namensraum (Schema) verknüpfen
  • Sortieren Sie die Liste der verbleibenden Relationen nach der Reihenfolge, in der ihre Schemas in search_path erschienen sind
  • und wähle das erste passende aus