web-dev-qa-db-fra.com

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? Faut-il absolument ajouter ::regclass?

NB: J'avais vu la documentation Postgresql link qui parle de regclass, mais je ne pouvais pas la comprendre .

38
saji89

Non, vous n'avez pas besoin du transtypage en regclass lors de l'appel d'une fonction comme nextval qui accepte un paramètre regclass, car il y a un transtypage implicite de text à regclass. Dans certains autres contextes, une conversion explicite en regclass peut être requise.

Explication:

::regclass Est une distribution, 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. La conversion en regclass est un moyen raccourci de dire "c'est le nom d'une relation, veuillez le convertir en l'oid de cette relation". Les conversions vers regclass connaissent le search_path, Contrairement à l'interrogation 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 tableaux sont des relations. Il en va de même pour les séquences et les vues. Ainsi, vous pouvez également obtenir le contenu d'une vue ou d'une séquence en effectuant également un cast dans regclass.

Il y a des transtypages implicites définis pour text en regclass, donc si vous omettez le transtypage explicite et que vous appelez une fonction qui accepte regclass le transtypage se fait automatiquement. Vous en avez donc pas besoin, par exemple, dans les appels nextval.

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 cast sur 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
  • Recherchez pg_class Les relations avec les noms correspondants et associez-les à son espace de noms (schéma)
  • Trier la liste des relations restantes par ordre dans lequel leurs schémas sont apparus dans search_path
  • et choisissez le premier match
53
Craig Ringer

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 (signifiant 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).

0
didierc