PostgreSQL:DBLink 奇怪的权限/连接错误

vol*_*ron 6 postgresql dblink

目标是 (1)创建一个连接,(2)返回另一个数据库的视图,以及 (3)关闭所有要存储在视图中的同一个连接(没有存储过程或嵌入式密码)。我想出了以下代码,它使用信任帐户并且似乎可以工作,直到过滤布尔字段。搜索false(field=false) 有效,但搜索true(field=true) 或IS NOT NULL提示输入密码。

返回数据时不需要密码真的很奇怪,但是在过滤时,那就是需要密码的时候。


PostgreSQL: v8.4:

  • 有两个数据库:db_remotedb_local
  • 有两个账户:
    • trust_user(在 pg_hba.conf 中设置为对两个数据库的信任
    • md5_user(在 pg_hba.conf 中设置为两个数据库的md5
  • db_remote 有一个视图 ( v_sessions),它包含两个字段:文本字段和布尔字段,它是用CASE语句创建的。

从 db_local(作为 md5_user)中:

-- Creates okay:
CREATE VIEW v_sessions AS 
SELECT * FROM (
     select  '1' query_type,'' as username, false as is_logged_in 
     from    dblink_connect_u('connection', 'host=development dbname=db_remote user=trusted_user') 
     union 
     select  '2' query_type, username, is_logged_in 
     from    dblink('connection', 'select username, is_logged_in from v_sessions') as v_session(username text, is_logged_in boolean) 
     union 
     select  '3' query_type,'',false 
     from    dblink_disconnect('connection')
) v_sessions 
WHERE query_type=2;

-- Calling the view with filter:
SELECT * FROM v_sessions WHERE is_logged_in;
Run Code Online (Sandbox Code Playgroud)

什么工作:

  • 删除 AND is_logged_in
  • 过滤文本字段AND username = 'some value'!!
  • 在布尔字段上过滤false( AND is_logged_in = false) !!

什么不起作用:

  • 过滤布尔字段以获得真值:AND is_logged_in IS NOT NULL, AND is_logged_in, or AND is_logged_in = true,给出以下错误消息:

    错误:需要密码
    详细信息:非超级用户必须在连接字符串中提供密码。


在第二个查询中进行过滤是有效的,但是当想要将其存储在视图中时它没有帮助。


我想我正在寻找建议,但真的试图了解正在发生的事情,例如。为什么搜索false有效而true没有 - 我首先认为连接是预先关闭的,但事实并非如此。

Chr*_*ers 2

这就是我认为正在发生的事情。我不认为这是一个错误。

  1. 你有一个观点。该视图有些复杂,但它是动态重写的查询。

  2. 策划者还是很聪明的。它将忽略搜索条件不会产生输出结果的 UNION 子句。

  3. 你没有执行你所认为的那样。(解释分析应该告诉你这一点)

我的建议:

  1. 将整个结果集包装在 plpgsql 函数中。将该函数包装在视图中。或者

  2. 使用WITH 子句。我对此不太确定。我认为 with 子句可能会导致整个过程一致运行,但不是 100% 确定,并且在未来的版本中也不能保证这一点。因此,包装在函数中可能会更好。

我认为策划者看到的是:

“哦,我们不需要执行视图的第一部分和第三部分,因为它们不在输出中!让我们跳过并只运行第二部分!” 这是一个功能,而不是一个错误(它使得表分区变得有用)。