8.19. Tipos de identificadores de objetos (OIDs) #

Los identificadores de objetos (OID) son utilizados internamente por PostgreSQL como claves primarias para varias tablas del sistema. El tipo oid representa un identificador de objeto. También hay varios tipos de alias para oid, cada uno llamado regalgo. La Table 8.26 muestra una visión general.

El tipo oid se implementa actualmente como un entero sin signo de cuatro bytes. Por lo tanto, no es lo suficientemente grande como para proporcionar unicidad en toda la base de datos en bases de datos grandes, o incluso en tablas individuales grandes.

El propio tipo oid tiene pocas operaciones más allá de la comparación. Sin embargo, se puede convertir a entero y luego manipularse utilizando los operadores de enteros estándar. (Ten cuidado con la posible confusión entre con signo y sin signo si haces esto).

Los tipos de alias de OID no tienen operaciones propias, excepto por rutinas especializadas de entrada y salida. Estas rutinas pueden aceptar y mostrar nombres simbólicos para objetos del sistema, en lugar de del valor numérico sin procesar que usaría el tipo oid. Los tipos de alias permiten una búsqueda simplificada de valores OID para objetos. Por ejemplo, para examinar las filas de pg_attribute relacionadas con una tabla mytable, se podría escribir:

SELECT * FROM pg_attribute WHERE attrelid = 'mytable'::regclass;

en lugar de:

SELECT * FROM pg_attribute
  WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'mytable');

Si bien esto no se ve tan mal por sí solo, sigue estando demasiado simplificado. Se necesitaría una subconsulta mucho más complicada para seleccionar el OID correcto si hay varias tablas llamadas mytable en diferentes esquemas. El convertidor de entrada regclass maneja la búsqueda de la tabla de acuerdo con la configuración de la ruta del esquema, por lo que hace lo correcto automáticamente. De manera similar, convertir el OID de una tabla a regclass es útil para la visualización simbólica de un OID numérico.

Table 8.26. Tipos de identificadores de objetos

NombreReferenciasDescripciónEjemplo de valor
oidcualquieraidentificador numérico de objeto564182
regclasspg_classnombre de relaciónpg_type
regcollationpg_collationnombre de ordenación (collation)"POSIX"
regconfigpg_ts_configconfiguración de búsqueda de textoenglish
regdictionarypg_ts_dictdiccionario de búsqueda de textosimple
regnamespacepg_namespacenombre de espacio de nombrespg_catalog
regoperpg_operatornombre de operador+
regoperatorpg_operatoroperador con tipos de argumentos*(integer,​integer) o -(NONE,​integer)
regprocpg_procnombre de funciónsum
regprocedurepg_procfunción con tipos de argumentossum(int4)
regrolepg_authidnombre de rolsmithee
regtypepg_typenombre de tipo de datosinteger

Todos los tipos de alias de OID para objetos que están agrupados por espacio de nombres aceptan nombres calificados por esquema, y mostrarán nombres calificados por esquema en la salida si el objeto no se encontrara en la ruta de búsqueda actual sin estar calificado. Por ejemplo, myschema.mytable es una entrada aceptable para regclass (si existe tal tabla). Ese valor podría mostrarse como myschema.mytable, o simplemente mytable, dependiendo de la ruta de búsqueda actual. Los tipos de alias regproc y regoper solo aceptarán nombres de entrada que sean únicos (no sobrecargados), por lo que son de utilidad limitada; para la mayoría de los usos, regprocedure o regoperator son más apropiados. Para regoperator, los operadores unarios se identifican escribiendo NONE para el operando no utilizado.

Las funciones de entrada para estos tipos permiten espacios en blanco entre tokens, y convertirán las letras mayúsculas a minúsculas, excepto dentro de las comillas dobles; esto se hace para que las reglas de sintaxis sean similares a la forma en que se escriben los nombres de los objetos en SQL. Por el contrario, las funciones de salida utilizarán comillas dobles si es necesario para que la salida sea un identificador SQL válido. Por ejemplo, el OID de una función llamada Foo (con la F en mayúscula) que toma dos argumentos enteros podría introducirse como ' "Foo" ( int, integer ) '::regprocedure. La salida se vería como "Foo"(integer,integer). Tanto el nombre de la función como los nombres de los tipos de argumentos podrían estar calificados por esquema también.

Muchas funciones integradas de PostgreSQL aceptan el OID de una tabla, o de otro tipo de objeto de base de datos, y por conveniencia se declaran como que toman regclass (o el tipo de alias OID adecuado). Esto significa que no tienes que buscar el OID del objeto a mano, sino que puedes introducir simplemente su nombre como una cadena literal. Por ejemplo, la función nextval(regclass) toma el OID de una relación de secuencia, por lo que podrías llamarla de esta manera:

nextval('foo')              opera sobre la secuencia foo
nextval('FOO')              igual que el anterior
nextval('"Foo"')            opera sobre la secuencia Foo
nextval('myschema.foo')     opera sobre myschema.foo
nextval('"myschema".foo')   igual que el anterior
nextval('foo')              busca en la ruta de búsqueda para foo

Note

Cuando escribes el argumento de dicha función como una cadena literal simple, se convierte en una constante de tipo regclass (o el tipo adecuado). Dado que esto es realmente solo un OID, rastreará el objeto originalmente identificado a pesar de que posteriormente se cambie de nombre, se reasigne a otro esquema, etc. Este comportamiento de enlace temprano (early binding) suele ser deseable para las referencias a objetos en valores predeterminados de columnas y vistas. Pero a veces es posible que desees un enlace tardío (late binding) donde la referencia al objeto se resuelva en tiempo de ejecución. Para obtener el comportamiento de enlace tardío, fuerza a que la constante se almacene como una constante de tipo text en lugar de regclass:

nextval('foo'::text)      foo se busca en tiempo de ejecución

La función to_regclass() y sus funciones hermanas también se pueden utilizar para realizar búsquedas en tiempo de ejecución. Consulta la Table 9.76.

Otro ejemplo práctico del uso de regclass es buscar el OID de una tabla enumerada en las vistas de information_schema, que no proporcionan tales OID directamente. Por ejemplo, uno podría desear llamar a la función pg_relation_size(), que requiere el OID de la tabla. Teniendo en cuenta las reglas anteriores, la forma correcta de hacer eso es:

SELECT table_schema, table_name,
       pg_relation_size((quote_ident(table_schema) || '.' ||
                         quote_ident(table_name))::regclass)
FROM information_schema.tables
WHERE ...

La función quote_ident() se encargará de poner comillas dobles a los identificadores donde sea necesario. La forma aparentemente más fácil:

SELECT pg_relation_size(table_name)
FROM information_schema.tables
WHERE ...

no se recomienda, porque fallará para tablas que estén fuera de tu ruta de búsqueda o tengan nombres que requieran comillas.

Una propiedad adicional de la mayoría de los tipos de alias OID es la creación de dependencias. Si una constante de uno de estos tipos aparece en una expresión almacenada (como una expresión predeterminada de columna o vista), crea una dependencia en el objeto referenciado. Por ejemplo, si una columna tiene una expresión predeterminada nextval('my_seq'::regclass), PostgreSQL entiende que la expresión predeterminada depende de la secuencia my_seq, por lo que el sistema no permitirá que la secuencia sea eliminada sin quitar primero la expresión predeterminada. La alternativa de nextval('my_seq'::text) no crea una dependencia. (regrole es una excepción a esta propiedad. No se permiten constantes de este tipo en expresiones almacenadas).

Otro tipo de identificador utilizado por el sistema es xid, o identificador de transacción (abreviado xact). Este es el tipo de datos de las columnas del sistema xmin y xmax. Los identificadores de transacciones son cantidades de 32 bits. En algunos contextos, se utiliza una variante de 64 bits xid8. A diferencia de los valores xid, los valores xid8 aumentan de forma estrictamente monótona y no se pueden reutilizar en la vida de un clúster de base de datos. Consulta la Section 67.1 para más detalles.

Un tercer tipo de identificador utilizado por el sistema es cid, o identificador de comando. Este es el tipo de datos de las columnas del sistema cmin and cmax. Los identificadores de comandos también son cantidades de 32 bits.

Un último tipo de identificador utilizado por el sistema es tid, o identificador de tupla (identificador de fila). Este es el tipo de datos de la columna del sistema ctid. Un ID de tupla es un par (número de bloque, índice de tupla dentro del bloque) que identifica la ubicación física de la fila dentro de su tabla.

(Las columnas del sistema se explican con más detalle en la Section 5.6).