Перейти к содержанию

Справочник

Здесь собраны правила, которые в главах показаны на примерах. Приложение удобно держать под рукой, когда нужно быстро вспомнить, что допускает та или иная операция.

Все правила ниже проверяются при компиляции: если условие не выполнено, программа не соберётся, а компилятор сообщит, что именно не так.

Соответствие типов PostgreSQL и Haskell и то, как добавить свои типы, описано в приложении «Типы данных».

Операции по ключу

Для одной таблицы есть три операции, которые работают со строками по отдельности. Они различаются тем, что должно быть во входной записи, и тем, какой SQL выполняется.

Операция Что должно быть во входной записи SQL
insertSch все обязательные колонки insert
updateByKey полный первичный ключ или полный уникальный ключ update по ключу, без вставки
upsertByKey все обязательные колонки и полный первичный или уникальный ключ insert … on conflict (ключ) do update

Обязательными считаются колонки NOT NULL без значения по умолчанию. Если в записи есть первичный ключ, используется он, иначе — первый уникальный ключ, все колонки которого есть в записи. upsertByKey не принимает запись, в которой есть только ключ: для изменения строки по ключу без полного набора обязательных колонок нужен updateByKey.

Returning

Тип результата определяет, какие колонки попадут в returning. Для разных операций к нему предъявляются разные требования.

Операция Правило для типа результата
insertSch, upsertByKey обычная строка с любыми колонками таблицы; Maybe на всей строке запрещён
updateByKey обычная строка с любыми колонками таблицы; результат имеет тип [Maybe r] и идёт в том же порядке, что и вход (по одному элементу на запись); Nothing означает, что строки с таким ключом нет
insertJSON обычные строки на всех уровнях дерева; Maybe на строках запрещён
upsertJSON если во входной строке есть все обязательные колонки — строка без Maybe; иначе строка только изменяется по ключу и обязана быть Maybe, на любом уровне, включая корень; для дочерней строки со всеми обязательными колонками Maybe запрещён
updateJSON и корень, и элементы дочерних списков обязаны быть Maybe

Правила с Maybe на элементах дочерних списков относятся только к операциям над связанными таблицами (*JSON), а не к операциям с одной таблицей.

Если в upsertJSON или updateJSON строка по ключу не найдена, на её месте в результате будет Nothing, а длина списка совпадает с числом входных корней.

Ограничения

Часть данных pg-schema передаёт через JSON: вложенные ветки результата selectSch собираются в базе в JSON, а операции insertJSON, upsertJSON и updateJSON передают и получают всё дерево в jsonb. Поэтому типы полей в этих местах должны уметь превращаться в JSON и обратно. Отсюда главное ограничение: колонку bytea (тип Binary ByteString) можно читать и писать только в корне selectSch и в операциях с одной таблицей, но не во вложенных ветках и не в *JSON.

Для собственного типа в колонке json/jsonb нужны FromJSON и ToJSON, а для чтения в корне selectSch и для операций с одной таблицей — ещё FromField и ToField (их проще всего определить через fromJSONField и toJSONField).

Остальные ограничения, которые встречались в главах:

  • поддерживаются агрегатные функции count, min, max, sum и avg, а тип результата должен соответствовать типу, который возвращает SQL-функция;
  • qLimit, qOffset и qDistinct применяются только в корне запроса и в дочерних ветках, но не в ветке к родителю;
  • для связи таблицы с самой собой вместо qPath используются qPathFromHere и qPathToHere;
  • pin принимает непустой список (NonEmpty), для списка, который может быть пустым, есть pinArr;
  • глубина вложенности дерева ограничена числом в аннотации Ann;
  • условия, сортировка и ограничения из qPath применяются к полю результата с тем же именем связи и не попадают в запрос, если такого поля в типе нет.