Fixed a bug reorganizing tables without toast tables.
This commit is contained in:
parent
24a03c01a5
commit
aab19c7db0
@ -27,63 +27,68 @@ CREATE TABLE tbl_gistkey (
|
|||||||
);
|
);
|
||||||
CREATE INDEX cidx_circle ON tbl_gistkey USING gist (c);
|
CREATE INDEX cidx_circle ON tbl_gistkey USING gist (c);
|
||||||
ALTER TABLE tbl_gistkey CLUSTER ON cidx_circle;
|
ALTER TABLE tbl_gistkey CLUSTER ON cidx_circle;
|
||||||
|
--
|
||||||
|
-- insert data
|
||||||
|
--
|
||||||
INSERT INTO tbl_cluster VALUES(1, '2008-12-31 10:00:00', 'admin');
|
INSERT INTO tbl_cluster VALUES(1, '2008-12-31 10:00:00', 'admin');
|
||||||
INSERT INTO tbl_cluster VALUES(2, '2008-01-01 00:00:00', 'king');
|
INSERT INTO tbl_cluster VALUES(2, '2008-01-01 00:00:00', 'king');
|
||||||
INSERT INTO tbl_cluster VALUES(3, '2008-03-04 12:00:00', 'joker');
|
INSERT INTO tbl_cluster VALUES(3, '2008-03-04 12:00:00', 'joker');
|
||||||
INSERT INTO tbl_cluster VALUES(4, '2008-03-05 15:00:00', 'queen');
|
INSERT INTO tbl_cluster VALUES(4, '2008-03-05 15:00:00', 'queen');
|
||||||
INSERT INTO tbl_cluster VALUES(5, '2008-01-01 00:30:00', sqrt(2::numeric(1000,999))::text || sqrt(3::numeric(1000,999))::text);
|
INSERT INTO tbl_cluster VALUES(5, '2008-01-01 00:30:00', sqrt(2::numeric(1000,999))::text || sqrt(3::numeric(1000,999))::text);
|
||||||
|
INSERT INTO tbl_only_pkey VALUES(1, 'abc');
|
||||||
|
INSERT INTO tbl_only_pkey VALUES(2, 'def');
|
||||||
|
INSERT INTO tbl_only_ckey VALUES(1, '2008-01-01 00:00:00', 'abc');
|
||||||
|
INSERT INTO tbl_only_ckey VALUES(2, '2008-02-01 00:00:00', 'def');
|
||||||
|
INSERT INTO tbl_gistkey VALUES(1, '<(1,2),3>');
|
||||||
|
INSERT INTO tbl_gistkey VALUES(2, '<(4,5),6>');
|
||||||
--
|
--
|
||||||
-- do reorg
|
-- do reorg
|
||||||
--
|
--
|
||||||
|
\! pg_reorg --dbname=contrib_regression --no-order
|
||||||
|
\! pg_reorg --dbname=contrib_regression
|
||||||
\! pg_reorg --dbname=contrib_regression --table=tbl_cluster
|
\! pg_reorg --dbname=contrib_regression --table=tbl_cluster
|
||||||
--
|
--
|
||||||
-- results
|
-- results
|
||||||
--
|
--
|
||||||
\d+ tbl_cluster
|
\d tbl_cluster
|
||||||
Table "public.tbl_cluster"
|
Table "public.tbl_cluster"
|
||||||
Column | Type | Modifiers | Storage | Description
|
Column | Type | Modifiers
|
||||||
--------+-----------------------------+-----------+----------+-------------
|
--------+-----------------------------+-----------
|
||||||
col1 | integer | not null | plain |
|
col1 | integer | not null
|
||||||
col2 | timestamp without time zone | | plain |
|
col2 | timestamp without time zone |
|
||||||
:-) | text | not null | extended |
|
:-) | text | not null
|
||||||
Indexes:
|
Indexes:
|
||||||
"tbl_cluster_pkey" PRIMARY KEY, btree (":-)", col1)
|
"tbl_cluster_pkey" PRIMARY KEY, btree (":-)", col1)
|
||||||
"cidx_cluster" btree (col2, length(":-)")) CLUSTER
|
"cidx_cluster" btree (col2, length(":-)")) CLUSTER
|
||||||
Has OIDs: no
|
|
||||||
Options: fillfactor=70
|
|
||||||
|
|
||||||
\d+ tbl_gistkey
|
\d tbl_gistkey
|
||||||
Table "public.tbl_gistkey"
|
Table "public.tbl_gistkey"
|
||||||
Column | Type | Modifiers | Storage | Description
|
Column | Type | Modifiers
|
||||||
--------+---------+-----------+---------+-------------
|
--------+---------+-----------
|
||||||
id | integer | not null | plain |
|
id | integer | not null
|
||||||
c | circle | | plain |
|
c | circle |
|
||||||
Indexes:
|
Indexes:
|
||||||
"tbl_gistkey_pkey" PRIMARY KEY, btree (id)
|
"tbl_gistkey_pkey" PRIMARY KEY, btree (id)
|
||||||
"cidx_circle" gist (c) CLUSTER
|
"cidx_circle" gist (c) CLUSTER
|
||||||
Has OIDs: no
|
|
||||||
|
|
||||||
\d+ tbl_only_ckey
|
\d tbl_only_ckey
|
||||||
Table "public.tbl_only_ckey"
|
Table "public.tbl_only_ckey"
|
||||||
Column | Type | Modifiers | Storage | Description
|
Column | Type | Modifiers
|
||||||
--------+-----------------------------+-----------+----------+-------------
|
--------+-----------------------------+-----------
|
||||||
col1 | integer | | plain |
|
col1 | integer |
|
||||||
col2 | timestamp without time zone | | plain |
|
col2 | timestamp without time zone |
|
||||||
:-) | text | | extended |
|
:-) | text |
|
||||||
Indexes:
|
Indexes:
|
||||||
"cidx_only_ckey" btree (col2, ":-)") CLUSTER
|
"cidx_only_ckey" btree (col2, ":-)") CLUSTER
|
||||||
Has OIDs: no
|
|
||||||
Options: fillfactor=70
|
|
||||||
|
|
||||||
\d+ tbl_only_pkey
|
\d tbl_only_pkey
|
||||||
Table "public.tbl_only_pkey"
|
Table "public.tbl_only_pkey"
|
||||||
Column | Type | Modifiers | Storage | Description
|
Column | Type | Modifiers
|
||||||
--------+---------+-----------+----------+-------------
|
--------+---------+-----------
|
||||||
col1 | integer | not null | plain |
|
col1 | integer | not null
|
||||||
:-) | text | | extended |
|
:-) | text |
|
||||||
Indexes:
|
Indexes:
|
||||||
"tbl_only_pkey_pkey" PRIMARY KEY, btree (col1)
|
"tbl_only_pkey_pkey" PRIMARY KEY, btree (col1)
|
||||||
Has OIDs: no
|
|
||||||
|
|
||||||
SET synchronize_seqscans = off;
|
SET synchronize_seqscans = off;
|
||||||
SELECT col1, to_char(col2, 'YYYY-MM-DD HH24:MI:SS'), ":-)" FROM tbl_cluster;
|
SELECT col1, to_char(col2, 'YYYY-MM-DD HH24:MI:SS'), ":-)" FROM tbl_cluster;
|
||||||
@ -96,27 +101,33 @@ SELECT col1, to_char(col2, 'YYYY-MM-DD HH24:MI:SS'), ":-)" FROM tbl_cluster;
|
|||||||
1 | 2008-12-31 10:00:00 | admin
|
1 | 2008-12-31 10:00:00 | admin
|
||||||
(5 rows)
|
(5 rows)
|
||||||
|
|
||||||
SELECT * FROM tbl_gistkey;
|
SELECT * FROM tbl_only_ckey ORDER BY 1;
|
||||||
id | c
|
col1 | col2 | :-)
|
||||||
----+---
|
------+--------------------------+-----
|
||||||
(0 rows)
|
1 | Tue Jan 01 00:00:00 2008 | abc
|
||||||
|
2 | Fri Feb 01 00:00:00 2008 | def
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
SELECT * FROM tbl_only_ckey;
|
SELECT * FROM tbl_only_pkey ORDER BY 1;
|
||||||
col1 | col2 | :-)
|
|
||||||
------+------+-----
|
|
||||||
(0 rows)
|
|
||||||
|
|
||||||
SELECT * FROM tbl_only_pkey;
|
|
||||||
col1 | :-)
|
col1 | :-)
|
||||||
------+-----
|
------+-----
|
||||||
(0 rows)
|
1 | abc
|
||||||
|
2 | def
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT * FROM tbl_gistkey ORDER BY 1;
|
||||||
|
id | c
|
||||||
|
----+-----------
|
||||||
|
1 | <(1,2),3>
|
||||||
|
2 | <(4,5),6>
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
RESET synchronize_seqscans;
|
RESET synchronize_seqscans;
|
||||||
--
|
--
|
||||||
-- clean up
|
-- clean up
|
||||||
--
|
--
|
||||||
DROP TABLE tbl_cluster;
|
DROP TABLE tbl_cluster;
|
||||||
DROP TABLE tbl_gistkey;
|
|
||||||
DROP TABLE tbl_only_pkey;
|
DROP TABLE tbl_only_pkey;
|
||||||
DROP TABLE tbl_only_ckey;
|
DROP TABLE tbl_only_ckey;
|
||||||
|
DROP TABLE tbl_gistkey;
|
||||||
RESET client_min_messages;
|
RESET client_min_messages;
|
||||||
|
@ -34,32 +34,47 @@ CREATE TABLE tbl_gistkey (
|
|||||||
CREATE INDEX cidx_circle ON tbl_gistkey USING gist (c);
|
CREATE INDEX cidx_circle ON tbl_gistkey USING gist (c);
|
||||||
ALTER TABLE tbl_gistkey CLUSTER ON cidx_circle;
|
ALTER TABLE tbl_gistkey CLUSTER ON cidx_circle;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- insert data
|
||||||
|
--
|
||||||
|
|
||||||
INSERT INTO tbl_cluster VALUES(1, '2008-12-31 10:00:00', 'admin');
|
INSERT INTO tbl_cluster VALUES(1, '2008-12-31 10:00:00', 'admin');
|
||||||
INSERT INTO tbl_cluster VALUES(2, '2008-01-01 00:00:00', 'king');
|
INSERT INTO tbl_cluster VALUES(2, '2008-01-01 00:00:00', 'king');
|
||||||
INSERT INTO tbl_cluster VALUES(3, '2008-03-04 12:00:00', 'joker');
|
INSERT INTO tbl_cluster VALUES(3, '2008-03-04 12:00:00', 'joker');
|
||||||
INSERT INTO tbl_cluster VALUES(4, '2008-03-05 15:00:00', 'queen');
|
INSERT INTO tbl_cluster VALUES(4, '2008-03-05 15:00:00', 'queen');
|
||||||
INSERT INTO tbl_cluster VALUES(5, '2008-01-01 00:30:00', sqrt(2::numeric(1000,999))::text || sqrt(3::numeric(1000,999))::text);
|
INSERT INTO tbl_cluster VALUES(5, '2008-01-01 00:30:00', sqrt(2::numeric(1000,999))::text || sqrt(3::numeric(1000,999))::text);
|
||||||
|
|
||||||
|
INSERT INTO tbl_only_pkey VALUES(1, 'abc');
|
||||||
|
INSERT INTO tbl_only_pkey VALUES(2, 'def');
|
||||||
|
|
||||||
|
INSERT INTO tbl_only_ckey VALUES(1, '2008-01-01 00:00:00', 'abc');
|
||||||
|
INSERT INTO tbl_only_ckey VALUES(2, '2008-02-01 00:00:00', 'def');
|
||||||
|
|
||||||
|
INSERT INTO tbl_gistkey VALUES(1, '<(1,2),3>');
|
||||||
|
INSERT INTO tbl_gistkey VALUES(2, '<(4,5),6>');
|
||||||
|
|
||||||
--
|
--
|
||||||
-- do reorg
|
-- do reorg
|
||||||
--
|
--
|
||||||
|
|
||||||
|
\! pg_reorg --dbname=contrib_regression --no-order
|
||||||
|
\! pg_reorg --dbname=contrib_regression
|
||||||
\! pg_reorg --dbname=contrib_regression --table=tbl_cluster
|
\! pg_reorg --dbname=contrib_regression --table=tbl_cluster
|
||||||
|
|
||||||
--
|
--
|
||||||
-- results
|
-- results
|
||||||
--
|
--
|
||||||
|
|
||||||
\d+ tbl_cluster
|
\d tbl_cluster
|
||||||
\d+ tbl_gistkey
|
\d tbl_gistkey
|
||||||
\d+ tbl_only_ckey
|
\d tbl_only_ckey
|
||||||
\d+ tbl_only_pkey
|
\d tbl_only_pkey
|
||||||
|
|
||||||
SET synchronize_seqscans = off;
|
SET synchronize_seqscans = off;
|
||||||
SELECT col1, to_char(col2, 'YYYY-MM-DD HH24:MI:SS'), ":-)" FROM tbl_cluster;
|
SELECT col1, to_char(col2, 'YYYY-MM-DD HH24:MI:SS'), ":-)" FROM tbl_cluster;
|
||||||
SELECT * FROM tbl_gistkey;
|
SELECT * FROM tbl_only_ckey ORDER BY 1;
|
||||||
SELECT * FROM tbl_only_ckey;
|
SELECT * FROM tbl_only_pkey ORDER BY 1;
|
||||||
SELECT * FROM tbl_only_pkey;
|
SELECT * FROM tbl_gistkey ORDER BY 1;
|
||||||
RESET synchronize_seqscans;
|
RESET synchronize_seqscans;
|
||||||
|
|
||||||
--
|
--
|
||||||
@ -67,7 +82,7 @@ RESET synchronize_seqscans;
|
|||||||
--
|
--
|
||||||
|
|
||||||
DROP TABLE tbl_cluster;
|
DROP TABLE tbl_cluster;
|
||||||
DROP TABLE tbl_gistkey;
|
|
||||||
DROP TABLE tbl_only_pkey;
|
DROP TABLE tbl_only_pkey;
|
||||||
DROP TABLE tbl_only_ckey;
|
DROP TABLE tbl_only_ckey;
|
||||||
|
DROP TABLE tbl_gistkey;
|
||||||
RESET client_min_messages;
|
RESET client_min_messages;
|
||||||
|
41
lib/reorg.c
41
lib/reorg.c
@ -25,16 +25,12 @@
|
|||||||
#include "utils/relcache.h"
|
#include "utils/relcache.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
#ifdef PG_MODULE_MAGIC
|
|
||||||
PG_MODULE_MAGIC;
|
PG_MODULE_MAGIC;
|
||||||
#endif
|
|
||||||
|
|
||||||
#if PG_VERSION_NUM < 80300
|
|
||||||
#if PG_VERSION_NUM < 80300
|
#if PG_VERSION_NUM < 80300
|
||||||
#define SET_VARSIZE(PTR, len) (VARATT_SIZEP((PTR)) = (len))
|
#define SET_VARSIZE(PTR, len) (VARATT_SIZEP((PTR)) = (len))
|
||||||
typedef void *SPIPlanPtr;
|
typedef void *SPIPlanPtr;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
Datum reorg_trigger(PG_FUNCTION_ARGS);
|
Datum reorg_trigger(PG_FUNCTION_ARGS);
|
||||||
@ -513,11 +509,10 @@ reorg_swap(PG_FUNCTION_ARGS)
|
|||||||
reorg_execd(
|
reorg_execd(
|
||||||
"SELECT X.oid, X.reltoastrelid, TX.reltoastidxid,"
|
"SELECT X.oid, X.reltoastrelid, TX.reltoastidxid,"
|
||||||
" Y.oid, Y.reltoastrelid, TY.reltoastidxid"
|
" Y.oid, Y.reltoastrelid, TY.reltoastidxid"
|
||||||
" FROM pg_class X, pg_class Y, pg_class TX, pg_class TY"
|
" FROM pg_class X LEFT JOIN pg_class TX ON X.reltoastrelid = TX.oid,"
|
||||||
|
" pg_class Y LEFT JOIN pg_class TY ON Y.reltoastrelid = TY.oid"
|
||||||
" WHERE X.oid = $1"
|
" WHERE X.oid = $1"
|
||||||
" AND X.reltoastrelid = TX.oid"
|
" AND Y.oid = ('reorg.table_' || X.oid)::regclass",
|
||||||
" AND Y.oid = ('reorg.table_' || X.oid)::regclass"
|
|
||||||
" AND Y.reltoastrelid = TY.oid",
|
|
||||||
1, argtypes, values, nulls, SPI_OK_SELECT);
|
1, argtypes, values, nulls, SPI_OK_SELECT);
|
||||||
|
|
||||||
tuptable = SPI_tuptable;
|
tuptable = SPI_tuptable;
|
||||||
@ -525,7 +520,7 @@ reorg_swap(PG_FUNCTION_ARGS)
|
|||||||
records = SPI_processed;
|
records = SPI_processed;
|
||||||
|
|
||||||
if (records == 0)
|
if (records == 0)
|
||||||
elog(ERROR, "reorg_swap : unexpected");
|
elog(ERROR, "reorg_swap : no swap target");
|
||||||
|
|
||||||
tuple = tuptable->vals[0];
|
tuple = tuptable->vals[0];
|
||||||
|
|
||||||
@ -535,6 +530,16 @@ reorg_swap(PG_FUNCTION_ARGS)
|
|||||||
reltoastrelid2 = getoid(tuple, desc, 5);
|
reltoastrelid2 = getoid(tuple, desc, 5);
|
||||||
reltoastidxid2 = getoid(tuple, desc, 6);
|
reltoastidxid2 = getoid(tuple, desc, 6);
|
||||||
|
|
||||||
|
/* should be all-or-nothing */
|
||||||
|
if ((reltoastrelid1 == InvalidOid || reltoastidxid1 == InvalidOid ||
|
||||||
|
reltoastrelid2 == InvalidOid || reltoastidxid2 == InvalidOid) &&
|
||||||
|
(reltoastrelid1 != InvalidOid || reltoastidxid1 != InvalidOid ||
|
||||||
|
reltoastrelid2 != InvalidOid || reltoastidxid2 != InvalidOid))
|
||||||
|
{
|
||||||
|
elog(ERROR, "reorg_swap : unexpected toast relations (T1=%u, I1=%u, T2=%u, I2=%u",
|
||||||
|
reltoastrelid1, reltoastidxid1, reltoastrelid2, reltoastidxid2);
|
||||||
|
}
|
||||||
|
|
||||||
swap_heap_or_index_files(oid, oid2);
|
swap_heap_or_index_files(oid, oid2);
|
||||||
CommandCounterIncrement();
|
CommandCounterIncrement();
|
||||||
|
|
||||||
@ -886,6 +891,9 @@ swap_heap_or_index_files(Oid r1, Oid r2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if PG_VERSION_NUM < 80400
|
#if PG_VERSION_NUM < 80400
|
||||||
|
|
||||||
|
extern PGDLLIMPORT bool allowSystemTableMods;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
SPI_execute_with_args(const char *src,
|
SPI_execute_with_args(const char *src,
|
||||||
int nargs, Oid *argtypes,
|
int nargs, Oid *argtypes,
|
||||||
@ -918,6 +926,19 @@ cstring_to_text(const char * s)
|
|||||||
static void
|
static void
|
||||||
RenameRelationInternal(Oid myrelid, const char *newrelname, Oid namespaceId)
|
RenameRelationInternal(Oid myrelid, const char *newrelname, Oid namespaceId)
|
||||||
{
|
{
|
||||||
renamerel(myrelid, newrelname, OBJECT_TABLE);
|
bool save_allowSystemTableMods = allowSystemTableMods;
|
||||||
|
|
||||||
|
allowSystemTableMods = true;
|
||||||
|
PG_TRY();
|
||||||
|
{
|
||||||
|
renamerel(myrelid, newrelname, OBJECT_TABLE);
|
||||||
|
allowSystemTableMods = save_allowSystemTableMods;
|
||||||
|
}
|
||||||
|
PG_CATCH();
|
||||||
|
{
|
||||||
|
allowSystemTableMods = save_allowSystemTableMods;
|
||||||
|
PG_RE_THROW();
|
||||||
|
}
|
||||||
|
PG_END_TRY();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user