intarray

Функции и операторы для работы с массивами целых чисел без NULL.
Схема размещения: ext.
Модуль предоставляет несколько полезных функций и операторов для работы с одномерными целочисленными массивами (1-D integer arrays). Если в массиве присутствует значение NULL, операция выдаст ошибку. Также поддерживается поиск по индексу для ряда операторов.
Модуль поддерживает проверку равенства массивов, а также индексы для операторов:
  • && – пересечение;
  • @> – левый содержит правый;
  • <@ – правый содержит левый;
  • @@, ~~ – соответствие запросу.
Операторы &&, @> и <@ работают только с не содержащими NULL целочисленными массивами. Благодаря этому ограничению, в большинстве случаев они работают быстрее, чем равнозначные одноименные встроенные операторы PostgreSQL, которые работают с массивами любых типов.
Операторы @@ и ~~ проверяют, удовлетворяет ли массив запросу, представляемому в виде значения специализированного типа данных query_int. Запрос содержит целочисленные значения, возможно с использованием операторов & (AND), | (OR) и ! (NOT). Например, запросу 1&(2|3) удовлетворяют массивы, которые содержат 1 и также содержат 2 или 3.
Выражение запроса заключается в одинарные кавычки (апострофы). Пример: '1&(2|3)'.

Функции

ФункцияВходные параметрыВозвращаемое значениеОписание
icount
integer[]integerВыдает число элементов в массиве
sort
integer[], dir textinteger[]Сортирует массив в порядке возрастания или убывания в зависимости от значения параметра dir: asc – по возрастанию или desc – по убыванию
sort
integer[]integer[]Сортирует в порядке возрастания
sort_asc
integer[]integer[]Сортирует в порядке возрастания
sort_desc
integer[]integer[]Сортирует в порядке убывания
uniq
integer[]integer[]Удаляет стоящие рядом дубликаты
idx
integer[], item integerintegerВозвращает порядковый номер (индекс) первого равного значению item элемента массива или 0 в случае отсутствия элемента со значением item
subarray
integer[], start integer [, len integer]integer[]Извлекает часть массива, которая начинается с позиции start и содержит len элементов; параметр len можно опустить, тогда будет извлечена часть массива, которая начинается с позиции start и до конца
intset
integerinteger[]Создает массив с одним элементом

Операторы

ОператорВозвращаемое значениеОписаниеПримечание
integer[] && integer[]
booleanПересекаются ли массивы; true – имеется минимум один общий элемент
integer[] @> integer[]
booleanПравый массив содержится в левом
integer[] <@ integer[]
booleanЛевый массив содержится в правом
# integer[]
integerВозвращает число элементов в массивеАналогичная функция – icount
integer[] # integer
integerВозвращает индекс первого элемента, равного правому аргументу, или 0, если такого элемента нетАналогичная функция – idx
integer[] + [integer | integer[]]
integer[]Соединение: добавляет элемент в конец массива или соединяет два массиваВ качестве правого аргумента может быть целое число или массив
integer[] - [integer | integer[]]
integer[]Вычитание: удаляет элемент из массива или из левого массива удаляет элементы правого массиваВ качестве правого аргумента может быть целое число или массив
integer[] | [integer | integer[]]
integer[]Вычисляет объединение аргументовВ качестве правого аргумента может быть целое число или массив
integer[] & integer[]
integer[]Вычисляет пересечение аргументов
integer[] @@ query_int
booleanУдовлетворяет ли массив запросу; запрос представлен в виде значения специализированного типа данных query_intПример: запросу 1&(2|3) удовлетворяют запросы, которые содержат 1 И также содержат 2 ИЛИ 3
query_int ~~ integer[]
booleanУдовлетворяет ли массив запросу; коммутирующий оператор к @@; запрос представлен в виде значения специализированного типа данных query_intЗапрос содержит целочисленные значения, сравниваемые с элементами массива, возможно с использованием операторов & (AND), | (OR) и ! (NOT)

Индексы

Модуль поддерживает индексы для операторов &&, @>, <@ и @@, а также проверку равенства массивов.
Модуль предоставляет два параметризованных класса операторов GiST:
  • gist__int_ops (используется по умолчанию) подходит для небольших по размеру наборов данных (массивов); этот класс аппроксимирует набор целых чисел в виде массива диапазонов; в его параметре numranges можно задать максимальное число диапазонов в одном ключе индекса (параметр необязательный, целочисленный и может принимать значения от 1 до 253, по умолчанию равен 100); при увеличении числа составляющих ключ индекса GiST массивов поиск работает точнее из-за того, что сканируется меньшая область в индексе и меньше страниц массива, но сам индекс при этом становится больше;
  • gist__intbig_ops применяет сигнатуру большего размера и подходит для индексации больших наборов данных (массивов), то есть содержащих много различных значений массива столбцов; этот класс аппроксимирует набор целых чисел в виде сигнатуры битовой карты; в его параметре siglen можно задать размер сигнатуры в байтах (параметр необязательный, целочисленный и может принимать значения от 1 до 2024, по умолчанию равен 16); при увеличении размера сигнатуры поиск работает точнее из-за того, что сканируется меньшая область в индексе и меньше страниц массива, но сам индекс становится больше;
  • gin__int_ops – нестандартный класс операторов GIN, поддерживающий те же операторы.

Использование модуля

Значения массива можно вводить разными способами, которые являются идентичными:
  • '{1,2,3,5}'::integer[];
  • array [1,2,3,5].
В примерах будут использоваться оба способа.
Функции:
  • icount:
    SELECT icount('{1,223,303,5,33}'::integer[]);
    Другой способ представления массива:
    SELECT icount(array [1,223,303,5,33]);
    Пример вывода:
    Раскрыть type=sql
     icount
    --------
          5
    (1 row)
    
  • sort:
    Пример в порядке убывания:
    SELECT sort('{1,223,303,5,33}'::integer[], 'desc');
    Пример вывода:
    Раскрыть type=sql
           sort
    ------------------
     {303,223,33,5,1}
    (1 row)
    
    Пример в порядке возрастания без параметра dir:
    SELECT sort(array[1,223,303,5,33]);
    Пример вывода:
    Раскрыть type=sql
           sort
    ------------------
     {1,5,33,223,303}
    (1 row)
    
  • sort_asc:
    SELECT sort_asc (array[1,223,303,5,33]);
    Пример вывода:
    Раскрыть type=sql
         sort_asc
    ------------------
     {1,5,33,223,303}
    (1 row)
    
  • sort_desc:
    SELECT sort_desc (array[1,223,303,5,33]);
    Пример вывода:
    Раскрыть type=sql
        sort_desc
    ------------------
     {303,223,33,5,1}
    (1 row)
    
  • uniq:
    SELECT uniq('{1,1,223,303,5,5,332,2,2,2,3,1,1}'::integer[]);
    Пример вывода:
    Раскрыть type=sql
              uniq
    -------------------------
     {1,223,303,5,332,2,3,1}
    (1 row)
    
    Использование в сочетании с функцией sort для удаления всех дубликатов:
    SELECT uniq(sort('{1,1,1,223,303,5,5,332,2,2,2,3,1,1}'::integer[]));
    Пример вывода:
    Раскрыть type=sql
             uniq
    -----------------------
     {1,2,3,5,223,303,332}
    (1 row)
    
  • idx:
    Элемент со значением item присутствует в массиве:
    SELECT idx(array[1,223,303,5,33], 5);
    Пример вывода:
    Раскрыть type=sql
     idx
    -----
       4
    (1 row)
    
    Элемента со значением item нет в массиве:
    SELECT idx(array[1,223,303,5,33], 6);
    Пример вывода:
    Раскрыть type=sql
     idx
    -----
       0
    (1 row)
    
  • subarray:
    Извлечение части массива, начиная с позиции 3 длиной в 4 элемента:
    SELECT subarray('{1,2,3,4,5,4,3}'::integer[], 3, 4);
    Пример вывода:
    Раскрыть type=sql
     subarray
    -----------
     {3,4,5,4}
    (1 row)
    
    Применение функции без указания параметра длины извлекаемой части массива len:
    SELECT subarray('{1,2,3,4,5,4,3}'::integer[], 3);
    Пример вывода:
    Раскрыть type=sql
     subarray
    -----------
     {3,4,5,4,3}
    (1 row)
    
  • intset:
    SELECT intset(233);
    Пример вывода:
    Раскрыть type=sql
     intset
    --------
     {233}
    (1 row)
    
Операторы:
  • пересечение:
    • Есть пересечение:
      SELECT '{1,2,3,4,5,4,3}'::integer[] && '{1,4,6}'::integer[];
      Пример вывода:
      Раскрыть type=sql
       ?column?
      ----------
       t
      (1 row)
      
    • Нет пересечения:
      SELECT '{1,2,3,4,5,4,3}'::integer[] && '{12,33}'::integer[];
      Пример вывода:
      Раскрыть type=sql
        ?column?
      ----------
       f
      (1 row)
      
  • содержание одного массива в другом:
    • правый массив содержится в левом:
      SELECT '{1,2,3,4,5,4,3}'::integer[] @> '{4,5,4}'::integer[];
      Пример вывода:
      Раскрыть type=sql
       ?column?
      ----------
       t
      (1 row)
      
    • левый массив содержится в правом:
      SELECT '{2,3,8}'::integer[] <@ '{1,2,3,4,5,4,3}'::integer[];
      Пример вывода:
      Раскрыть type=sql
       ?column?
      ----------
       f
      (1 row)
      
  • добавление элемента в конец массива:
    SELECT '{14,54}'::integer[] + 34;
    Пример вывода:
    Раскрыть type=sql
      ?column?
    ------------
     {14,54,34}
    (1 row)
    
  • соединение двух массивов:
    SELECT '{14,54}'::integer[] + '{2,3,8}'::integer[];
    Пример вывода:
    Раскрыть type=sql
       ?column?
    ---------------
     {14,54,2,3,8}
    (1 row)
    
  • удаление элемента из массива:
    SELECT '{14,54,34}'::integer[] - 54;
    Пример вывода:
    Раскрыть type=sql
     ?column?
    ----------
     {14,34}
    (1 row)
    
  • удаление элементов правого массива из левого:
    SELECT '{2,2,18,3,3,66,3}'::integer[] - '{2,3,8}'::integer[];
    Пример вывода:
    Раскрыть type=sql
     ?column?
    ----------
     {18,66}
    (1 row)
    
  • объединение аргументов:
    • объединение с элементом:
      SELECT array[2,4,8,66] | 55;
      Пример вывода:
      Раскрыть type=sql
         ?column?
      ---------------
       {2,4,8,55,66}
      (1 row)
      
    • объединение с массивом:
      SELECT array[2,4,8,66] | array[1,3,55];
      Пример вывода:
      Раскрыть type=sql
           ?column?
      -------------------
       {1,2,3,4,8,55,66}
      (1 row)
      
  • пересечение аргументов:
    SELECT '{2,18,3,66}'::integer[] & '{2,3,8}'::integer[];
    Пример вывода:
    Раскрыть type=sql
     ?column?
    ----------
     {2,3}
    (1 row)
    
  • соответствие запросу:
    • проверка по запросу – оператор @@:
      SELECT '{2,18,3,66}'::integer[] @@ '2&(5|6)';
      Пример вывода:
      Раскрыть type=sql
       ?column?
      ----------
       f
      (1 row)
      
    • Проверка по запросу – оператор ~~:
      SELECT '3&(18|6)' ~~ '{2,18,3,66}'::integer[];
      Пример вывода:
      Раскрыть type=sql
       ?column?
      ----------
       t
      (1 row)
      
Индексы (в примере сообщение (message) может относиться к одной или нескольким «секциям» (sections)):
  1. Создать таблицу, индекс с длиной сигнатуры 32 байта и наполнить тестовыми данными:
    Раскрыть type=sql
    CREATE TABLE message (
       mid INT PRIMARY KEY,
       sections INT[],
       name text
       );
    CREATE INDEX message_rdtree_idx ON message USING GIST
                (sections gist__intbig_ops (siglen = 32));
    INSERT INTO message VALUES (1, array[3,4], 'Hi, World!'),
                               (2, array[1,4], 'Hello! World!'),
                               (3, array[1,2], 'Hi, my World!'),
                               (4, array[2,5], 'O, my World!');
    
  2. Вывести сообщения из секций 1 или 2 — оператор пересечения &&:
    SELECT message.mid FROM message WHERE message.sections && '{1,2}';
    Пример вывода:
    Раскрыть type=sql
     mid
    -----
       2
       3
       4
    (3 rows)
    
  3. Вывести сообщения из секций 1 и 2 — оператор включения @>:
    SELECT message.mid FROM message WHERE message.sections @> '{1,2}';
    Пример вывода:
    Раскрыть type=sql
     mid
    -----
       3
    (1 row)
    
  4. Применить оператор запроса – query_int = 1 И 2:
    SELECT message.mid FROM message WHERE message.sections @@ '1&2'::query_int;
    Пример вывода:
    Раскрыть type=sql
     mid
    -----
       3
    (1 row)
    
  5. Применить оператор запроса – query_int = 1 ИЛИ 2:
    SELECT message.mid FROM message WHERE message.sections @@ '1|2'::query_int;
    Пример вывода:
    Раскрыть type=sql
     mid
    -----
       2
       3
       4
    (3 rows)
    

Ссылки на документацию разработчика

Дополнительную информацию по поставляемому модулю intarray можно получить по ссылке.
Предыдущий раздел
intagg
Следующий раздел
isn
Была ли страница полезной?