0
create table my_table(
id varchar(255) not null primary key,
text_column varchar(255) not null,
array_column text[] not null
);

My table state is

id|text_column|array_column|
--+-----------+------------+
1 |Abcd       |{a,b}       |
2 |Abcd       |{a}         |
3 |Xyz        |{a,b}       |

I would want this to fail

insert into my_table values ('4', 'Abcd', '{"b", "a"}');
insert into my_table values ('5', 'Abcd', '{"a", "b"}');

I am trying to impose the unique constraint on text_column and array_column.

Array_column is not sorted.

Also is it better way to do?

1
  • @LaurenzAlbe, I have updated it. Sorry for incomplete details Commented Dec 5, 2022 at 9:10

1 Answer 1

1

You could create an auxiliary function that sorts the elements of an array and use that in a unique index:

CREATE FUNCTION array_sort(anyarray) RETURNS anyarray
   IMMUTABLE LANGUAGE sql AS
'SELECT array_agg(a.e ORDER BY a.e) FROM unnest($1) AS a(e)';

CREATE UNIQUE INDEX ON my_table (text_column, array_sort(array_column));
Sign up to request clarification or add additional context in comments.

6 Comments

Thank you. I am trying to put sort as trigger, by passing column name. Just may be out of this context, can we pass column names dynamically to sort?
CREATE OR REPLACE FUNCTION my_table_sort_array() RETURNS trigger AS $BODY$ DECLARE column_name text := TG_ARGV[0]; BEGIN NEW.column_name = sort_array(column_name); RETURN NEW; END; $BODY$ LANGUAGE 'plpgsql';
Sure, that should work in a BEFORE trigger.
I tried, giving this error record "new" has no field "column_name". Its not recognizing the column name
Your trigger is wrong. But it should work in principle. And no, I am not going to fix your trigger in a comment. That is a different question.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.