Search code examples
sqlarrayspostgresqlpostgresql-9.4

Syntax for array of nested composite type without using ARRAY[]


CREATE TYPE pencil_count AS(
    pencil_color varchar(30),
    count integer
);

CREATE TYPE pencil_count_with_date(
date_ date,
pencil_count pencil_count[]
);

CREATE TABLE pencils(id serial, pencils_ pencil_count_with_date[]);

INSERT INTO pencils(pencils_) 
VALUES('{"(\"2016-03-13\",{"(\"blue\",1)","(\"red\",2)"})"}');

What would be the correct syntax if I want to add this composite array without using ARRAY[...]?


Solution

  • Using literal string will be less readable when you add new nested levels:

    CREATE TYPE pencil_count AS(pencil_color varchar(30)
           ,"count" int);
    
    CREATE TYPE pencil_count_with_date AS(date_ date
                                         ,pencil_count pencil_count[]);
    
    CREATE TABLE pencils(id serial, pencils_ pencil_count_with_date[]);
    
    INSERT INTO pencils(pencils_) 
    VALUES('{"(
                   \"2016-03-13\",
                   \"{
                       \"\"(Blue,5)\"\",
                       \"\"(Red,2)\"\"
                   }\"
              )"}');   
    
    
    SELECT pencils_[1].pencil_count[1].pencil_color
    FROM pencils;
    

    SqlFiddleDemo

    Remarks:

    1. You need to quote each level with " escaped by \ based on nest level.
    2. This kind of schema looks like trying to introduce OO world to databases. It could be harder to maintain and slower than normalized version. Related question.
    3. You could quote string literals with $$ if needed.
    4. Using ARRAY and ROW could be easier to spot where each level starts and stops.