pun*_*ish 5 postgresql types visibility
以下问题让我难过
SELECT string_agg(e.enumlabel, '|') as enum_value
FROM pg_type t
JOIN pg_enum e on t.oid = e.enumtypid
JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
WHERE typname = 'contacts'
above|below|lateral|lateral-bottom|lateral-top|within
CREATE TABLE unit_contacts
(
id integer NOT NULL DEFAULT nextval('unit_contacts_id_seq1'::regclass),
unit_id integer NOT NULL,
old_contact contacts NOT NULL,
contact contacts NOT NULL,
old_with_unit integer NOT NULL,
with_unit integer NOT NULL,
CONSTRAINT unit_contacts__pkey PRIMARY KEY (id )
)
WITH (
OIDS=FALSE
);
mm=> INSERT INTO unit_contacts VALUES (15, 1, 'below', 'below', 8112, 2);
ERROR: malformed record literal: "below"
LINE 1: ...SERT INTO unit_contacts VALUES (15, 1, 'below', '...
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚为什么我根本无法插入行.
显然,你正在陷入命名冲突.
缺失enum
值的错误消息是:
Run Code Online (Sandbox Code Playgroud)ERROR: invalid input value for enum rainbow: "below" LINE 1: INSERT INTO t VALUES (1, 'below');
您的错误消息显示存在同名的复合类型,这很可能源于同名的表.你应该避免使用相同的名字!
为了让大众重现,请考虑以下演示:
CREATE TYPE contacts AS ENUM ('above', 'below', 'lateral');
SELECT 'above'::contacts; -- all good, before the next step
CREATE TEMP TABLE contacts (id int, x text); -- !the crucial part
SELECT string_agg(e.enumlabel, '|') as enum_value
FROM pg_type t
JOIN pg_enum e on t.oid = e.enumtypid
WHERE t.typname = 'contacts'; -- all good
CREATE TEMP TABLE t (id int, r contacts);
INSERT INTO t VALUES (1, 'above'); -- ERROR
SELECT 'above'::contacts; -- same ERROR
Run Code Online (Sandbox Code Playgroud)
只有当enum
type和table(行类型)存在于两个不同的模式中时,才会发生这种情况.PostgreSQL不允许在同一模式中使用它们.在您的情况下,当您创建表时,具有表的模式(复合类型)的模式显然enum
位于search_path中 类型的模式之前.或许当时甚至不存在这种类型.看到:enum
在我的示例中,临时表首先出现,因为pg_temp
默认情况下架构首先出现在搜索路径中.当我创建表时,contacts
被解析为行类型(pg_temp.contacts
),而不是enum
类型(public.contacts
).
如果必须有一个表和一个enum
同名的表,请确保对正在使用的类型名称进行模式限定.在我的例子中:
pg_temp.contacts -- the composite type
public.contacts -- the enum type
Run Code Online (Sandbox Code Playgroud)