注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

PostgreSQL 中文网

 
 
 

日志

 
 

PostgreSQL: Using pgsql_fdw in a funnction Result "ERROR: cache lookup failed for type 0"  

2012-06-30 14:25:33|  分类: PG案例分析 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

   
        今天读德哥 blog (原文 http://blog.163.com/digoal@126/blog/static/16387704020125218171919/ ),
里面描述的问题引起了我的好奇,问题是这样的,在 function 中 使用 pgsql_fdw 调用pg远程外部表时,会
报错,而在 session 中不会,具体演示下。


一 环境信息
--1.1 源库:

 IP         192.168.1.26/1923  
database   mydb
table      test
   

--1.2 目标库

 IP  192.168.1.26/1923
database   skytf
table      test_tf
   

   备注:  关于 pgsql_fdw 安装略,可以参考之前写的 BLOG:
                 http://francs3.blog.163.com/blog/static/4057672720125711112496/

 

--1.3 目标库表信息

 mydb=> \d test
             Table "mydb.test"
 Column |         Type          | Modifiers
--------+-----------------------+-----------
 id     | integer               |
 name   | character varying(32) |
Indexes:
    "idx_test_1" btree (id)

mydb=> select count(*) from test;
  count 
---------
 1990000
(1 row)

   

--1.4  版本信息

pgsql_fdw 模块版本:pgsql_fdw-1.0

postgresql 版本:   PostgreSQL 9.1.0

 


二 外部表测试
--2.1 create foreign server

 skytf=> \c skytf postgres
You are now connected to database "skytf" as user "postgres".

skytf=# grant usage on foreign data wrapper pgsql_fdw to skytf;
GRANT

skytf=# \c skytf skytf
You are now connected to database "skytf" as user "skytf".
skytf=> CREATE SERVER pgsql_srv FOREIGN DATA WRAPPER pgsql_fdw
skytf-> OPTIONS (host '127.0.0.1', port '1923', dbname 'mydb');
CREATE SERVER

skytf=> \des
           List of foreign servers
     Name     | Owner | Foreign-data wrapper
--------------+-------+----------------------
 file_srv     | skytf | file_fdw
 mysql_svr_25 | skytf | mysql_fdw
 pgsql_srv    | skytf | pgsql_fdw
(3 rows)

   

--2.2 create mapping user

 skytf=> CREATE USER MAPPING FOR public SERVER pgsql_srv
skytf-> OPTIONS (user 'mydb', password 'mydb');
CREATE USER MAPPING
   


--2.3 create foreign table

 skytf=> CREATE FOREIGN TABLE ft_test (
skytf(> id    integer  ,
skytf(> name  character varying(32) )
skytf-> SERVER pgsql_srv
skytf-> OPTIONS (nspname 'mydb', relname 'test');
CREATE FOREIGN TABLE
   


--2.4 查询外部表测试

 skytf=> \d ft_test;
       Foreign table "skytf.ft_test"
 Column |         Type          | Modifiers
--------+-----------------------+-----------
 id     | integer               |
 name   | character varying(32) |
Server: pgsql_srv

skytf=> select * From ft_test limit 3;
  id   | name
-------+------
 54241 | AAA
 54242 | AAA
 54243 | AAA
(3 rows)

   

--2.5 创建中间表

 skytf=> create table test_tf (id int4,name varchar(32));
CREATE TABLE
   


--2.6 创建函数

 CREATE or replace FUNCTION  func_sync_bill() RETURNS INTEGER  AS $$
    BEGIN
     begin
       insert into test_tf (id,name) select id,name from ft_test;
       return 0;    
     end;
    END;
$$ LANGUAGE 'plpgsql';
   

--2.7 执行函数

 skytf=> select func_sync_bill() ;
ERROR:  cache lookup failed for type 0
CONTEXT:  SQL statement "insert into test_tf (id,name) select id,name from ft_test"
PL/pgSQL function "func_sync_bill" line 4 at SQL statement

skytf=> select count(*) from  test_tf;
 count
-------
     0
(1 row)

   

 备注:错误出现在语句 "insert into test_tf (id,name) select id,name from ft_test"
             而这个语句单独在 session 中执行是正确的。
      

--2.8 在会话中执行插入语句
skytf=> select count(*) from  test_tf;
 count
-------
     0
(1 row)

skytf=> insert into test_tf (id,name) select id,name from ft_test;
INSERT 0 1990000

 备注:在 seesion 中调用 pgsql_fdw 表是正常的,而在 plpgsql function 中却不行, 之后网上
           查了很多资料也没有相关 bug 确认信息,后来 dba.stackexchange.com 问了下,有人建议
           使用 "EXCUTE" 语句,原贴如下 http://dba.stackexchange.com/questions/19919/using
           -pgsql-fdw-in-a-function-result-error-cache-lookup-failed-for-type-0/20179#20179
 


 
三 使用 EXCUTE 语句 测试 pgdql_fdw
--3.1  创建 function

 skytf=> CREATE or replace FUNCTION  func_sync_bill() RETURNS INTEGER  AS $$
skytf$>     BEGIN
skytf$>      begin
skytf$>         EXECUTE 'insert into test_tf (id,name) select id,name from ft_test';
skytf$>        return 0;    
skytf$>      end;
skytf$>     END;
skytf$> $$ LANGUAGE 'plpgsql';   
CREATE FUNCTION
   

--3.2 再次测试 

 skytf=> truncate table test_tf;
TRUNCATE TABLE

skytf=> select func_sync_bill();
 func_sync_bill
----------------
              0
(1 row)

skytf=> select count(*) from test_tf;
  count 
---------
 1990000
(1 row)

   

 备注:在 function 中采用 EXECUTE 语句执行后报错消失,估计 pgsql_fdw 模块目前还不很成熟,
             如果需要查询远程库数据的需求,也可以用比较原始的方法,即 dblink 来代替 pgsql_fdw。

  评论这张
 
阅读(27600)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016