Detailed use of Postgres array array type

Keywords: PostgreSQL

// This article mainly refers to Deco's articles, links:
http://blog.163.com/digoal@126/blog/static/163877040201201275922529/

This article by De Ge is very good. I have some explanations in the related function section, especially in the array_upper,array_lower section.

The ARRAY type contains several important features

  • dimension
    In other words, a multi-dimensional array, no matter how it is assigned, ARRAY must ultimately be a matrix.
Example 1: 
ARRAY[1,2,3,4] is a one-dimensional array.
ARRAY[[1,2],[3,4],[5,6]] is a two-dimensional array.

Example 2: 
ARRAY[['digoal','zhou'],['a','b',c'] is wrong. Because the first array in the second dimension has two elements and the second array has three elements. It is not a matrix. The number must be the same.
At the same time, the types must be consistent.

Example 3: 
ARRAY[['digoal','zhou'],[1,2]] is wrong. Because ['digoal','zhou'] is text [] type, and [1,2] is int [] type.
  • element
    The four elements in one-dimensional array ARRAY[1,2,3,4] are 1, 2, 3, 4. The values of these int types.

    The first dimension of two-dimensional array ARRAY[[1,2],[3,4],[5,6]] has three elements: ARRAY [1,2], ARRAY [3,4], and ARRAY [5,6]. The first subscript of the second dimension has two elements, one is 1,2. The second subscript is 3,4. The third subscript is 5,6.
    The separators between elements are commas, except that the box type is a sign.

  • Extensibility
    One-dimensional arrays can be extended, but two-dimensional arrays can not.
    Reference resources http://blog.163.com/digoal@126/blog/static/163877040201201272718196/

  • subscript
    Accessing elements in ARRAY requires a subscript value. The default number is from 1. Unless subscript is mandatory at assignment time
    Example 1:

ARRAY[[1,2],[3,4],[5,6]] as a
a[1][1] = 1;
a[1][2] = 2;
a[2][1] = 3;
a[2][2] = 4;
a[3][1] = 5;
a[3][2] = 6;
a First[]Represents the first dimension, The numbers inside represent what is accessed in the first dimension. subscript,
a The second[]Represents the second dimension, The numbers inside represent what is accessed in the second dimension. subscript,
//You can also visit ARRAY's slice.

Example 2:

a[1:2][1:1] = {{1},{3}}
In the first [], 1 represents low subscript and 2 represents high subscript.
In the second [] 1 on the left represents the low subscript and 1 on the right represents the high subscript.
a[2:3][1:2] = {{3,4},{5,6}}
Another way to write fragments is that if one of the dimensions is written in fragments, the other dimensions are deemed to be high by default if they are not written in fragments.
If a[2:3][2] is equivalent to a[2:3][1:2]
  • Next, I will explain some common functions of ARRAY type:
array_dims, Returns the lowest position in each dimension. subscript And high subscript, as follows : 
digoal=> select array_dims(ARRAY[[1,2,3,4,5],[6,7,8,9,10]]);
 array_dims 
---------+--
 [1:2][1:5]
array_length, What's returned is array The length or number of elements specified in the dimension, as follows : 
digoal=> select array_length(ARRAY[[1,2,3,4,5],[6,7,8,9,10]], 1);
 array_length 
-------+------
            2
digoal=> select array_length(ARRAY[[1,2,3,4,5],[6,7,8,9,10]], 2);
 array_length 
--------+-----
            5
Note: Both array_lower and array_upper return values are subscripts, defaulting to subscripts starting from 1.
array_lower, returns the low subscript value of the specified dimension in ARRAY, as follows: 
digoal=> select array_lower(ARRAY[[1,2,3,4,5],[6,7,8,9,10]], 2);
 array_lower 
--------+----
           1
 The following is to force the subscript value to be specified. 
digoal=> select array_lower('[-3:-2]={1,2}'::int[], 1);
 array_lower 
---------+----
          -3
array_upper, which returns the high subscript value of the specified dimension in ARRAY, is as follows:
digoal=> select array_upper(ARRAY[[1,2,3,4,5],[6,7,8,9,10]], 2);
 array_upper 
--------+----
           5
 The following is to force the subscript value to be specified. 
digoal=> select array_upper('[-3:-2]={1,2}'::int[], 1);
 array_upper 
--------+----
          -2
array_prepend, Used to insert elements in front of a one-dimensional array, as follows
digoal=> select array_prepend('digoal', ARRAY['francs','david']);
     array_prepend     
-------------------+---
 {digoal,francs,david}
array_append, For inserting elements after a one-dimensional array, as follows
digoal=> select array_append(ARRAY['francs','david'], 'digoal');
     array_append      
---------------+-------
 {francs,david,digoal}
array_cat, Connection for two arrays of the same dimension, Or one n Dimensional arrays and one n+1Connection of Dimensional Arrays, as follows
digoal=> select array_cat(ARRAY['francs'], ARRAY['digoal','david']);
       array_cat       
----------------+------
 {francs,digoal,david}
digoal=> select array_cat(ARRAY['francs'], ARRAY[['digoal']]);
      array_cat      
-----------------+---
 {{francs},{digoal}}
generate_subscripts, Used for sequential return ARRAY Designated Dimensional subscript(s)value, as follows : 
//Returns the subscript value of the first dimension forward.
digoal=> select generate_subscripts(a, 1) from (select ARRAY['a','b','c','d'] as a) t;
 generate_subscripts 
---------------+-----
                   1
                   2
                   3
                   4
//Returns the subscript value of the first dimension in reverse.
digoal=> select generate_subscripts(a, 1, true) from (select ARRAY['a','b','c','d'] as a) t;
 generate_subscripts 
-----------------+--
                   4
                   3
                   2
                   1
digoal=> select generate_subscripts(a, 1) from (select '[-5:-1]={1,2,3,4,5}'::int[] as a) t;
 generate_subscripts 
---------------+-----
                  -5
                  -4
                  -3
                  -2
                  -1
digoal=> select generate_subscripts(a, 1, true) from (select '[-5:-1]={1,2,3,4,5}'::int[] as a) t;
 generate_subscripts 
---------------+-----
                  -1
                  -2
                  -3
                  -4
                  -5
//The second dimension of a multidimensional array,
digoal=> select generate_subscripts(a, 2) from (select '[-5:-4][2:4]={{1,2,3},{4,5,6}}'::int[] as a) t;
 generate_subscripts 
---------------+-----
                   2
                   3
                   4
  • Next, I'll explain the ARRAY type operators.
digoal=> select typname,oid from pg_type where typname='anyarray';
 typname  | oid  
----------+------
 anyarray | 2277
The operator is as follows : 
digoal=> select oprname,oprleft,oprright,oprresult,oprcode,oprrest,oprjoin from pg_operator where oprleft=2277 or oprright=2277;
 oprname | oprleft | oprright | oprresult |    oprcode     |   oprrest   |     oprjoin     
---------+---------+----------+-----------+----------------+-------------+-----------------
 ||      |    2277 |     2283 |      2277 | array_append   | -           | -
 ||      |    2283 |     2277 |      2277 | array_prepend  | -           | -
 ||      |    2277 |     2277 |      2277 | array_cat      | -           | -
 =       |    2277 |     2277 |        16 | array_eq       | eqsel       | eqjoinsel
 <>      |    2277 |     2277 |        16 | array_ne       | neqsel      | neqjoinsel
 <       |    2277 |     2277 |        16 | array_lt       | scalarltsel | scalarltjoinsel
 >       |    2277 |     2277 |        16 | array_gt       | scalargtsel | scalargtjoinsel
 <=      |    2277 |     2277 |        16 | array_le       | scalarltsel | scalarltjoinsel
 >=      |    2277 |     2277 |        16 | array_ge       | scalargtsel | scalargtjoinsel
 &&      |    2277 |     2277 |        16 | arrayoverlap   | areasel     | areajoinsel
 @>      |    2277 |     2277 |        16 | arraycontains  | contsel     | contjoinsel
 <@      |    2277 |     2277 |        16 | arraycontained | contsel     | contjoinsel
(12 rows)
[Attention]
- There are no restrictions on ARRAY-type dimensions in PostgreSQL. For example, int [] does not mean that only one-dimensional arrays can be stored. In fact, ARRAY values of any dimension can be stored.
- PostgreSQL does not limit the number of elements in ARRAY type, such as int[10], which does not mean that only 10 elements can be stored. It can be exceeded.
For example: 
digoal=> create table array_test (id int[2]);
CREATE TABLE
digoal=> insert into array_test values (ARRAY[[1,2,3,4,5],[6,7,8,9,10]]);
INSERT 0 1
 In this example, the number and dimension of elements exceed the limit of int[2], but there is no error, and the data has been stored.
digoal=> select * from array_test ;
             id             
---------------------+------
 {{1,2,3,4,5},{6,7,8,9,10}}

The explanations in the manual are as follows:

However, the current implementation ignores any supplied array size limits, i.e., the behavior is the same as for arrays of unspecified length.

The current implementation does not enforce the declared number of dimensions either. Arrays of a particular element type are all considered to be of the same type, regardless of size or number of dimensions. So, declaring the array size or number of dimensions in CREATE TABLE is simply documentation; it does not affect run-time behavior.

Posted by dwees on Sun, 16 Jun 2019 12:56:07 -0700