When CREATE INDEX is invoked on a partitioned table, the default
behavior is to recurse to all partitions to ensure they all have
matching indexes. Each partition is first checked to determine whether
an equivalent index already exists, and if so, that index will become
attached as a partition index to the index being created, which will
become its parent index. If no matching index exists, a new index will
be created and automatically attached; the name of the new index in
each partition will be determined as if no index name had been
specified in the command. If the ONLY option is specified, no
recursion is done, and the index is marked invalid. (ALTER INDEX ...
ATTACH PARTITION marks the index valid, once all partitions acquire
matching indexes.) Note, however, that any partition that is created
in the future using CREATE TABLE ... PARTITION OF will automatically
have a matching index, regardless of whether ONLY is specified.
small demo example:
create table index_part (a int, b int) partition by range (a, b);
create table index_part1 partition of index_part for values from (0,0) to (10, 10);
create table index_part2 partition of index_part for values from (10,10) to (20, 20);
create index index_part_a_b_idx on only index_part (a, b);
now is INVALID:
\d+ index_part_a_b_idx
---
btree, for table "public.index_part", invalid
Partitions: index_part2_a_b_idx
Access method: btree
create index idxpart1_a_b_idx on index_part1 (a, b);
alter index index_part_a_b_idx attach partition idxpart1_a_b_idx;
still INVALID.
\d+ index_part_a_b_idx
---
btree, for table "public.index_part", invalid
Partitions: idxpart1_a_b_idx
Access method: btree
then
create index idxpart2_a_b_idx on index_part2(a, b);
alter index index_part_a_b_idx attach partition idxpart2_a_b_idx;
now ISVALID.
select indisvalid from pg_index where indexrelid = 'idxpart2_a_b_idx'::regclass; ---return true.