Add index_get_partition convenience function
authorAlvaro Herrera <[email protected]>
Wed, 20 Mar 2019 21:18:50 +0000 (18:18 -0300)
committerAlvaro Herrera <[email protected]>
Wed, 20 Mar 2019 21:18:50 +0000 (18:18 -0300)
This new function simplifies some existing coding, as well as supports
future patches.

Discussion: https://postgr.es/m/201901222145[email protected]
Reviewed-by: Amit Langote, Jesper Pedersen
src/backend/catalog/partition.c
src/backend/commands/tablecmds.c
src/include/catalog/partition.h

index 3ccdaff8c458c0cdbcf15618208b8471e198923e..8ea7a62418f3e574d64cab26cdaf174e93bdd2d8 100644 (file)
@@ -145,6 +145,42 @@ get_partition_ancestors_worker(Relation inhRel, Oid relid, List **ancestors)
    get_partition_ancestors_worker(inhRel, parentOid, ancestors);
 }
 
+/*
+ * index_get_partition
+ *     Return the OID of index of the given partition that is a child
+ *     of the given index, or InvalidOid if there isn't one.
+ */
+Oid
+index_get_partition(Relation partition, Oid indexId)
+{
+   List       *idxlist = RelationGetIndexList(partition);
+   ListCell   *l;
+
+   foreach(l, idxlist)
+   {
+       Oid         partIdx = lfirst_oid(l);
+       HeapTuple   tup;
+       Form_pg_class classForm;
+       bool        ispartition;
+
+       tup = SearchSysCache1(RELOID, ObjectIdGetDatum(partIdx));
+       if (!tup)
+           elog(ERROR, "cache lookup failed for relation %u", partIdx);
+       classForm = (Form_pg_class) GETSTRUCT(tup);
+       ispartition = classForm->relispartition;
+       ReleaseSysCache(tup);
+       if (!ispartition)
+           continue;
+       if (get_partition_parent(lfirst_oid(l)) == indexId)
+       {
+           list_free(idxlist);
+           return partIdx;
+       }
+   }
+
+   return InvalidOid;
+}
+
 /*
  * map_partition_varattnos - maps varattno of any Vars in expr from the
  * attno's of 'from_rel' to the attno's of 'to_rel' partition, each of which
index 515c29072c811365f6e5b391db4e1a4e904ed31b..3183b2aaa12d693ed49be0467845af3665d9989e 100644 (file)
@@ -15649,36 +15649,18 @@ ATExecAttachPartitionIdx(List **wqueue, Relation parentIdx, RangeVar *name)
 static void
 refuseDupeIndexAttach(Relation parentIdx, Relation partIdx, Relation partitionTbl)
 {
-   Relation    pg_inherits;
-   ScanKeyData key;
-   HeapTuple   tuple;
-   SysScanDesc scan;
-
-   pg_inherits = table_open(InheritsRelationId, AccessShareLock);
-   ScanKeyInit(&key, Anum_pg_inherits_inhparent,
-               BTEqualStrategyNumber, F_OIDEQ,
-               ObjectIdGetDatum(RelationGetRelid(parentIdx)));
-   scan = systable_beginscan(pg_inherits, InheritsParentIndexId, true,
-                             NULL, 1, &key);
-   while (HeapTupleIsValid(tuple = systable_getnext(scan)))
-   {
-       Form_pg_inherits inhForm;
-       Oid         tab;
+   Oid         existingIdx;
 
-       inhForm = (Form_pg_inherits) GETSTRUCT(tuple);
-       tab = IndexGetRelation(inhForm->inhrelid, false);
-       if (tab == RelationGetRelid(partitionTbl))
-           ereport(ERROR,
-                   (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
-                    errmsg("cannot attach index \"%s\" as a partition of index \"%s\"",
-                           RelationGetRelationName(partIdx),
-                           RelationGetRelationName(parentIdx)),
-                    errdetail("Another index is already attached for partition \"%s\".",
-                              RelationGetRelationName(partitionTbl))));
-   }
-
-   systable_endscan(scan);
-   table_close(pg_inherits, AccessShareLock);
+   existingIdx = index_get_partition(partitionTbl,
+                                     RelationGetRelid(parentIdx));
+   if (OidIsValid(existingIdx))
+       ereport(ERROR,
+               (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+                errmsg("cannot attach index \"%s\" as a partition of index \"%s\"",
+                       RelationGetRelationName(partIdx),
+                       RelationGetRelationName(parentIdx)),
+                errdetail("Another index is already attached for partition \"%s\".",
+                          RelationGetRelationName(partitionTbl))));
 }
 
 /*
index d84e32598354d70aa05c5be6c979feb0059bec74..616e18af30884d09fff3ab86c14e7528d0c121b4 100644 (file)
@@ -21,6 +21,7 @@
 
 extern Oid get_partition_parent(Oid relid);
 extern List *get_partition_ancestors(Oid relid);
+extern Oid index_get_partition(Relation partition, Oid indexId);
 extern List *map_partition_varattnos(List *expr, int fromrel_varno,
                        Relation to_rel, Relation from_rel,
                        bool *found_whole_row);