@@ -138,6 +138,10 @@ typedef struct PartitionRangeBound
138
138
bool lower ; /* this is the lower (vs upper) bound */
139
139
} PartitionRangeBound ;
140
140
141
+
142
+ static Oid get_partition_parent_worker (Relation inhRel , Oid relid );
143
+ static void get_partition_ancestors_worker (Relation inhRel , Oid relid ,
144
+ List * * ancestors );
141
145
static int32 qsort_partition_hbound_cmp (const void * a , const void * b );
142
146
static int32 qsort_partition_list_value_cmp (const void * a , const void * b ,
143
147
void * arg );
@@ -1377,6 +1381,7 @@ check_default_allows_bound(Relation parent, Relation default_rel,
1377
1381
1378
1382
/*
1379
1383
* get_partition_parent
1384
+ * Obtain direct parent of given relation
1380
1385
*
1381
1386
* Returns inheritance parent of a partition by scanning pg_inherits
1382
1387
*
@@ -1387,15 +1392,34 @@ check_default_allows_bound(Relation parent, Relation default_rel,
1387
1392
Oid
1388
1393
get_partition_parent (Oid relid )
1389
1394
{
1390
- Form_pg_inherits form ;
1391
1395
Relation catalogRelation ;
1392
- SysScanDesc scan ;
1393
- ScanKeyData key [2 ];
1394
- HeapTuple tuple ;
1395
1396
Oid result ;
1396
1397
1397
1398
catalogRelation = heap_open (InheritsRelationId , AccessShareLock );
1398
1399
1400
+ result = get_partition_parent_worker (catalogRelation , relid );
1401
+
1402
+ if (!OidIsValid (result ))
1403
+ elog (ERROR , "could not find tuple for parent of relation %u" , relid );
1404
+
1405
+ heap_close (catalogRelation , AccessShareLock );
1406
+
1407
+ return result ;
1408
+ }
1409
+
1410
+ /*
1411
+ * get_partition_parent_worker
1412
+ * Scan the pg_inherits relation to return the OID of the parent of the
1413
+ * given relation
1414
+ */
1415
+ static Oid
1416
+ get_partition_parent_worker (Relation inhRel , Oid relid )
1417
+ {
1418
+ SysScanDesc scan ;
1419
+ ScanKeyData key [2 ];
1420
+ Oid result = InvalidOid ;
1421
+ HeapTuple tuple ;
1422
+
1399
1423
ScanKeyInit (& key [0 ],
1400
1424
Anum_pg_inherits_inhrelid ,
1401
1425
BTEqualStrategyNumber , F_OIDEQ ,
@@ -1405,22 +1429,64 @@ get_partition_parent(Oid relid)
1405
1429
BTEqualStrategyNumber , F_INT4EQ ,
1406
1430
Int32GetDatum (1 ));
1407
1431
1408
- scan = systable_beginscan (catalogRelation , InheritsRelidSeqnoIndexId , true,
1432
+ scan = systable_beginscan (inhRel , InheritsRelidSeqnoIndexId , true,
1409
1433
NULL , 2 , key );
1410
-
1411
1434
tuple = systable_getnext (scan );
1412
- if (!HeapTupleIsValid (tuple ))
1413
- elog (ERROR , "could not find tuple for parent of relation %u" , relid );
1435
+ if (HeapTupleIsValid (tuple ))
1436
+ {
1437
+ Form_pg_inherits form = (Form_pg_inherits ) GETSTRUCT (tuple );
1414
1438
1415
- form = ( Form_pg_inherits ) GETSTRUCT ( tuple ) ;
1416
- result = form -> inhparent ;
1439
+ result = form -> inhparent ;
1440
+ }
1417
1441
1418
1442
systable_endscan (scan );
1419
- heap_close (catalogRelation , AccessShareLock );
1420
1443
1421
1444
return result ;
1422
1445
}
1423
1446
1447
+ /*
1448
+ * get_partition_ancestors
1449
+ * Obtain ancestors of given relation
1450
+ *
1451
+ * Returns a list of ancestors of the given relation.
1452
+ *
1453
+ * Note: Because this function assumes that the relation whose OID is passed
1454
+ * as an argument and each ancestor will have precisely one parent, it should
1455
+ * only be called when it is known that the relation is a partition.
1456
+ */
1457
+ List *
1458
+ get_partition_ancestors (Oid relid )
1459
+ {
1460
+ List * result = NIL ;
1461
+ Relation inhRel ;
1462
+
1463
+ inhRel = heap_open (InheritsRelationId , AccessShareLock );
1464
+
1465
+ get_partition_ancestors_worker (inhRel , relid , & result );
1466
+
1467
+ heap_close (inhRel , AccessShareLock );
1468
+
1469
+ return result ;
1470
+ }
1471
+
1472
+ /*
1473
+ * get_partition_ancestors_worker
1474
+ * recursive worker for get_partition_ancestors
1475
+ */
1476
+ static void
1477
+ get_partition_ancestors_worker (Relation inhRel , Oid relid , List * * ancestors )
1478
+ {
1479
+ Oid parentOid ;
1480
+
1481
+ /* Recursion ends at the topmost level, ie., when there's no parent */
1482
+ parentOid = get_partition_parent_worker (inhRel , relid );
1483
+ if (parentOid == InvalidOid )
1484
+ return ;
1485
+
1486
+ * ancestors = lappend_oid (* ancestors , parentOid );
1487
+ get_partition_ancestors_worker (inhRel , parentOid , ancestors );
1488
+ }
1489
+
1424
1490
/*
1425
1491
* get_qual_from_partbound
1426
1492
* Given a parser node for partition bound, return the list of executable
0 commit comments