PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Que signifie regclass dans Postgresql

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