Que signifie regclass dans Postgresql
J'ai la ligne suivante dans une instruction CREATE TABLE:
field1_id bigint DEFAULT nextval('table1_field1_id_seq'::regclass) NOT NULL,
Que signifie regclass dans ce qui précède? Est-ce une exigence absolue d'ajouter ::regclass
?
N. B: j'avais vu la documentation Postgresql link qui parle de regclass
, mais je ne pouvais pas le comprendre.
2 réponses
Non, vous n'avez pas besoin de la distribution à regclass
lors de l'appel d'une fonction comme nextval
qui accepte un paramètre regclass
, car il y a une distribution implicite de text
à regclass
. Dans d'autres contextes, une distribution explicite à regclass
peut être requise.
Explication:
::regclass
est un casting, comme ::integer
.
regclass
est une "magie" type de données; c'est en fait un alias pour oid
, ou "identificateur d'objet". Voir types D'identificateur D'objet dans la documentation. Le Casting à regclass
est un raccourci façon de dire "c'est le nom d'une relation, veuillez le convertir en oid de cette relation". Les conversions vers {[3] } sont au courant du search_path
, contrairement à l'interrogation pg_class
pour une relation oid
directement, donc la conversion en regclass n'est pas exactement équivalente à la sous-requête pg_class
.
Les Tables sont des relations. Tout comme les séquences et les vues. Ainsi, vous pouvez obtenir l'oid d'une vue ou d'une séquence en convertissant aussi en regclass.
Il y a des conversions implicites définies pour text
à regclass
, donc si vous omettez l' distribution explicite et vous appelez une fonction qui accepte regclass
la distribution est effectuée automatiquement. Donc, vous n'avez pas besoin de dans les appels nextval
, par exemple.
Il y a d'autres endroits où vous pouvez. Par exemple, vous ne pouvez pas comparer text
directement avec oid
; Vous pouvez donc faire ceci:
regress=> select * from pg_class where oid = 'table1'::regclass;
, Mais pas ceci:
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';
Juste pour le plaisir, j'ai essayé d'écrire une requête qui effectuait l'opération équivalente de coulée à regclass
. Ne l'utilisez pas, c'est surtout pour le plaisir, et comme un essayez de démo ce qui se passe réellement. Sauf si vous êtes vraiment intéressé par la façon dont les tripes de Pg fonctionnent, vous pouvez arrêter de lire ici.
Si je comprends bien, 'sequence_name'::regclass::oid
est à peu près équivalent à la requête suivante:
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;
, Sauf que c'est beaucoup plus court et beaucoup plus vite. Voir fonctions D'information Système pour la définition de current_schemas(...)
, etc.
En d'autres termes:
- obtenez un tableau ab listant tous les schémas auxquels nous avons accès et associez chaque entrée avec un nombre ordinal pour sa position dans le tableau
- Recherche
pg_class
les relations avec les noms correspondants et associe chacun à son espace de noms (schéma) - trie la liste des relations restantes selon l'ordre dans lequel leurs schémas apparaissent dans
search_path
- et choisissez le premier match
D'après ce que je comprends de la documentation, les oid sont subdivisés en types. regclass
sont des objets de base de données représentant des relations (de sorte qu'ils appartiennent à la table de métadonnées pg_class).
Il exprime une dépendance entre la séquence et l'expression DEFAULT
(ce qui signifie le processus de production d'une valeur par défaut si aucune valeur explicite n'est fournie dans une requête INSERT par exemple), de sorte que si l'on émet un DROP SEQUENCE ...
sur la séquence, la requête ne passera pas, sauf si elle est en cascade (en écrivant DROP SEQUENCE table1_field1_id_seq CASCADE
).