Esto parece funcionar, pero podría tener consecuencias imprevistas. Requiere retoques con los catálogos del sistema, ¡lo cual no es realmente una buena idea!
En primer lugar, usted tiene que permitir superusuarios para actualizar los catálogos del sistema añadiendo esto a su configuración de PostgreSQL:
allow_system_table_mods = on
y reinicie.
Ahora, puede usar las sentencias DDL para modificar los catálogos del sistema (debe tener miedo). Conectarse a una de las bases de datos de usuario (una prueba de uno sería una buena idea) y:
alter table pg_catalog.pg_database rename to pg_database_catalog;
create view pg_catalog.pg_database as
select oid, 1262::oid as tableoid, pg_database_catalog.*
from pg_catalog.pg_database_catalog
where has_database_privilege(pg_database_catalog.oid, 'connect');
grant select on pg_catalog.pg_database to public;
Ahora debe encontrar que si se conecta a que base de datos como un usuario bajo priv, el comando \l
se simplemente liste las bases de datos a las que ese usuario se puede conectar.
El problema es que ahora necesita adivinar a qué base de datos se conectan inicialmente los usuarios para recuperar su lista de bases de datos. Si se conectan a su propia base de datos inicialmente, entonces probablemente termines en este punto. Si se conectan primero al postgres
o al template1
, debe realizar este cambio en esa base de datos.
Me parece que esto debería funcionar, ya que el catálogo pg_database
es referido por postgres backends directamente por oid, en lugar de por nombre, por lo que moverlo fuera del camino y cambiar las filas que se muestran en él debería ser invisible para ellos En particular, no puede evitar que el servidor distinga al usuario entre una base de datos que no existe y los que no tienen privilegio de conexión.
No voy a hacer ninguna promesa de que este tipo de cambio no arruine algo más en el futuro. Si se rompe, tienes que guardar las piezas.
Probablemente desee hacer este cambio en una base de datos de plantillas, y crear bases de datos de usuarios a partir de ese momento, y desactivar la configuración allow_system_table_mods
cuando haya terminado (lo que requiere un reinicio del servidor, recuerde).
Además, probé esto en 9.0: me parece que también debería funcionar en algunas versiones anteriores, caveat emptor.
¿Por qué no tener varias instancias ejecutándose a la vez? –
Necesito ejecutarlos todos en el mismo puerto. – Kai