1

How to add a unique index on text array column.

I have a column in my Postgres table which contains sections.

 +----+-----------+
 | id |  sections |
 |----|-----------|
 |  1 |['A', 'B'] |
 +----+-----------+
 |  2 |['A', 'A'] |
 +----+-----------+

As you can see for id 2 I can insert two sections with the same text. I do not want to add duplicate text. I do not want duplicate sections in my column. Is there a way I can add an index on text array.

I saw the examples for int array but can't find anything for text array

I do not want to create the new function. I want to use the existing function in Postgres.

4
  • 2
    You can't create a unique index over an array to prevent overlapping array elements. Normalize your model, then it is really eas Commented Oct 3, 2018 at 11:03
  • 1
    You would need a trigger for that, but it would be costly. Normalize your model as @a_horse_with_no_name mentioned. Commented Oct 3, 2018 at 11:07
  • Do you want to disallow duplicate values in a single row? As in the example above you don't allow to insert ['A', 'A'] into row 2 but ['A', 'B'] would be allowed. Or do you want to disallow adding a row with array containing A altogether given that there is a row with array having A? Commented Oct 3, 2018 at 11:12
  • I want to disallow duplicate values in the single row. EDIT: Actually both will work. Commented Oct 3, 2018 at 11:15

2 Answers 2

2

You can append into the sections column and unnest with distinct element like this:

update class set sections = array(
    select distinct unnest(
        array_append(
            (select section from class where id = 2), 'A'))
    where id = 2)
Sign up to request clarification or add additional context in comments.

Comments

0

I like arays and do not always it good to normalize tables :-)

CREATE OR REPLACE FUNCTION is_not_unique(a int[]) RETURNS bool AS $f$
   SELECT array_upper(a, 1) = array_upper(
               (
                SELECT array_agg(DISTINCT u)
                  FROM unnest(a) AS u
          ), 1);
$f$ LANGUAGE sql;

CREATE TEMP TABLE a (a int[], CHECK (is_not_unique(a)));

Test it:

# INSERT INTO a VALUES (ARRAY[1]);
INSERT 0 1
# INSERT INTO a VALUES (ARRAY[1, 2]);
INSERT 0 1
# INSERT INTO a VALUES (ARRAY[1, 1]);
ERROR:  new row for relation "a" violates check constraint "a_a_check"
DETAIL:  Failing row contains ({1,1}).

2 Comments

For integer, I achieved the solution before this question. I am looking for a text array solution. Thanks for the help :)
The same for text

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.