暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

cached plan must not change result type 原因和解法

digoal 2019-04-17
6935

作者

digoal

日期

2019-04-17

标签

PostgreSQL , cached plan must not change result type , prepared statement , 绑定变量


背景

PostgreSQL的优化器是非常复杂的,和Oracle属于一个量级,所以如果是OLTP系统,建议使用绑定变量,减少sql parser, plan的开销。

在使用绑定变量时,可能会遇到这样的问题,当结构发生变化时,如果绑定变量的SQL结果依赖这个结构,那么会报类似错误:

ERROR: 0A000: cached plan must not change result type LOCATION: RevalidateCachedQuery, plancache.c:745

原因是绑定变量对应SQL的结果与当前结构下对应的结果不一致。

例子:

```
postgres=# create table tc (id int ,c1 int);
CREATE TABLE
postgres=# insert into tc values (1,1);
postgres=# prepare x (int) as select * from tc where id=$1;
PREPARE
postgres=# \set VERBOSITY verbose
postgres=# execute x(1);
id | c1
----+----
1 | 1
(1 row)

postgres=# alter table tc add column c2 int;
ALTER TABLE
postgres=# execute x(1);
ERROR: 0A000: cached plan must not change result type
LOCATION: RevalidateCachedQuery, plancache.c:745
```

解法

discard all后,重新绑定即可。

```
postgres=# discard all;
DISCARD ALL
postgres=# execute x(1);
ERROR: 26000: prepared statement "x" does not exist
LOCATION: FetchPreparedStatement, prepare.c:535

postgres=# prepare x (int) as select * from tc where id=$1;
PREPARE
postgres=# execute x(1);
id | c1 | c2
----+----+----
1 | 1 |
(1 row)
```

参考

https://www.postgresql.org/docs/11/sql-prepare.html

https://www.postgresql.org/docs/11/libpq-async.html

PostgreSQL 许愿链接

您的愿望将传达给PG kernel hacker、数据库厂商等, 帮助提高数据库产品质量和功能, 说不定下一个PG版本就有您提出的功能点. 针对非常好的提议,奖励限量版PG文化衫、纪念品、贴纸、PG热门书籍等,奖品丰富,快来许愿。开不开森.

9.9元购买3个月阿里云RDS PostgreSQL实例

PostgreSQL 解决方案集合

德哥 / digoal's github - 公益是一辈子的事.

digoal's wechat

文章转载自digoal,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论