Non, vous n'avez pas besoin du cast pour regclass
lors de l'appel d'une fonction comme nextval
qui accepte une regclass
paramètre, car il y a un cast implicite de text
à regclass
. Dans certains autres contextes, un cast explicite en regclass
peut être nécessaire.
Explication :
::regclass
est un cast, comme ::integer
.
regclass
est un type de données "magique" ; c'est en fait un alias pour oid
, ou "identifiant d'objet". Voir Types d'identifiant d'objet
dans la documentation. Diffuser vers regclass
est un raccourci pour dire "c'est le nom d'une relation, veuillez le convertir en l'oid de cette relation". Convertit en regclass
connaissent le search_path
, contrairement à la requête pg_class
pour le oid
d'une relation directement, donc la conversion en regclass n'est pas exactement équivalente à la sous-requête pg_class
.
Les tables sont des relations. Il en va de même pour les séquences et les vues. Ainsi, vous pouvez également obtenir l'oid d'une vue ou d'une séquence en effectuant un cast vers regclass.
Il existe des conversions implicites définies pour text
à regclass
, donc si vous omettez le cast explicite et que vous appelez une fonction qui accepte regclass
le casting se fait automatiquement. Alors vous ne faites pas besoin dans, par exemple, nextval
appels.
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 ça :
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 conversion en regclass
. Ne l'utilisez pas, c'est surtout pour le plaisir et comme une tentative de démonstration de ce qui se passe réellement. À moins que vous ne soyez vraiment intéressé par le fonctionnement des tripes de Pg, 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 rapide. Voir Fonctions d'informations système
pour la définition de current_schemas(...)
, etc.
En d'autres termes :
- Obtenez un tableau ab répertoriant tous les schémas auxquels nous avons accès et associez chaque entrée à un nombre ordinal pour sa position dans le tableau
- Rechercher
pg_class
pour les relations avec des noms correspondants et associez chacune à son espace de noms (schéma) - Trier la liste des relations restantes selon l'ordre dans lequel leurs schémas sont apparus dans
search_path
- et choisissez la première correspondance