Skip to content

Commit 4eaa537

Browse files
committed
Don't allow partitioned index on foreign-table partitions
Creating indexes on foreign tables is already forbidden, but local partitioned indexes (commit 8b08f7d) forgot to check for them. Add a preliminary check to prevent wasting time. Another school of thought says to allow the index to be created if it's not a unique index; but it's possible to do better in the future (enable indexing of foreign tables, somehow), so we avoid painting ourselves in a corner by rejecting all cases, to avoid future grief (a.k.a. backward incompatible changes). Reported-by: Arseny Sher Author: Amit Langote, Álvaro Herrera Discussion: https://postgr.es/m/87sh71cakz.fsf@ars-thinkpad
1 parent fc2a41e commit 4eaa537

File tree

3 files changed

+39
-12
lines changed

3 files changed

+39
-12
lines changed

src/backend/tcop/utility.c

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
#include "tcop/utility.h"
6868
#include "utils/acl.h"
6969
#include "utils/guc.h"
70+
#include "utils/lsyscache.h"
7071
#include "utils/syscache.h"
7172
#include "utils/rel.h"
7273

@@ -1287,7 +1288,6 @@ ProcessUtilitySlow(ParseState *pstate,
12871288
IndexStmt *stmt = (IndexStmt *) parsetree;
12881289
Oid relid;
12891290
LOCKMODE lockmode;
1290-
List *inheritors = NIL;
12911291

12921292
if (stmt->concurrent)
12931293
PreventInTransactionBlock(isTopLevel,
@@ -1314,17 +1314,33 @@ ProcessUtilitySlow(ParseState *pstate,
13141314
* CREATE INDEX on partitioned tables (but not regular
13151315
* inherited tables) recurses to partitions, so we must
13161316
* acquire locks early to avoid deadlocks.
1317+
*
1318+
* We also take the opportunity to verify that all
1319+
* partitions are something we can put an index on,
1320+
* to avoid building some indexes only to fail later.
13171321
*/
1318-
if (stmt->relation->inh)
1322+
if (stmt->relation->inh &&
1323+
get_rel_relkind(relid) == RELKIND_PARTITIONED_TABLE)
13191324
{
1320-
Relation rel;
1321-
1322-
/* already locked by RangeVarGetRelidExtended */
1323-
rel = heap_open(relid, NoLock);
1324-
if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
1325-
inheritors = find_all_inheritors(relid, lockmode,
1326-
NULL);
1327-
heap_close(rel, NoLock);
1325+
ListCell *lc;
1326+
List *inheritors = NIL;
1327+
1328+
inheritors = find_all_inheritors(relid, lockmode, NULL);
1329+
foreach(lc, inheritors)
1330+
{
1331+
char relkind = get_rel_relkind(lfirst_oid(lc));
1332+
1333+
if (relkind != RELKIND_RELATION &&
1334+
relkind != RELKIND_MATVIEW &&
1335+
relkind != RELKIND_PARTITIONED_TABLE)
1336+
ereport(ERROR,
1337+
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1338+
errmsg("cannot create index on partitioned table \"%s\"",
1339+
stmt->relation->relname),
1340+
errdetail("Table \"%s\" contains partitions that are foreign tables.",
1341+
stmt->relation->relname)));
1342+
}
1343+
list_free(inheritors);
13281344
}
13291345

13301346
/* Run parse analysis ... */
@@ -1353,8 +1369,6 @@ ProcessUtilitySlow(ParseState *pstate,
13531369
parsetree);
13541370
commandCollected = true;
13551371
EventTriggerAlterTableEnd();
1356-
1357-
list_free(inheritors);
13581372
}
13591373
break;
13601374

src/test/regress/expected/foreign_data.out

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,13 @@ SELECT * FROM ft1; -- ERROR
749749
ERROR: foreign-data wrapper "dummy" has no handler
750750
EXPLAIN SELECT * FROM ft1; -- ERROR
751751
ERROR: foreign-data wrapper "dummy" has no handler
752+
CREATE TABLE lt1 (a INT) PARTITION BY RANGE (a);
753+
CREATE FOREIGN TABLE ft_part1
754+
PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) SERVER s0;
755+
CREATE INDEX ON lt1 (a); -- ERROR
756+
ERROR: cannot create index on partitioned table "lt1"
757+
DETAIL: Table "lt1" contains partitions that are foreign tables.
758+
DROP TABLE lt1;
752759
-- ALTER FOREIGN TABLE
753760
COMMENT ON FOREIGN TABLE ft1 IS 'foreign table';
754761
COMMENT ON FOREIGN TABLE ft1 IS NULL;

src/test/regress/sql/foreign_data.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,12 @@ CREATE INDEX id_ft1_c2 ON ft1 (c2); -- ERROR
316316
SELECT * FROM ft1; -- ERROR
317317
EXPLAIN SELECT * FROM ft1; -- ERROR
318318

319+
CREATE TABLE lt1 (a INT) PARTITION BY RANGE (a);
320+
CREATE FOREIGN TABLE ft_part1
321+
PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) SERVER s0;
322+
CREATE INDEX ON lt1 (a); -- ERROR
323+
DROP TABLE lt1;
324+
319325
-- ALTER FOREIGN TABLE
320326
COMMENT ON FOREIGN TABLE ft1 IS 'foreign table';
321327
COMMENT ON FOREIGN TABLE ft1 IS NULL;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy