Является ли INSERT RETURNING гарантией возврата вещей в "правильном" порядке?

Пример:

create table foo(
    id serial, 
    txt text
);

insert into foo(txt) values ('a'),('b'),('c') returning id;

Возврат:

 id 
----
  1
  2
  3
(3 rows)

Кажется, что первый id в возвращаемом значении всегда будет id для 'a', второй для 'b' и т.д., но это определенное поведение insert into, или оно совпадение, которое может потерпеть неудачу при нечетных обстоятельствах?

Ответ 1

Я ничего не вижу в документации, которая гарантирует заказ для RETURNING, поэтому я не думаю, что вы можете зависеть от него. Вероятность того, что порядок RETURNING будет соответствовать порядку VALUES, но я не вижу никаких гарантий относительно того, какой порядок будет вставляться VALUES; VALUES почти наверняка будут вставляться в порядке слева направо, но опять же, нет документированной гарантии.

Кроме того, реляционная модель настроена так, что упорядочение является чем-то, применяемым пользователем, а не неотъемлемым свойством отношения. В общем случае, если нет возможности явно указывать порядок, нет никакого подразумеваемого упорядочения.

Выполнить резюме: порядок, который вы видите, вероятно, всегда будет, но он не гарантируется, поэтому не зависеть от него.

Ответ 2

Пока документация не совсем ясна, она заявляет, что:

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

Теперь "похожее на" не является железной гарантией, и я поднял это для обсуждения в списке рассылки... но на практике PostgreSQL не будет вмешиваться в порядок значений в RETURNING. Маловероятно, что мы когда-либо будем в состоянии, даже если мы хотим оптимизировать, потому что слишком много приложений полагаются на то, что оно упорядочено так же, как и вход.

Итак... для INSERT INTO ... VALUES (...), (...), ... RETURNING ... и для INSERT INTO ... SELECT ... ORDER BY ... RETURNING ... должно быть безопасно предположить, что отношение результата находится в том же порядке, что и вход.

Ответ 3

Пока это вам не поможет, 9.1 будет включать "записываемые общие табличные выражения" . Это официальное название синтаксиса WITH. ( Wikipedia.)

Эта новая возможность должна помещать ваш INSERT ... RETURNING внутри WITH, давать псевдоним, а затем SELECT против него с определенным порядком с простым старым предложением ORDER BY.