更改Postgres中的列类型会导致pg_attrdef警告

问题描述 投票:3回答:1

我们正在尝试将numeric(10,2)列类型更改为numeric(17,2)类型。当我们用天真的方法做到这一点时:

ALTER TABLE table_a ALTER COLUMN col_a SET DATA TYPE numeric(17,2);

我们得到了警告,我们不明白:

WARNING:  1 attrdef record(s) missing for rel table_a
WARNING:  generating possibly-non-unique OID for "pg_attrdef"

列类型确实正确地更改为numeric(17,2)(至少\d table_a告诉我们),我看不出结果表有什么问题,但警告仍然存在。

我们的表定义类似于:

                         Table "public.table_a"
         Column          |          Type          | Collation | Nullable | Default
-------------------------+------------------------+-----------+----------+---------
 col_a                   | numeric(10,2)          |           | not null | 0.00

在查阅postgres文档之后,我们首先删除了Default约束,然后尝试了另一个列:

ALTER TABLE table_a ALTER COLUMN col_b DROP DEFAULT;
ALTER TABLE table_a ALTER COLUMN col_b SET DATA TYPE numeric(17,2);
ALTER TABLE table_a ALTER COLUMN col_b SET DEFAULT 0.00; 

导致更多警告:

WARNING:  2 attrdef record(s) missing for rel table_a
WARNING:  generating possibly-non-unique OID for "pg_attrdef"

正如您在另一列上运行查询后所看到的,我们现在在pg_attrdef中缺少2条记录。在运行查询时,警告似乎会持续存在并随机显示。

我们检查了pg_attrdef表,看看我们是否能找到任何注意到:location内部表示中的adbin字段已设置为-1

adrelid | 37294
adnum   | 37
adbin   | {FUNCEXPR :funcid 1703 :funcresulttype 1700 :funcretset false :funcvariadic false :funcformat 2 :funccollid 0 :inputcollid 0 :args ({CONST :consttype 1700 :consttypmod -1 :constcollid 0 :constlen -1 :constbyval false :constisnull false :location -1 :constvalue 6 [ 24 0 0 0 0 -127 ]} {CONST :consttype 23 :consttypmod -1 :constcollid 0 :constlen 4 :constbyval true :constisnull false :location -1 :constvalue 4 [ 6 0 17 0 0 0 0 0 ]}) :location -1}
adsrc   | 0.00

但编译它:

select pg_get_expr(pa.adbin, 'table_a'::regclass) from pg_attrdef pa where adrelid = 37294 and adnum = 37;

工作并返回正确的0.00值。

一些进一步的背景信息:该表由Hibernate生成,列定义如下所示:

@Column(nullable = false, columnDefinition = "Decimal(10,2) default '0.00'")
private Double col_a = 0.0;

我正在PostgreSQL 10.0 DB上运行查询,但希望稍后在8.4 DB上运行它。

有人可以帮助我们弄清楚这些警告意味着什么,以及我们如何避免它们?

sql postgresql hibernate
1个回答
0
投票

服务器上的pg_catalog.attrdef表发生了某种情况,因此缺少应该出现在attrdef的oid列上的唯一索引。

你可以在这里看到警告https://github.com/postgres/postgres/blob/master/src/backend/catalog/catalog.c#L312

我读它是因为你发出的语句试图设置一个默认值,所以他们写入attrdef表。 Postgres有一个内置的假设,即目录表将在oid列上具有唯一索引,并在缺少某个索引时输出警告。我无法在我的v10盒子上重新创建,所以我认为有人已经删除了特定实例上的唯一索引。

似乎缺少的索引称为“pg_attrdef_oid_index”,因此如果在pg_catalog.pg_class中没有这个,则会出现问题。

除了您所看到的警告之外,可能没有任何后果。

尼尔

© www.soinside.com 2019 - 2024. All rights reserved.