Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+26-12
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

+7
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

+6
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)