Skip to content

Commit 943e082

Browse files
def-claude
andauthored
catalog: Fix pg_index.indnatts and pg_class.relnatts for index rows (#36314)
indnatts was counting columns of the indexed table instead of the index itself. relnatts was always 0 for index rows because mz_columns has no entries keyed by index IDs. Follow-up to #33204 Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 0839a26 commit 943e082

3 files changed

Lines changed: 40 additions & 20 deletions

File tree

src/catalog/src/builtin.rs

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7111,14 +7111,24 @@ SELECT
71117111
WHEN class_objects.type = 'view' THEN 'v'
71127112
WHEN class_objects.type = 'materialized-view' THEN 'm'
71137113
END relkind,
7114-
COALESCE(
7115-
(
7116-
SELECT count(*)::pg_catalog.int2
7117-
FROM mz_catalog.mz_columns
7118-
WHERE mz_columns.id = class_objects.id
7119-
),
7120-
0::pg_catalog.int2
7121-
) AS relnatts,
7114+
CASE
7115+
WHEN class_objects.type = 'index' THEN COALESCE(
7116+
(
7117+
SELECT count(*)::pg_catalog.int2
7118+
FROM mz_catalog.mz_index_columns
7119+
WHERE mz_index_columns.index_id = class_objects.id
7120+
),
7121+
0::pg_catalog.int2
7122+
)
7123+
ELSE COALESCE(
7124+
(
7125+
SELECT count(*)::pg_catalog.int2
7126+
FROM mz_catalog.mz_columns
7127+
WHERE mz_columns.id = class_objects.id
7128+
),
7129+
0::pg_catalog.int2
7130+
)
7131+
END AS relnatts,
71227132
-- MZ doesn't support CHECK constraints so relchecks is filled with 0
71237133
0::pg_catalog.int2 AS relchecks,
71247134
-- MZ doesn't support creating rules so relhasrules is filled with false
@@ -7334,15 +7344,7 @@ pub static PG_INDEX: LazyLock<BuiltinView> = LazyLock::new(|| {
73347344
sql: "SELECT
73357345
mz_indexes.oid AS indexrelid,
73367346
mz_relations.oid AS indrelid,
7337-
COALESCE(
7338-
(
7339-
SELECT count(*)::pg_catalog.int2
7340-
FROM mz_catalog.mz_columns
7341-
JOIN mz_catalog.mz_relations mri ON mz_columns.id = mri.id
7342-
WHERE mri.oid = mz_catalog.mz_relations.oid
7343-
),
7344-
0::pg_catalog.int2
7345-
) AS indnatts,
7347+
count(mz_index_columns.index_position)::pg_catalog.int2 AS indnatts,
73467348
-- MZ doesn't support creating unique indexes so indisunique is filled with false
73477349
false::pg_catalog.bool AS indisunique,
73487350
false::pg_catalog.bool AS indisprimary,

test/sqllogictest/pg_catalog_class.slt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ WHERE relname = (SELECT name FROM mz_indexes WHERE on_id = (SELECT id FROM mz_ob
4848
----
4949
0 0 0 0 false p i 0 false false false false d false false
5050

51+
# relnatts for an index row is the number of columns in the index
52+
query TI
53+
SELECT relname, relnatts FROM pg_catalog.pg_class
54+
WHERE relname = (SELECT name FROM mz_indexes WHERE on_id = (SELECT id FROM mz_objects WHERE name = 'a'))
55+
----
56+
a_primary_idx 1
57+
5158
# Test that pg_class is restricted to the current database, but includes items
5259
# in ambient schemas (in this case, pg_class itself).
5360

test/sqllogictest/pg_catalog_index.slt

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,21 @@ CREATE TABLE a (b int, c int);
1515
statement ok
1616
CREATE INDEX a_index ON a (b);
1717

18-
# Test that pg_class reports the correct number of columns of an index's relation
18+
# indnatts is the number of columns in the index, not the indexed table
1919
query I
2020
SELECT indnatts FROM pg_catalog.pg_index
21-
JOIN mz_catalog.mz_relations ON pg_catalog.pg_index.indrelid = mz_catalog.mz_relations.oid
22-
WHERE mz_catalog.mz_relations.name = 'a'
21+
JOIN mz_catalog.mz_indexes ON pg_catalog.pg_index.indexrelid = mz_catalog.mz_indexes.oid
22+
WHERE mz_catalog.mz_indexes.name = 'a_index'
23+
----
24+
1
25+
26+
statement ok
27+
CREATE INDEX a_index2 ON a (b, c);
28+
29+
# Multi-column index reports 2
30+
query I
31+
SELECT indnatts FROM pg_catalog.pg_index
32+
JOIN mz_catalog.mz_indexes ON pg_catalog.pg_index.indexrelid = mz_catalog.mz_indexes.oid
33+
WHERE mz_catalog.mz_indexes.name = 'a_index2'
2334
----
2435
2

0 commit comments

Comments
 (0)