Size: a a a

pgsql – PostgreSQL

2020 June 27

s

sexst in pgsql – PostgreSQL
Артур Семенов
SQL Error [42601]: ОШИБКА: ошибка синтаксиса (примерное положение: "exchange")
 Позиция: 32
А у вас enterprisedb стоит?
источник

АС

Артур Семенов... in pgsql – PostgreSQL
sexst
А у вас enterprisedb стоит?
Стоит обычная, бесплатная
источник

s

sexst in pgsql – PostgreSQL
Артур Семенов
Стоит обычная, бесплатная
Непонятно тогда откуда вы взяли alter table ... exchange partitions. Оно только в enterprisedb есть. А в постгресе даже документация такого не содержит.
https://postgrespro.ru/docs/postgresql/12/sql-altertable#
источник

АС

Артур Семенов... in pgsql – PostgreSQL
sexst
Непонятно тогда откуда вы взяли alter table ... exchange partitions. Оно только в enterprisedb есть. А в постгресе даже документация такого не содержит.
https://postgrespro.ru/docs/postgresql/12/sql-altertable#
В просторах интернета достаточно гайдов где в постгресе делают обмен партициями
источник

АС

Артур Семенов... in pgsql – PostgreSQL
sexst
Непонятно тогда откуда вы взяли alter table ... exchange partitions. Оно только в enterprisedb есть. А в постгресе даже документация такого не содержит.
https://postgrespro.ru/docs/postgresql/12/sql-altertable#
И правда, все эти статьи для enterprise db
Тогда подскажите наиболее эффективный спосов вставки данных в партицированную таблицу (если делать обмен нельзя)

Я просто с Оракла )
источник

s

sexst in pgsql – PostgreSQL
Артур Семенов
И правда, все эти статьи для enterprise db
Тогда подскажите наиболее эффективный спосов вставки данных в партицированную таблицу (если делать обмен нельзя)

Я просто с Оракла )
Ну так это же по сути синтаксический сахар поверх detach-rename-attach в транзакции. Если нужно именно поменять имеющуюся партицию с отдельной таблицей местами, то можно сделать как-то так.

CREATE TABLE measurement (
   city_id         int not null,
   logdate         date not null,
   peaktemp        int,
   unitsales       int
) PARTITION BY RANGE (logdate);
CREATE TABLE measurement_y2006m02 PARTITION OF measurement
   FOR VALUES FROM ('2006-02-01') TO ('2006-03-01');

CREATE TABLE measurement_y2006m03 PARTITION OF measurement
   FOR VALUES FROM ('2006-03-01') TO ('2006-04-01');

CREATE TABLE measurement_y2006m04 PARTITION OF measurement
   FOR VALUES FROM ('2006-04-01') TO ('2006-05-01');

-- Заполняем заменяемую позже партицию
insert into measurement values(1,'2006-03-02',0,0);

--Создаём таблицу для обмена с партицией
CREATE TABLE measurement_y2006m03_2
 (LIKE measurement INCLUDING DEFAULTS INCLUDING CONSTRAINTS);
ALTER TABLE measurement_y2006m03_2 ADD CONSTRAINT y2006m03
  CHECK ( logdate >= DATE '2006-03-01' AND logdate < DATE '2006-04-01' );

-- Заполняем новую таблицу чем нужно
insert into measurement_y2006m03_2 values(2,'2006-03-02',1,1), values(3,'2006-03-03',2,2);

--Меняем местами живую партицию и новую исправленную в транзакции (имена меняю по сути для красоты)
BEGIN;
ALTER TABLE measurement DETACH PARTITION measurement_y2006m03;
ALTER TABLE measurement_y2006m03 RENAME TO measurement_y2006m03_old;
ALTER TABLE measurement_y2006m03_2 RENAME TO measurement_y2006m03;
ALTER TABLE measurement ATTACH PARTITION measurement_y2006m03 FOR VALUES FROM ('2006-03-01') TO ('2006-04-01');
ALTER TABLE measurement_y2006m03_old RENAME TO measurement_y2006m03_2;
COMMIT;

Всё, поменяли местами.
Или нужно вообще пустую партиционированную таблицу (или партицию таблицы) заполнить даннымы?
источник

s

sexst in pgsql – PostgreSQL
Такой функционал малой кровью можно добавить по идее, просто он не настолько вроде и востребован чтобы сахаром обмазывать.


А, да.  Вот это вот в новой таблице:
ALTER TABLE measurement_y2006m03_2 ADD CONSTRAINT y2006m03
  CHECK ( logdate >= DATE '2006-03-01' AND logdate < DATE '2006-04-01' );
Вешается, чтобы при её добавлении в качестве партиции, не нужно было сканировать таблицу и проверять  ограничения секции. удерживая блокировку ACCESS EXCLUSIVE в секции и SHARE UPDATE EXCLUSIVE в родительской таблице.  После выполнения команды ATTACH PARTITION это ставшее ненужным ограничение CHECK при желании можно удалить.
источник

АС

Артур Семенов... in pgsql – PostgreSQL
sexst
Ну так это же по сути синтаксический сахар поверх detach-rename-attach в транзакции. Если нужно именно поменять имеющуюся партицию с отдельной таблицей местами, то можно сделать как-то так.

CREATE TABLE measurement (
   city_id         int not null,
   logdate         date not null,
   peaktemp        int,
   unitsales       int
) PARTITION BY RANGE (logdate);
CREATE TABLE measurement_y2006m02 PARTITION OF measurement
   FOR VALUES FROM ('2006-02-01') TO ('2006-03-01');

CREATE TABLE measurement_y2006m03 PARTITION OF measurement
   FOR VALUES FROM ('2006-03-01') TO ('2006-04-01');

CREATE TABLE measurement_y2006m04 PARTITION OF measurement
   FOR VALUES FROM ('2006-04-01') TO ('2006-05-01');

-- Заполняем заменяемую позже партицию
insert into measurement values(1,'2006-03-02',0,0);

--Создаём таблицу для обмена с партицией
CREATE TABLE measurement_y2006m03_2
 (LIKE measurement INCLUDING DEFAULTS INCLUDING CONSTRAINTS);
ALTER TABLE measurement_y2006m03_2 ADD CONSTRAINT y2006m03
  CHECK ( logdate >= DATE '2006-03-01' AND logdate < DATE '2006-04-01' );

-- Заполняем новую таблицу чем нужно
insert into measurement_y2006m03_2 values(2,'2006-03-02',1,1), values(3,'2006-03-03',2,2);

--Меняем местами живую партицию и новую исправленную в транзакции (имена меняю по сути для красоты)
BEGIN;
ALTER TABLE measurement DETACH PARTITION measurement_y2006m03;
ALTER TABLE measurement_y2006m03 RENAME TO measurement_y2006m03_old;
ALTER TABLE measurement_y2006m03_2 RENAME TO measurement_y2006m03;
ALTER TABLE measurement ATTACH PARTITION measurement_y2006m03 FOR VALUES FROM ('2006-03-01') TO ('2006-04-01');
ALTER TABLE measurement_y2006m03_old RENAME TO measurement_y2006m03_2;
COMMIT;

Всё, поменяли местами.
Или нужно вообще пустую партиционированную таблицу (или партицию таблицы) заполнить даннымы?
В Оракле, например эффективнее производить вставку в пустую таблицу (внутрь партиции)  а потом в секунду делать обмен without validation

Путем простого инсерта в постргесе в партицированную таблицу, в моем понимании такого трюка не добиться
источник

s

sexst in pgsql – PostgreSQL
Артур Семенов
В Оракле, например эффективнее производить вставку в пустую таблицу (внутрь партиции)  а потом в секунду делать обмен without validation

Путем простого инсерта в постргесе в партицированную таблицу, в моем понимании такого трюка не добиться
Ну вот это по сути и есть пустая таблица, кууда можно напихать данных через тот же /COPY
CHECK CONSTRAINT валидацию отключает при присоединении её как партиции. Транзакция меняет местами с уже имеющейся партицией с таким же ключём секционирования.
Если партиции с таким же ключом и не висело, то можно просто attach partition без транзакций сделать и всё.
источник

s

sexst in pgsql – PostgreSQL
В общем это то же самое, просто hand-driven и писать чуть больше.
источник

E

Eugen in pgsql – PostgreSQL
Вечер добрый.
Кто нибудь знает, можно ли передать ссылку на CTE в функцию?

WITH xxx as ( select * from (values (1,2)) as t(id) )
select * from my_fn( 'xxx' );
источник

YS

Yaroslav Schekin in pgsql – PostgreSQL
Eugen
Вечер добрый.
Кто нибудь знает, можно ли передать ссылку на CTE в функцию?

WITH xxx as ( select * from (values (1,2)) as t(id) )
select * from my_fn( 'xxx' );
Нет, нельзя.
источник

E

Eugen in pgsql – PostgreSQL
Yaroslav Schekin
Нет, нельзя.
эх... прийдётся тогда через TEMP TABLE делать ((
источник

Д

Диман in pgsql – PostgreSQL
Eugen
эх... прийдётся тогда через TEMP TABLE делать ((
Не надо стремиться сделать все в один стейтмент. Поверьте, это не есть круто. Вы и себе проблему создаёте на ровном месте и коллегам вне контекста вашей задачи жизнь усложняете в понимании в дальнейшем вашего кода. :)
источник

E

Eugen in pgsql – PostgreSQL
Диман
Не надо стремиться сделать все в один стейтмент. Поверьте, это не есть круто. Вы и себе проблему создаёте на ровном месте и коллегам вне контекста вашей задачи жизнь усложняете в понимании в дальнейшем вашего кода. :)
А как тогда одинаковые части запроса вынести в функцию?
https://dbfiddle.uk/?rdbms=postgres_12&fiddle=5133205697d121dc9bcb063ba3380d66
источник

E

Eugen in pgsql – PostgreSQL
источник

Д

Диман in pgsql – PostgreSQL
После saldoanal'a ничего не могу уже посоветовать.)))
источник

E

Eugen in pgsql – PostgreSQL
😁
источник

Д

Диман in pgsql – PostgreSQL
Не стройте 100500 этажей. Сохраняйте во вре енные таблицы. Нелогируемые к примеру, если боитесь на скорости проиграть.
источник

Д

Диман in pgsql – PostgreSQL
Не надейтесь что функция развернется|не развернётся на этапе оптимизации. Два эти варианта одинаково могут как ускорить так и замедлить исполнение предполагаемой задачи.
источник