mirror of
https://github.com/postgres/postgres.git
synced 2026-10-23 13:29:09 +03:00
Reject REPACK (ANALYZE) in a transaction block
The current implementation doesn't support it correctly, leading to mysterious warnings and some worse problems. Have the combination throw an error. This is intended as a temporary stopgap until we can implement it in a future release, as it's a useful feature. Author: Fujii Masao <masao.fujii@gmail.com> Author: Antonin Houska <ah@cybertec.at> Author: Osama Abdul Qader <osamaabdulqader.cs@gmail.com> Reported-by: Nathan Bossart <nathandbossart@gmail.com> Backpatch-through: 19 Discussion: https://postgr.es/m/apBCEl4hBHlq0axm@nathan
This commit is contained in:
@@ -329,6 +329,8 @@ REPACK [ ( <replaceable class="parameter">option</replaceable> [, ...] ) ] USING
|
||||
<para>
|
||||
Applies <xref linkend="sql-analyze"/> on the table after repacking. This is
|
||||
currently only supported when a single (non-partitioned) table is specified.
|
||||
This option cannot be used inside a transaction block, or from a function,
|
||||
procedure, or <command>DO</command> block.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
@@ -303,7 +303,7 @@ ExecRepack(ParseState *pstate, RepackStmt *stmt, bool isTopLevel)
|
||||
if ((params.options & CLUOPT_CONCURRENT) != 0)
|
||||
{
|
||||
/*
|
||||
* Make sure we're not in a transaction block.
|
||||
* In concurrent mode, make sure we're not in a transaction block.
|
||||
*
|
||||
* The reason is that repack_setup_logical_decoding() could wait
|
||||
* indefinitely for our XID to complete. (The deadlock detector would
|
||||
@@ -314,6 +314,17 @@ ExecRepack(ParseState *pstate, RepackStmt *stmt, bool isTopLevel)
|
||||
*/
|
||||
PreventInTransactionBlock(isTopLevel, "REPACK (CONCURRENTLY)");
|
||||
}
|
||||
else if ((params.options & CLUOPT_ANALYZE) != 0)
|
||||
{
|
||||
/*
|
||||
* With ANALYZE, process_single_relation() would commit the current
|
||||
* transaction and start a new one, which would break our state if
|
||||
* we're in a transaction block or PL-execution environment. Reject
|
||||
* the option in that case. It may be possible to remove this
|
||||
* restriction in the future.
|
||||
*/
|
||||
PreventInTransactionBlock(isTopLevel, "REPACK (ANALYZE)");
|
||||
}
|
||||
|
||||
/*
|
||||
* If a single relation is specified, process it and we're done ... unless
|
||||
|
||||
@@ -796,9 +796,24 @@ ORDER BY 1;
|
||||
clstr_tst_pkey
|
||||
(3 rows)
|
||||
|
||||
-- Verify partial analyze works
|
||||
-- Verify REPACK (ANALYZE) works, including partial analyze.
|
||||
REPACK (ANALYZE) clstr_tst (a);
|
||||
REPACK (ANALYZE) clstr_tst;
|
||||
-- Plain REPACK is allowed in a transaction block.
|
||||
BEGIN;
|
||||
REPACK clstr_tst;
|
||||
ROLLBACK;
|
||||
-- REPACK (ANALYZE) is not allowed in a transaction block.
|
||||
BEGIN;
|
||||
REPACK (ANALYZE) clstr_tst;
|
||||
ERROR: REPACK (ANALYZE) cannot run inside a transaction block
|
||||
ROLLBACK;
|
||||
-- REPACK is allowed within a PL, as long as there's no ANALYZE.
|
||||
DO $$ BEGIN EXECUTE 'REPACK clstr_tst'; END $$;
|
||||
DO $$ BEGIN EXECUTE 'REPACK (ANALYZE) clstr_tst'; END $$;
|
||||
ERROR: REPACK (ANALYZE) cannot be executed from a function or procedure
|
||||
CONTEXT: SQL statement "REPACK (ANALYZE) clstr_tst"
|
||||
PL/pgSQL function inline_code_block line 1 at EXECUTE
|
||||
REPACK (VERBOSE) clstr_tst (a);
|
||||
ERROR: ANALYZE option must be specified when a column list is provided
|
||||
-- REPACK w/o argument performs no ordering, so we can only check which tables
|
||||
|
||||
@@ -380,9 +380,24 @@ INSERT INTO clstr_tst (b, c) VALUES (1111, 'this should fail');
|
||||
SELECT conname FROM pg_constraint WHERE conrelid = 'clstr_tst'::regclass
|
||||
ORDER BY 1;
|
||||
|
||||
-- Verify partial analyze works
|
||||
-- Verify REPACK (ANALYZE) works, including partial analyze.
|
||||
REPACK (ANALYZE) clstr_tst (a);
|
||||
REPACK (ANALYZE) clstr_tst;
|
||||
|
||||
-- Plain REPACK is allowed in a transaction block.
|
||||
BEGIN;
|
||||
REPACK clstr_tst;
|
||||
ROLLBACK;
|
||||
|
||||
-- REPACK (ANALYZE) is not allowed in a transaction block.
|
||||
BEGIN;
|
||||
REPACK (ANALYZE) clstr_tst;
|
||||
ROLLBACK;
|
||||
|
||||
-- REPACK is allowed within a PL, as long as there's no ANALYZE.
|
||||
DO $$ BEGIN EXECUTE 'REPACK clstr_tst'; END $$;
|
||||
DO $$ BEGIN EXECUTE 'REPACK (ANALYZE) clstr_tst'; END $$;
|
||||
|
||||
REPACK (VERBOSE) clstr_tst (a);
|
||||
|
||||
-- REPACK w/o argument performs no ordering, so we can only check which tables
|
||||
|
||||
Reference in New Issue
Block a user