title: Postgresql partition pruning and btree_gin indexes not playing ball
body: <p>The setup can be roughly summarized as follows:</p>
  <pre><code>CREATE TYPE bird_species AS ENUM('sparrow', 'chicken', 'hawk');
  
  CREATE TABLE bird (
    id INTEGER GENERATED ALWAYS AS IDENTITY,
    species bird_species NOT NULL,
    description TEXT,
    PRIMARY KEY(species, id)
  ) PARTITION BY LIST(species);
  
  CREATE TABLE bird_sparrow PARTITION OF bird
  FOR VALUES IN ('sparrow');
  
  CREATE TABLE bird_chicken PARTITION OF bird
  FOR VALUES IN ('chicken');
  
  CREATE TABLE bird_hawk PARTITION OF bird
  FOR VALUES IN ('hawk');
  </code></pre>
  <p>description is not null for around 17% of entries.
  The table is filled in with a couple million entries.</p>
  <p>I want the query</p>
  <pre><code>SELECT * FROM bird
  WHERE
    species = 'sparrow'
    AND description IS NOT NULL
    AND to_tsvector('english', description) @@ plainto_tsquery('english', $1)
  ORDER BY id DESC
  LIMIT 10
  </code></pre>
  <p>to run at a reasonable speed.
  I've attempted creating a btree_gin index:</p>
  <pre><code>CREATE INDEX bird_species_description_index ON bird USING GIN(species, to_tsvector(description)) WHERE description IS NOT NULL;
  </code></pre>
  <p>But the query seems to still fall on an inverted pk index scan followed by a filter.
  However, the queries</p>
  <pre><code>SELECT * FROM bird
  WHERE
    species = 'sparrow'
    AND description IS NOT NULL
    AND to_tsvector('english', description) @@ plainto_tsquery('english', $1)
  ORDER BY id DESC
  </code></pre>
  <p>(does exactly the bitmap index scan on the partial index on the partitioned table you'd expect and is my current hack solution) and</p>
  <pre><code>SELECT * FROM bird
  WHERE
    description IS NOT NULL
    AND to_tsvector('english', description) @@ plainto_tsquery('english', $1)
  ORDER BY id DESC
  LIMIT 10
  </code></pre>
  <p>(does the correct bitmap index scan on each partition and then joins everything) are both very performant.</p>
  <p>I think postgres is falling onto a very queer index plan because it doesn't know what values are actually common in the GIN index, but I don't know how to solve that.</p>
  <p>Postgres version: 14.3.</p>
  <p>Configuration: default except for 500mb shared buffers, random page cost set to 1.1 and work_mem increased to 2MB.</p>