PostgreSQL生成的列并非始终最新

vsdwdz23  于 2022-11-04  发布在  PostgreSQL
关注(0)|答案(1)|浏览(144)

版本:PostgreSQL 12.4版本
方案

CREATE TABLE table1 (
    id int16 NOT NULL,
    placed_count int4 NOT NULL DEFAULT 0,
    picked_count int4 NOT NULL DEFAULT 0,
    packed_count int4 NOT NULL DEFAULT 0,
    generated_status int2 NULL GENERATED ALWAYS AS (calculate_status(placed_count, picked_count, packed_count)) STORED,
    CONSTRAINT table1_pk PRIMARY KEY (id),
);

功能

CREATE OR REPLACE FUNCTION calculate_status(
placed_count integer, 
picked_count integer, 
packed_count integer
)
 RETURNS integer
 LANGUAGE sql
 IMMUTABLE STRICT
AS $function$
select
    case
        when placed_count <= 0 then 1 --pending
        when packed_count = placed_count then 3 --packed
        when picked_count = placed_count then 2 --picked
        else 4 --else
    end
$function$
;

generated_status生成的列在某些记录中不是最新的,并且与使用该行中找到的相同值运行函数的结果不匹配。

SELECT count(*) FROM Table1 tt
WHERE generated_status  != 
calculate_status
(
  tt.placed_count, 
  tt.picked_count, 
  tt.packed_count
)

会传回正数。
我通常遇到问题的行是:
| 识别码|放置_计数|拾取_计数|压缩计数|生成的状态|
| - -|- -|- -|- -|- -|
| 一个|三个|三个|三个|2个|
| 2个|四个|四个|四个|2个|
当我将这些值输入到函数中时,它们确实返回3,但在我看来,生成的列有时并没有为最后放置的计数更新而更新,或者它的值被一些并发问题/争用条件覆盖。
什么可能是错误的,这并不经常发生(~30在100 k),但我需要这个状态总是最新的,否则它会造成一些麻烦。

dldeef67

dldeef671#

发生这种情况的唯一方法(除非有错误)是更改函数的定义。这样做不会导致重新计算预先存在的行的值。
更新:我能够复制这一点,并提交了a bug report,其中有复制器的情况下附加到它。

相关问题