@@ -1479,6 +1479,7 @@ describeOneTableDetails(const char *schemaname,
1479
1479
bool rowsecurity ;
1480
1480
bool forcerowsecurity ;
1481
1481
bool hasoids ;
1482
+ bool ispartition ;
1482
1483
Oid tablespace ;
1483
1484
char * reloptions ;
1484
1485
char * reloftype ;
@@ -1502,7 +1503,7 @@ describeOneTableDetails(const char *schemaname,
1502
1503
printfPQExpBuffer (& buf ,
1503
1504
"SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
1504
1505
"c.relhastriggers, c.relrowsecurity, c.relforcerowsecurity, "
1505
- "false AS relhasoids, %s, c.reltablespace, "
1506
+ "false AS relhasoids, c.relispartition, %s, c.reltablespace, "
1506
1507
"CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, "
1507
1508
"c.relpersistence, c.relreplident, am.amname\n"
1508
1509
"FROM pg_catalog.pg_class c\n "
@@ -1515,12 +1516,29 @@ describeOneTableDetails(const char *schemaname,
1515
1516
: "''" ),
1516
1517
oid );
1517
1518
}
1519
+ else if (pset .sversion >= 100000 )
1520
+ {
1521
+ printfPQExpBuffer (& buf ,
1522
+ "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
1523
+ "c.relhastriggers, c.relrowsecurity, c.relforcerowsecurity, "
1524
+ "c.relhasoids, c.relispartition, %s, c.reltablespace, "
1525
+ "CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, "
1526
+ "c.relpersistence, c.relreplident\n"
1527
+ "FROM pg_catalog.pg_class c\n "
1528
+ "LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)\n"
1529
+ "WHERE c.oid = '%s';" ,
1530
+ (verbose ?
1531
+ "pg_catalog.array_to_string(c.reloptions || "
1532
+ "array(select 'toast.' || x from pg_catalog.unnest(tc.reloptions) x), ', ')\n"
1533
+ : "''" ),
1534
+ oid );
1535
+ }
1518
1536
else if (pset .sversion >= 90500 )
1519
1537
{
1520
1538
printfPQExpBuffer (& buf ,
1521
1539
"SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
1522
1540
"c.relhastriggers, c.relrowsecurity, c.relforcerowsecurity, "
1523
- "c.relhasoids, %s, c.reltablespace, "
1541
+ "c.relhasoids, false as relispartition, %s, c.reltablespace, "
1524
1542
"CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, "
1525
1543
"c.relpersistence, c.relreplident\n"
1526
1544
"FROM pg_catalog.pg_class c\n "
@@ -1537,7 +1555,7 @@ describeOneTableDetails(const char *schemaname,
1537
1555
printfPQExpBuffer (& buf ,
1538
1556
"SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
1539
1557
"c.relhastriggers, false, false, c.relhasoids, "
1540
- "%s, c.reltablespace, "
1558
+ "false as relispartition, %s, c.reltablespace, "
1541
1559
"CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, "
1542
1560
"c.relpersistence, c.relreplident\n"
1543
1561
"FROM pg_catalog.pg_class c\n "
@@ -1554,7 +1572,7 @@ describeOneTableDetails(const char *schemaname,
1554
1572
printfPQExpBuffer (& buf ,
1555
1573
"SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
1556
1574
"c.relhastriggers, false, false, c.relhasoids, "
1557
- "%s, c.reltablespace, "
1575
+ "false as relispartition, %s, c.reltablespace, "
1558
1576
"CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, "
1559
1577
"c.relpersistence\n"
1560
1578
"FROM pg_catalog.pg_class c\n "
@@ -1571,7 +1589,7 @@ describeOneTableDetails(const char *schemaname,
1571
1589
printfPQExpBuffer (& buf ,
1572
1590
"SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
1573
1591
"c.relhastriggers, false, false, c.relhasoids, "
1574
- "%s, c.reltablespace, "
1592
+ "false as relispartition, %s, c.reltablespace, "
1575
1593
"CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END\n"
1576
1594
"FROM pg_catalog.pg_class c\n "
1577
1595
"LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)\n"
@@ -1587,7 +1605,7 @@ describeOneTableDetails(const char *schemaname,
1587
1605
printfPQExpBuffer (& buf ,
1588
1606
"SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
1589
1607
"c.relhastriggers, false, false, c.relhasoids, "
1590
- "%s, c.reltablespace\n"
1608
+ "false as relispartition, %s, c.reltablespace\n"
1591
1609
"FROM pg_catalog.pg_class c\n "
1592
1610
"LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)\n"
1593
1611
"WHERE c.oid = '%s';" ,
@@ -1602,7 +1620,7 @@ describeOneTableDetails(const char *schemaname,
1602
1620
printfPQExpBuffer (& buf ,
1603
1621
"SELECT relchecks, relkind, relhasindex, relhasrules, "
1604
1622
"reltriggers <> 0, false, false, relhasoids, "
1605
- "%s, reltablespace\n"
1623
+ "false as relispartition, %s, reltablespace\n"
1606
1624
"FROM pg_catalog.pg_class WHERE oid = '%s';" ,
1607
1625
(verbose ?
1608
1626
"pg_catalog.array_to_string(reloptions, E', ')" : "''" ),
@@ -1613,7 +1631,7 @@ describeOneTableDetails(const char *schemaname,
1613
1631
printfPQExpBuffer (& buf ,
1614
1632
"SELECT relchecks, relkind, relhasindex, relhasrules, "
1615
1633
"reltriggers <> 0, false, false, relhasoids, "
1616
- "'', reltablespace\n"
1634
+ "false as relispartition, '', reltablespace\n"
1617
1635
"FROM pg_catalog.pg_class WHERE oid = '%s';" ,
1618
1636
oid );
1619
1637
}
@@ -1622,7 +1640,7 @@ describeOneTableDetails(const char *schemaname,
1622
1640
printfPQExpBuffer (& buf ,
1623
1641
"SELECT relchecks, relkind, relhasindex, relhasrules, "
1624
1642
"reltriggers <> 0, false, false, relhasoids, "
1625
- "'', ''\n"
1643
+ "false as relispartition, '', ''\n"
1626
1644
"FROM pg_catalog.pg_class WHERE oid = '%s';" ,
1627
1645
oid );
1628
1646
}
@@ -1647,20 +1665,21 @@ describeOneTableDetails(const char *schemaname,
1647
1665
tableinfo .rowsecurity = strcmp (PQgetvalue (res , 0 , 5 ), "t" ) == 0 ;
1648
1666
tableinfo .forcerowsecurity = strcmp (PQgetvalue (res , 0 , 6 ), "t" ) == 0 ;
1649
1667
tableinfo .hasoids = strcmp (PQgetvalue (res , 0 , 7 ), "t" ) == 0 ;
1668
+ tableinfo .ispartition = strcmp (PQgetvalue (res , 0 , 8 ), "t" ) == 0 ;
1650
1669
tableinfo .reloptions = (pset .sversion >= 80200 ) ?
1651
- pg_strdup (PQgetvalue (res , 0 , 8 )) : NULL ;
1670
+ pg_strdup (PQgetvalue (res , 0 , 9 )) : NULL ;
1652
1671
tableinfo .tablespace = (pset .sversion >= 80000 ) ?
1653
- atooid (PQgetvalue (res , 0 , 9 )) : 0 ;
1672
+ atooid (PQgetvalue (res , 0 , 10 )) : 0 ;
1654
1673
tableinfo .reloftype = (pset .sversion >= 90000 &&
1655
- strcmp (PQgetvalue (res , 0 , 10 ), "" ) != 0 ) ?
1656
- pg_strdup (PQgetvalue (res , 0 , 10 )) : NULL ;
1674
+ strcmp (PQgetvalue (res , 0 , 11 ), "" ) != 0 ) ?
1675
+ pg_strdup (PQgetvalue (res , 0 , 11 )) : NULL ;
1657
1676
tableinfo .relpersistence = (pset .sversion >= 90100 ) ?
1658
- * (PQgetvalue (res , 0 , 11 )) : 0 ;
1677
+ * (PQgetvalue (res , 0 , 12 )) : 0 ;
1659
1678
tableinfo .relreplident = (pset .sversion >= 90400 ) ?
1660
- * (PQgetvalue (res , 0 , 12 )) : 'd' ;
1679
+ * (PQgetvalue (res , 0 , 13 )) : 'd' ;
1661
1680
if (pset .sversion >= 120000 )
1662
- tableinfo .relam = PQgetisnull (res , 0 , 13 ) ?
1663
- (char * ) NULL : pg_strdup (PQgetvalue (res , 0 , 13 ));
1681
+ tableinfo .relam = PQgetisnull (res , 0 , 14 ) ?
1682
+ (char * ) NULL : pg_strdup (PQgetvalue (res , 0 , 14 ));
1664
1683
else
1665
1684
tableinfo .relam = NULL ;
1666
1685
PQclear (res );
@@ -2394,12 +2413,36 @@ describeOneTableDetails(const char *schemaname,
2394
2413
if (tableinfo .hastriggers ||
2395
2414
tableinfo .relkind == RELKIND_PARTITIONED_TABLE )
2396
2415
{
2397
- printfPQExpBuffer (& buf ,
2398
- "SELECT conname,\n"
2399
- " pg_catalog.pg_get_constraintdef(r.oid, true) as condef\n"
2400
- "FROM pg_catalog.pg_constraint r\n"
2401
- "WHERE r.conrelid = '%s' AND r.contype = 'f' ORDER BY 1;" ,
2402
- oid );
2416
+ if (pset .sversion >= 120000 &&
2417
+ (tableinfo .ispartition || tableinfo .relkind == RELKIND_PARTITIONED_TABLE ))
2418
+ {
2419
+ /*
2420
+ * Put the constraints defined in this table first, followed
2421
+ * by the constraints defined in ancestor partitioned tables.
2422
+ */
2423
+ printfPQExpBuffer (& buf ,
2424
+ "SELECT conrelid = '%s'::pg_catalog.regclass AS sametable,\n"
2425
+ " conname,\n"
2426
+ " pg_catalog.pg_get_constraintdef(oid, true) AS condef,\n"
2427
+ " conrelid::pg_catalog.regclass AS ontable\n"
2428
+ " FROM pg_catalog.pg_constraint,\n"
2429
+ " pg_catalog.pg_partition_ancestors('%s')\n"
2430
+ " WHERE conrelid = relid AND contype = 'f' AND conparentid = 0\n"
2431
+ "ORDER BY sametable DESC, conname;" ,
2432
+ oid , oid );
2433
+ }
2434
+ else
2435
+ {
2436
+ printfPQExpBuffer (& buf ,
2437
+ "SELECT true as sametable, conname,\n"
2438
+ " pg_catalog.pg_get_constraintdef(r.oid, true) as condef,\n"
2439
+ " conrelid::pg_catalog.regclass AS ontable\n"
2440
+ "FROM pg_catalog.pg_constraint r\n"
2441
+ "WHERE r.conrelid = '%s' AND r.contype = 'f'\n"
2442
+ "ORDER BY conname;" ,
2443
+ oid );
2444
+ }
2445
+
2403
2446
result = PSQLexec (buf .data );
2404
2447
if (!result )
2405
2448
goto error_return ;
@@ -2408,29 +2451,62 @@ describeOneTableDetails(const char *schemaname,
2408
2451
2409
2452
if (tuples > 0 )
2410
2453
{
2454
+ int i_sametable = PQfnumber (result , "sametable" ),
2455
+ i_conname = PQfnumber (result , "conname" ),
2456
+ i_condef = PQfnumber (result , "condef" ),
2457
+ i_ontable = PQfnumber (result , "ontable" );
2458
+
2411
2459
printTableAddFooter (& cont , _ ("Foreign-key constraints:" ));
2412
2460
for (i = 0 ; i < tuples ; i ++ )
2413
2461
{
2414
- /* untranslated constraint name and def */
2415
- printfPQExpBuffer (& buf , " \"%s\" %s" ,
2416
- PQgetvalue (result , i , 0 ),
2417
- PQgetvalue (result , i , 1 ));
2462
+ /*
2463
+ * Print untranslated constraint name and definition. Use
2464
+ * a "TABLE tab" prefix when the constraint is defined in
2465
+ * a parent partitioned table.
2466
+ */
2467
+ if (strcmp (PQgetvalue (result , i , i_sametable ), "f" ) == 0 )
2468
+ printfPQExpBuffer (& buf , " TABLE \"%s\" CONSTRAINT \"%s\" %s" ,
2469
+ PQgetvalue (result , i , i_ontable ),
2470
+ PQgetvalue (result , i , i_conname ),
2471
+ PQgetvalue (result , i , i_condef ));
2472
+ else
2473
+ printfPQExpBuffer (& buf , " \"%s\" %s" ,
2474
+ PQgetvalue (result , i , i_conname ),
2475
+ PQgetvalue (result , i , i_condef ));
2418
2476
2419
2477
printTableAddFooter (& cont , buf .data );
2420
2478
}
2421
2479
}
2422
2480
PQclear (result );
2423
2481
}
2424
2482
2425
- /* print incoming foreign-key references (none if no triggers) */
2426
- if (tableinfo .hastriggers )
2483
+ /* print incoming foreign-key references */
2484
+ if (tableinfo .hastriggers ||
2485
+ tableinfo .relkind == RELKIND_PARTITIONED_TABLE )
2427
2486
{
2428
- printfPQExpBuffer (& buf ,
2429
- "SELECT conname, conrelid::pg_catalog.regclass,\n"
2430
- " pg_catalog.pg_get_constraintdef(c.oid, true) as condef\n"
2431
- "FROM pg_catalog.pg_constraint c\n"
2432
- "WHERE c.confrelid = '%s' AND c.contype = 'f' ORDER BY 1;" ,
2433
- oid );
2487
+ if (pset .sversion >= 120000 )
2488
+ {
2489
+ printfPQExpBuffer (& buf ,
2490
+ "SELECT conname, conrelid::pg_catalog.regclass AS ontable,\n"
2491
+ " pg_catalog.pg_get_constraintdef(oid, true) AS condef\n"
2492
+ " FROM pg_catalog.pg_constraint c\n"
2493
+ " WHERE confrelid IN (SELECT pg_catalog.pg_partition_ancestors('%s')\n"
2494
+ " UNION ALL VALUES ('%s'::pg_catalog.regclass))\n"
2495
+ " AND contype = 'f' AND conparentid = 0\n"
2496
+ "ORDER BY conname;" ,
2497
+ oid , oid );
2498
+ }
2499
+ else
2500
+ {
2501
+ printfPQExpBuffer (& buf ,
2502
+ "SELECT conname, conrelid::pg_catalog.regclass AS ontable,\n"
2503
+ " pg_catalog.pg_get_constraintdef(oid, true) AS condef\n"
2504
+ " FROM pg_catalog.pg_constraint\n"
2505
+ " WHERE confrelid = %s AND contype = 'f'\n"
2506
+ "ORDER BY conname;" ,
2507
+ oid );
2508
+ }
2509
+
2434
2510
result = PSQLexec (buf .data );
2435
2511
if (!result )
2436
2512
goto error_return ;
@@ -2439,13 +2515,17 @@ describeOneTableDetails(const char *schemaname,
2439
2515
2440
2516
if (tuples > 0 )
2441
2517
{
2518
+ int i_conname = PQfnumber (result , "conname" ),
2519
+ i_ontable = PQfnumber (result , "ontable" ),
2520
+ i_condef = PQfnumber (result , "condef" );
2521
+
2442
2522
printTableAddFooter (& cont , _ ("Referenced by:" ));
2443
2523
for (i = 0 ; i < tuples ; i ++ )
2444
2524
{
2445
2525
printfPQExpBuffer (& buf , " TABLE \"%s\" CONSTRAINT \"%s\" %s" ,
2446
- PQgetvalue (result , i , 1 ),
2447
- PQgetvalue (result , i , 0 ),
2448
- PQgetvalue (result , i , 2 ));
2526
+ PQgetvalue (result , i , i_ontable ),
2527
+ PQgetvalue (result , i , i_conname ),
2528
+ PQgetvalue (result , i , i_condef ));
2449
2529
2450
2530
printTableAddFooter (& cont , buf .data );
2451
2531
}
0 commit comments