Simplify psql \d's rule for ordering the indexes of a table.
authorTom Lane
Tue, 2 Jul 2019 16:32:49 +0000 (12:32 -0400)
committerTom Lane
Tue, 2 Jul 2019 16:32:49 +0000 (12:32 -0400)
The previous rule was "primary key (if any) first, then other unique
indexes in name order, then all other indexes in name order".
But the preference for unique indexes seems a bit obsolete since the
introduction of exclusion constraints.   It's no longer the case
that unique indexes are the only ones that constrain what data can
be in the table, and it's hard to see what other rationale there is
for separating out unique indexes.  Other new features like the
possibility for some indexes to be INVALID (hence, not constraining
anything) make this even shakier.

Hence, simplify the sort order to be "primary key (if any) first,
then all other indexes in name order".

No documentation change, since this was never documented anyway.
A couple of existing regression test cases change output, though.

Discussion: https://postgr.es/m/14422.1561474929@sss.pgh.pa.us

src/bin/psql/describe.c
src/test/regress/expected/alter_table.out
src/test/regress/expected/create_index.out
src/test/regress/expected/replica_identity.out

index 97167d2c4bdb2f29ceec491fe73062bd3a158db8..1c770b4347a1dc901d41f887473f25347243de4b 100644 (file)
@@ -2312,7 +2312,7 @@ describeOneTableDetails(const char *schemaname,
                                     "  LEFT JOIN pg_catalog.pg_constraint con ON (conrelid = i.indrelid AND conindid = i.indexrelid AND contype IN ('p','u','x'))\n");
            appendPQExpBuffer(&buf,
                              "WHERE c.oid = '%s' AND c.oid = i.indrelid AND i.indexrelid = c2.oid\n"
-                             "ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname;",
+                             "ORDER BY i.indisprimary DESC, c2.relname;",
                              oid);
            result = PSQLexec(buf.data);
            if (!result)
index e687150511bb09f7e965ca95289f2c6c2b8f55d1..d621f61c623b031def9b2c8a6b3b9295fa59da20 100644 (file)
@@ -1925,12 +1925,12 @@ create unique index on anothertab(f4);
 Indexes:
     "anothertab_pkey" PRIMARY KEY, btree (f1)
     "anothertab_f1_f4_key" UNIQUE CONSTRAINT, btree (f1, f4)
-    "anothertab_f2_key" UNIQUE CONSTRAINT, btree (f2)
-    "anothertab_f4_idx" UNIQUE, btree (f4)
     "anothertab_f2_f3_idx" btree (f2, f3)
+    "anothertab_f2_key" UNIQUE CONSTRAINT, btree (f2)
     "anothertab_f3_excl" EXCLUDE USING btree (f3 WITH =)
     "anothertab_f4_excl" EXCLUDE USING btree (f4 WITH =) WHERE (f4 IS NOT NULL)
     "anothertab_f4_excl1" EXCLUDE USING btree (f4 WITH =) WHERE (f5 > 0)
+    "anothertab_f4_idx" UNIQUE, btree (f4)
 
 alter table anothertab alter column f1 type bigint;
 alter table anothertab
@@ -1950,12 +1950,12 @@ alter table anothertab alter column f5 type bigint;
 Indexes:
     "anothertab_pkey" PRIMARY KEY, btree (f1)
     "anothertab_f1_f4_key" UNIQUE CONSTRAINT, btree (f1, f4)
-    "anothertab_f2_key" UNIQUE CONSTRAINT, btree (f2)
-    "anothertab_f4_idx" UNIQUE, btree (f4)
     "anothertab_f2_f3_idx" btree (f2, f3)
+    "anothertab_f2_key" UNIQUE CONSTRAINT, btree (f2)
     "anothertab_f3_excl" EXCLUDE USING btree (f3 WITH =)
     "anothertab_f4_excl" EXCLUDE USING btree (f4 WITH =) WHERE (f4 IS NOT NULL)
     "anothertab_f4_excl1" EXCLUDE USING btree (f4 WITH =) WHERE (f5 > 0)
+    "anothertab_f4_idx" UNIQUE, btree (f4)
 
 drop table anothertab;
 create table another (f1 int, f2 text);
index 5305b53cac94a06722c7f94b2fd0f3ec1e090f97..9305649c1131bfef40e5cb9a26e4b9caf2ccd5c9 100644 (file)
@@ -1374,10 +1374,10 @@ VACUUM FULL concur_heap;
  f1     | text |           |          | 
  f2     | text |           |          | 
 Indexes:
-    "concur_index2" UNIQUE, btree (f1)
-    "concur_index3" UNIQUE, btree (f2) INVALID
     "concur_heap_expr_idx" btree ((f2 || f1))
     "concur_index1" btree (f2, f1)
+    "concur_index2" UNIQUE, btree (f1)
+    "concur_index3" UNIQUE, btree (f2) INVALID
     "concur_index4" btree (f2) WHERE f1 = 'a'::text
     "concur_index5" btree (f2) WHERE f1 = 'x'::text
     "std_index" btree (f2)
@@ -1390,10 +1390,10 @@ REINDEX TABLE concur_heap;
  f1     | text |           |          | 
  f2     | text |           |          | 
 Indexes:
-    "concur_index2" UNIQUE, btree (f1)
-    "concur_index3" UNIQUE, btree (f2)
     "concur_heap_expr_idx" btree ((f2 || f1))
     "concur_index1" btree (f2, f1)
+    "concur_index2" UNIQUE, btree (f1)
+    "concur_index3" UNIQUE, btree (f2)
     "concur_index4" btree (f2) WHERE f1 = 'a'::text
     "concur_index5" btree (f2) WHERE f1 = 'x'::text
     "std_index" btree (f2)
@@ -2115,8 +2115,8 @@ WARNING:  cannot reindex system catalogs concurrently, skipping all
  c2     | text    |           |          | 
 Indexes:
     "concur_reindex_ind1" PRIMARY KEY, btree (c1)
-    "concur_reindex_ind3" UNIQUE, btree (abs(c1))
     "concur_reindex_ind2" btree (c2)
+    "concur_reindex_ind3" UNIQUE, btree (abs(c1))
     "concur_reindex_ind4" btree (c1, c1, c2)
 Referenced by:
     TABLE "concur_reindex_tab2" CONSTRAINT "concur_reindex_tab2_c1_fkey" FOREIGN KEY (c1) REFERENCES concur_reindex_tab(c1)
index 175ecd28794affb536a7f210538b650e4ec15e68..739608aab4c73aad58906ee98f680464f66c2f29 100644 (file)
@@ -85,13 +85,13 @@ SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass;
 Indexes:
     "test_replica_identity_pkey" PRIMARY KEY, btree (id) REPLICA IDENTITY
     "test_replica_identity_expr" UNIQUE, btree (keya, keyb, (3))
+    "test_replica_identity_hash" hash (nonkey)
+    "test_replica_identity_keyab" btree (keya, keyb)
     "test_replica_identity_keyab_key" UNIQUE, btree (keya, keyb)
     "test_replica_identity_nonkey" UNIQUE, btree (keya, nonkey)
     "test_replica_identity_partial" UNIQUE, btree (keya, keyb) WHERE keyb <> '3'::text
     "test_replica_identity_unique_defer" UNIQUE CONSTRAINT, btree (keya, keyb) DEFERRABLE
     "test_replica_identity_unique_nondefer" UNIQUE CONSTRAINT, btree (keya, keyb)
-    "test_replica_identity_hash" hash (nonkey)
-    "test_replica_identity_keyab" btree (keya, keyb)
 
 -- succeed, nondeferrable unique constraint over nonnullable cols
 ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_unique_nondefer;
@@ -115,13 +115,13 @@ SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass;
 Indexes:
     "test_replica_identity_pkey" PRIMARY KEY, btree (id)
     "test_replica_identity_expr" UNIQUE, btree (keya, keyb, (3))
+    "test_replica_identity_hash" hash (nonkey)
+    "test_replica_identity_keyab" btree (keya, keyb)
     "test_replica_identity_keyab_key" UNIQUE, btree (keya, keyb) REPLICA IDENTITY
     "test_replica_identity_nonkey" UNIQUE, btree (keya, nonkey)
     "test_replica_identity_partial" UNIQUE, btree (keya, keyb) WHERE keyb <> '3'::text
     "test_replica_identity_unique_defer" UNIQUE CONSTRAINT, btree (keya, keyb) DEFERRABLE
     "test_replica_identity_unique_nondefer" UNIQUE CONSTRAINT, btree (keya, keyb)
-    "test_replica_identity_hash" hash (nonkey)
-    "test_replica_identity_keyab" btree (keya, keyb)
 
 SELECT count(*) FROM pg_index WHERE indrelid = 'test_replica_identity'::regclass AND indisreplident;
  count 
@@ -163,13 +163,13 @@ SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass;
 Indexes:
     "test_replica_identity_pkey" PRIMARY KEY, btree (id)
     "test_replica_identity_expr" UNIQUE, btree (keya, keyb, (3))
+    "test_replica_identity_hash" hash (nonkey)
+    "test_replica_identity_keyab" btree (keya, keyb)
     "test_replica_identity_keyab_key" UNIQUE, btree (keya, keyb)
     "test_replica_identity_nonkey" UNIQUE, btree (keya, nonkey)
     "test_replica_identity_partial" UNIQUE, btree (keya, keyb) WHERE keyb <> '3'::text
     "test_replica_identity_unique_defer" UNIQUE CONSTRAINT, btree (keya, keyb) DEFERRABLE
     "test_replica_identity_unique_nondefer" UNIQUE CONSTRAINT, btree (keya, keyb)
-    "test_replica_identity_hash" hash (nonkey)
-    "test_replica_identity_keyab" btree (keya, keyb)
 Replica Identity: FULL
 
 ALTER TABLE test_replica_identity REPLICA IDENTITY NOTHING;