Skip to content

Commit aab19c7

Browse files
committed
Fixed a bug reorganizing tables without toast tables.
1 parent 24a03c0 commit aab19c7

File tree

3 files changed

+110
-63
lines changed

3 files changed

+110
-63
lines changed

bin/expected/reorg.out

Lines changed: 55 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -27,63 +27,68 @@ CREATE TABLE tbl_gistkey (
2727
);
2828
CREATE INDEX cidx_circle ON tbl_gistkey USING gist (c);
2929
ALTER TABLE tbl_gistkey CLUSTER ON cidx_circle;
30+
--
31+
-- insert data
32+
--
3033
INSERT INTO tbl_cluster VALUES(1, '2008-12-31 10:00:00', 'admin');
3134
INSERT INTO tbl_cluster VALUES(2, '2008-01-01 00:00:00', 'king');
3235
INSERT INTO tbl_cluster VALUES(3, '2008-03-04 12:00:00', 'joker');
3336
INSERT INTO tbl_cluster VALUES(4, '2008-03-05 15:00:00', 'queen');
3437
INSERT INTO tbl_cluster VALUES(5, '2008-01-01 00:30:00', sqrt(2::numeric(1000,999))::text || sqrt(3::numeric(1000,999))::text);
38+
INSERT INTO tbl_only_pkey VALUES(1, 'abc');
39+
INSERT INTO tbl_only_pkey VALUES(2, 'def');
40+
INSERT INTO tbl_only_ckey VALUES(1, '2008-01-01 00:00:00', 'abc');
41+
INSERT INTO tbl_only_ckey VALUES(2, '2008-02-01 00:00:00', 'def');
42+
INSERT INTO tbl_gistkey VALUES(1, '<(1,2),3>');
43+
INSERT INTO tbl_gistkey VALUES(2, '<(4,5),6>');
3544
--
3645
-- do reorg
3746
--
47+
\! pg_reorg --dbname=contrib_regression --no-order
48+
\! pg_reorg --dbname=contrib_regression
3849
\! pg_reorg --dbname=contrib_regression --table=tbl_cluster
3950
--
4051
-- results
4152
--
42-
\d+ tbl_cluster
43-
Table "public.tbl_cluster"
44-
Column | Type | Modifiers | Storage | Description
45-
--------+-----------------------------+-----------+----------+-------------
46-
col1 | integer | not null | plain |
47-
col2 | timestamp without time zone | | plain |
48-
:-) | text | not null | extended |
53+
\d tbl_cluster
54+
Table "public.tbl_cluster"
55+
Column | Type | Modifiers
56+
--------+-----------------------------+-----------
57+
col1 | integer | not null
58+
col2 | timestamp without time zone |
59+
:-) | text | not null
4960
Indexes:
5061
"tbl_cluster_pkey" PRIMARY KEY, btree (":-)", col1)
5162
"cidx_cluster" btree (col2, length(":-)")) CLUSTER
52-
Has OIDs: no
53-
Options: fillfactor=70
5463

55-
\d+ tbl_gistkey
56-
Table "public.tbl_gistkey"
57-
Column | Type | Modifiers | Storage | Description
58-
--------+---------+-----------+---------+-------------
59-
id | integer | not null | plain |
60-
c | circle | | plain |
64+
\d tbl_gistkey
65+
Table "public.tbl_gistkey"
66+
Column | Type | Modifiers
67+
--------+---------+-----------
68+
id | integer | not null
69+
c | circle |
6170
Indexes:
6271
"tbl_gistkey_pkey" PRIMARY KEY, btree (id)
6372
"cidx_circle" gist (c) CLUSTER
64-
Has OIDs: no
6573

66-
\d+ tbl_only_ckey
67-
Table "public.tbl_only_ckey"
68-
Column | Type | Modifiers | Storage | Description
69-
--------+-----------------------------+-----------+----------+-------------
70-
col1 | integer | | plain |
71-
col2 | timestamp without time zone | | plain |
72-
:-) | text | | extended |
74+
\d tbl_only_ckey
75+
Table "public.tbl_only_ckey"
76+
Column | Type | Modifiers
77+
--------+-----------------------------+-----------
78+
col1 | integer |
79+
col2 | timestamp without time zone |
80+
:-) | text |
7381
Indexes:
7482
"cidx_only_ckey" btree (col2, ":-)") CLUSTER
75-
Has OIDs: no
76-
Options: fillfactor=70
7783

78-
\d+ tbl_only_pkey
79-
Table "public.tbl_only_pkey"
80-
Column | Type | Modifiers | Storage | Description
81-
--------+---------+-----------+----------+-------------
82-
col1 | integer | not null | plain |
83-
:-) | text | | extended |
84+
\d tbl_only_pkey
85+
Table "public.tbl_only_pkey"
86+
Column | Type | Modifiers
87+
--------+---------+-----------
88+
col1 | integer | not null
89+
:-) | text |
8490
Indexes:
8591
"tbl_only_pkey_pkey" PRIMARY KEY, btree (col1)
86-
Has OIDs: no
8792

8893
SET synchronize_seqscans = off;
8994
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;
96101
1 | 2008-12-31 10:00:00 | admin
97102
(5 rows)
98103

99-
SELECT * FROM tbl_gistkey;
100-
id | c
101-
----+---
102-
(0 rows)
103-
104-
SELECT * FROM tbl_only_ckey;
105-
col1 | col2 | :-)
106-
------+------+-----
107-
(0 rows)
104+
SELECT * FROM tbl_only_ckey ORDER BY 1;
105+
col1 | col2 | :-)
106+
------+--------------------------+-----
107+
1 | Tue Jan 01 00:00:00 2008 | abc
108+
2 | Fri Feb 01 00:00:00 2008 | def
109+
(2 rows)
108110

109-
SELECT * FROM tbl_only_pkey;
111+
SELECT * FROM tbl_only_pkey ORDER BY 1;
110112
col1 | :-)
111113
------+-----
112-
(0 rows)
114+
1 | abc
115+
2 | def
116+
(2 rows)
117+
118+
SELECT * FROM tbl_gistkey ORDER BY 1;
119+
id | c
120+
----+-----------
121+
1 | <(1,2),3>
122+
2 | <(4,5),6>
123+
(2 rows)
113124

114125
RESET synchronize_seqscans;
115126
--
116127
-- clean up
117128
--
118129
DROP TABLE tbl_cluster;
119-
DROP TABLE tbl_gistkey;
120130
DROP TABLE tbl_only_pkey;
121131
DROP TABLE tbl_only_ckey;
132+
DROP TABLE tbl_gistkey;
122133
RESET client_min_messages;

bin/sql/reorg.sql

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,40 +34,55 @@ CREATE TABLE tbl_gistkey (
3434
CREATE INDEX cidx_circle ON tbl_gistkey USING gist (c);
3535
ALTER TABLE tbl_gistkey CLUSTER ON cidx_circle;
3636

37+
--
38+
-- insert data
39+
--
40+
3741
INSERT INTO tbl_cluster VALUES(1, '2008-12-31 10:00:00', 'admin');
3842
INSERT INTO tbl_cluster VALUES(2, '2008-01-01 00:00:00', 'king');
3943
INSERT INTO tbl_cluster VALUES(3, '2008-03-04 12:00:00', 'joker');
4044
INSERT INTO tbl_cluster VALUES(4, '2008-03-05 15:00:00', 'queen');
4145
INSERT INTO tbl_cluster VALUES(5, '2008-01-01 00:30:00', sqrt(2::numeric(1000,999))::text || sqrt(3::numeric(1000,999))::text);
4246

47+
INSERT INTO tbl_only_pkey VALUES(1, 'abc');
48+
INSERT INTO tbl_only_pkey VALUES(2, 'def');
49+
50+
INSERT INTO tbl_only_ckey VALUES(1, '2008-01-01 00:00:00', 'abc');
51+
INSERT INTO tbl_only_ckey VALUES(2, '2008-02-01 00:00:00', 'def');
52+
53+
INSERT INTO tbl_gistkey VALUES(1, '<(1,2),3>');
54+
INSERT INTO tbl_gistkey VALUES(2, '<(4,5),6>');
55+
4356
--
4457
-- do reorg
4558
--
4659

60+
\! pg_reorg --dbname=contrib_regression --no-order
61+
\! pg_reorg --dbname=contrib_regression
4762
\! pg_reorg --dbname=contrib_regression --table=tbl_cluster
4863

4964
--
5065
-- results
5166
--
5267

53-
\d+ tbl_cluster
54-
\d+ tbl_gistkey
55-
\d+ tbl_only_ckey
56-
\d+ tbl_only_pkey
68+
\d tbl_cluster
69+
\d tbl_gistkey
70+
\d tbl_only_ckey
71+
\d tbl_only_pkey
5772

5873
SET synchronize_seqscans = off;
5974
SELECT col1, to_char(col2, 'YYYY-MM-DD HH24:MI:SS'), ":-)" FROM tbl_cluster;
60-
SELECT * FROM tbl_gistkey;
61-
SELECT * FROM tbl_only_ckey;
62-
SELECT * FROM tbl_only_pkey;
75+
SELECT * FROM tbl_only_ckey ORDER BY 1;
76+
SELECT * FROM tbl_only_pkey ORDER BY 1;
77+
SELECT * FROM tbl_gistkey ORDER BY 1;
6378
RESET synchronize_seqscans;
6479

6580
--
6681
-- clean up
6782
--
6883

6984
DROP TABLE tbl_cluster;
70-
DROP TABLE tbl_gistkey;
7185
DROP TABLE tbl_only_pkey;
7286
DROP TABLE tbl_only_ckey;
87+
DROP TABLE tbl_gistkey;
7388
RESET client_min_messages;

lib/reorg.c

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,12 @@
2525
#include "utils/relcache.h"
2626
#include "utils/syscache.h"
2727

28-
#ifdef PG_MODULE_MAGIC
2928
PG_MODULE_MAGIC;
30-
#endif
3129

32-
#if PG_VERSION_NUM < 80300
3330
#if PG_VERSION_NUM < 80300
3431
#define SET_VARSIZE(PTR, len) (VARATT_SIZEP((PTR)) = (len))
3532
typedef void *SPIPlanPtr;
3633
#endif
37-
#endif
3834

3935

4036
Datum reorg_trigger(PG_FUNCTION_ARGS);
@@ -513,19 +509,18 @@ reorg_swap(PG_FUNCTION_ARGS)
513509
reorg_execd(
514510
"SELECT X.oid, X.reltoastrelid, TX.reltoastidxid,"
515511
" Y.oid, Y.reltoastrelid, TY.reltoastidxid"
516-
" FROM pg_class X, pg_class Y, pg_class TX, pg_class TY"
512+
" FROM pg_class X LEFT JOIN pg_class TX ON X.reltoastrelid = TX.oid,"
513+
" pg_class Y LEFT JOIN pg_class TY ON Y.reltoastrelid = TY.oid"
517514
" WHERE X.oid = $1"
518-
" AND X.reltoastrelid = TX.oid"
519-
" AND Y.oid = ('reorg.table_' || X.oid)::regclass"
520-
" AND Y.reltoastrelid = TY.oid",
515+
" AND Y.oid = ('reorg.table_' || X.oid)::regclass",
521516
1, argtypes, values, nulls, SPI_OK_SELECT);
522517

523518
tuptable = SPI_tuptable;
524519
desc = tuptable->tupdesc;
525520
records = SPI_processed;
526521

527522
if (records == 0)
528-
elog(ERROR, "reorg_swap : unexpected");
523+
elog(ERROR, "reorg_swap : no swap target");
529524

530525
tuple = tuptable->vals[0];
531526

@@ -535,6 +530,16 @@ reorg_swap(PG_FUNCTION_ARGS)
535530
reltoastrelid2 = getoid(tuple, desc, 5);
536531
reltoastidxid2 = getoid(tuple, desc, 6);
537532

533+
/* should be all-or-nothing */
534+
if ((reltoastrelid1 == InvalidOid || reltoastidxid1 == InvalidOid ||
535+
reltoastrelid2 == InvalidOid || reltoastidxid2 == InvalidOid) &&
536+
(reltoastrelid1 != InvalidOid || reltoastidxid1 != InvalidOid ||
537+
reltoastrelid2 != InvalidOid || reltoastidxid2 != InvalidOid))
538+
{
539+
elog(ERROR, "reorg_swap : unexpected toast relations (T1=%u, I1=%u, T2=%u, I2=%u",
540+
reltoastrelid1, reltoastidxid1, reltoastrelid2, reltoastidxid2);
541+
}
542+
538543
swap_heap_or_index_files(oid, oid2);
539544
CommandCounterIncrement();
540545

@@ -566,7 +571,7 @@ reorg_swap(PG_FUNCTION_ARGS)
566571
{
567572
char name[NAMEDATALEN];
568573
int pid = getpid();
569-
574+
570575
/* rename X to TEMP */
571576
snprintf(name, NAMEDATALEN, "pg_toast_pid%d", pid);
572577
RenameRelationInternal(reltoastrelid1, name, PG_TOAST_NAMESPACE);
@@ -886,6 +891,9 @@ swap_heap_or_index_files(Oid r1, Oid r2)
886891
}
887892

888893
#if PG_VERSION_NUM < 80400
894+
895+
extern PGDLLIMPORT bool allowSystemTableMods;
896+
889897
static int
890898
SPI_execute_with_args(const char *src,
891899
int nargs, Oid *argtypes,
@@ -918,6 +926,19 @@ cstring_to_text(const char * s)
918926
static void
919927
RenameRelationInternal(Oid myrelid, const char *newrelname, Oid namespaceId)
920928
{
921-
renamerel(myrelid, newrelname, OBJECT_TABLE);
929+
bool save_allowSystemTableMods = allowSystemTableMods;
930+
931+
allowSystemTableMods = true;
932+
PG_TRY();
933+
{
934+
renamerel(myrelid, newrelname, OBJECT_TABLE);
935+
allowSystemTableMods = save_allowSystemTableMods;
936+
}
937+
PG_CATCH();
938+
{
939+
allowSystemTableMods = save_allowSystemTableMods;
940+
PG_RE_THROW();
941+
}
942+
PG_END_TRY();
922943
}
923944
#endif

0 commit comments

Comments
 (0)