sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Qué significa regclass en Postgresql?

No, no necesitas el cast para regclass al llamar a una función como nextval que acepta una regclass parámetro, ya que hay una conversión implícita de text a regclass . En algunos otros contextos, una conversión explícita a regclass puede ser necesario.

Explicación:

::regclass es una conversión, como ::integer .

regclass es un tipo de datos "mágico"; en realidad es un alias para oid , o "identificador de objeto". Consulte Tipos de identificadores de objetos en la documentación. Enviar a regclass es una forma abreviada de decir "este es el nombre de una relación, conviértalo al oid de esa relación". Transmite a regclass son conscientes de la search_path , a diferencia de consultar pg_class para el oid de una relación directamente, por lo que convertir a regclass no es exactamente equivalente a subconsultar pg_class .

Las tablas son relaciones. También lo son las secuencias y las vistas. Por lo tanto, también puede obtener el oid de una vista o secuencia transmitiendo a regclass.

Hay conversiones implícitas definidas para text a regclass , por lo que si omite la conversión explícita y está llamando a una función que acepta regclass el lanzamiento se hace automáticamente. Así que no lo necesita en, por ejemplo, nextval llamadas.

Hay otros lugares donde puedes. Por ejemplo, no puede comparar text directamente con oid; para que puedas hacer esto:

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

pero no esto:

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

Solo por diversión, traté de escribir una consulta que realizaba la operación equivalente de enviar a regclass . No lo use, es principalmente por diversión y como un intento de demostrar lo que realmente está sucediendo. A menos que esté realmente interesado en cómo funcionan las agallas de Pg, puede dejar de leer aquí.

Según tengo entendido, 'sequence_name'::regclass::oid es aproximadamente equivalente a la siguiente consulta:

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;

excepto que es mucho más corto y mucho más rápido. Consulte Funciones de información del sistema para la definición de current_schemas(...) , etc.

En otras palabras:

  • Obtenga una matriz ab que enumere todos los esquemas a los que tenemos acceso y empareje cada entrada con un número ordinal para su posición en la matriz
  • Buscar pg_class para relaciones con nombres coincidentes y asociar cada uno con su espacio de nombres (esquema)
  • Ordenar la lista de relaciones restantes por el orden en que aparecieron sus esquemas en search_path
  • y elige la primera coincidencia