Postgres - CRUD operations with arrays of composite types

蹲街弑〆低调 提交于 2020-01-25 06:48:09

问题


One really neat feature of Postgres that I have only just discovered is the ability to define composite type - also referred to in their docs as ROWS and as RECORDS. Consider the following example

CREATE TYPE dow_id AS
(
 tslot smallint,
 day smallint
);

Now consider the following tables

CREATE SEQUENCE test_id_seq INCREMENT 1 MINVALUE 1 MAXVALUE 2147483647 START 1 CACHE 1;

CREATE TABLE test_simple_array 
(
 id integer DEFAULT nextval('test_id_seq') NOT NULL,
 dx  integer []
);

CREATE TABLE test_composite_simple 
(
 id integer DEFAULT nextval('test_id_seq') NOT NULL,
 dx  dow_id
);

CREATE TABLE test_composite_array 
(
 id integer DEFAULT nextval('test_id_seq') NOT NULL,
 dx  dow_id[]
);

CRUD operations on the first two tables are relatively straightforward. For example

INSERT INTO test_simple_array (dx) VALUES ('{1,1}');
INSERT INTO test_composite_simple (dx) VALUES (ROW(1,1));

However, I have not been able to figure out how to perform CRUD ops when the table has an array of records/composite types as in test_composite_array. I have tried

INSERT INTO test_composite_array (dx) VALUES(ARRAY(ROW(1,1),ROW(1,2)));

which fails with the message

ERROR: syntax error at or near "ROW"

and

INSERT INTO test_composite_array (dx) VALUES("{(1,1),(1,2)}");

which fails with the message

ERROR: column "{(1,1),(1,2)}" does not exist

and

INSERT INTO test_composite_array (dx) VALUES('{"(1,1)","(1,2)"}');

which appears to work though it leaves me feeling confused since a subsequent

SELECT dx FROM test_composite_array

returns what appears to be a string result {"(1,1),(1,2)} although a further query such as

SELECT id FROM test_composite_array WHERE (dx[1]).tslot = 1;

works. I also tried the following

SELECT (dx[1]).day FROM test_composite_array;
UPDATE test_composite_array SET dx[1].day = 99 WHERE (dx[1]).tslot = 1;
SELECT (dx[1]).day FROM test_composite_array;

which works while

 UPDATE test_composite_array SET (dx[1]).day = 99 WHERE (dx[1]).tslot = 1;

fails. I find that I am figuring out how to manipulate arrays of records/composite types in Postgres by trial and error and - altough Postgres documentation is generally excellent - there appears to be no clear discussion of this topic in the documentation. I'd be much obliged to anyone who can point me to an authoritative discussion of how to manipulate arrays of composite types in Postgres.

That apart are there any unexpected gotchas when working with such arrays?


回答1:


You need square brackets with ARRAY:

ARRAY[ROW(1,1)::dow_id,ROW(1,2)::dow_id]

A warning: composite types are a great feature, but you will make your life harder if you overuse them. As soon as you want to use elements of a composite type in WHERE or JOIN conditions, you are doing something wrong, and you are going to suffer. There are good reasons for normalizing relational data.



来源:https://stackoverflow.com/questions/59812263/postgres-crud-operations-with-arrays-of-composite-types

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!