Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct syntax for array of composite type

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

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

INSERT INTO pencils(pencils_) VALUES('{("blue",5),("red",2)}');

This doesn't work and gives error:

Malformed array literal.

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

like image 612
lowdegeneration Avatar asked Mar 12 '16 09:03

lowdegeneration


People also ask

What is composite type in SQL?

A composite type represents the structure of a row or record; it is essentially just a list of field names and their data types. PostgreSQL allows composite types to be used in many of the same ways that simple types can be used. For example, a column of a table can be declared to be of a composite type.

What is Unnest in PostgreSQL?

Unnest function generates a table structure of an array in PostgreSQL. Unnest array function is beneficial in PostgreSQL for expanding the array into the set of values or converting the array into the structure of the rows. PostgreSQL offers unnest() function.

What is table type in PostgreSQL?

In PostgreSQL, every table name serves as type name for the row type (a.k.a. composite type) automatically - not as table type, there are no "table types" or "table variables" in Postgres (but there are typed tables). So you can declare a variable of that type in PL/pgSQL .


1 Answers

Advice so far is not optimal. There is a simpler solution and an actually applicable explanation.
When in doubt, just ask Postgres to show you:

CREATE TEMP TABLE pencil_count (  -- table also registers row type
  pencil_color varchar(30)
, count integer
);

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

Insert 2 basic rows:

INSERT INTO pencil_count VALUES ('red', 1), ('blue', 2);

See the syntax for the basic row type:

SELECT p::text AS p_row FROM pencil_count p;

  p_row
----------
 (red,1)
 (blue,2)

See the syntax for an array of rows:

SELECT ARRAY(SELECT p FROM pencil_count p)::text AS p_row_arr;

       p_row_arr
------------------------
 {"(red,1)","(blue,2)"}

All you need is to enclose each row literal in double quotes - which is only necessary to disable the special meaning of the comma within each row type.
Additional (escaped) double quotes would be redundant noise while there are no additional special characters.

None of this has anything to do with escape string syntax, which has been turned off by default since Postgres 9.1. You would have to declare escape string syntax explicitly by prefixing E, like E'string\n'. But there is no good reason to do that.

db<>fiddle here
Old sqlfiddle

Related answer with more explanation:

  • Insert text with single quotes in PostgreSQL
  • How to pass custom type array to Postgres function
  • PL/pgSQL Array of Rows
like image 108
Erwin Brandstetter Avatar answered Sep 30 '22 23:09

Erwin Brandstetter