Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

btree_index_atts CTE should assign attnum's starting at 1 #2

Open
fmcgeough opened this issue Jan 20, 2016 · 2 comments
Open

btree_index_atts CTE should assign attnum's starting at 1 #2

fmcgeough opened this issue Jan 20, 2016 · 2 comments

Comments

@fmcgeough
Copy link

I think : regexp_split_to_table(indkey::text, ' ')::smallint AS attnum,

should be : generate_series(1, array_length(indkey,1))::smallint AS attnum,

the join with pg_attributes include attnum but pg_attributes will number the attributes for the index at 1. the pg_index indkey is the physical index to the column within the table.

thanks for this query. its very helpful.

@qdw
Copy link
Contributor

qdw commented Jan 27, 2016

Thanks for the report! Let me summarize my understanding.

To my reading, both pg_index.indkey and pg_attribute use 1-based numbering for columns[1]. However, 0 has different meanings between those two tables:

  • pg_index.indkey = 0 means the index is "an expression over table columns" (like 'WHERE my_column IS NOT NULL')
  • pg_attribute.attnum = 0 means… actually, I'm not sure. The docs just say "System columns, such as oid, have (arbitrary) negative numbers" without mentioning 0.

If pg_attribute.attnum never has zeroes in it, then the JOIN won't return any multicolumn indexes:

    JOIN btree_index_atts AS ind_atts ON pg_attribute.attrelid = ind_atts.indexrelid AND pg_attribute.attnum = ind_atts.attnum

… but that's also true with your proposed solution, right?

If, on the other hand, pg_attribute.attnum can have zeroes in it, then we might get misleading results. Was that your concern?

Sorry if I'm missing the point; if so, please correct me. Of course, either way, the larger issue is that expression indexes won't (currently) be included in the bloat report.

Thanks,
Quinn

[1] From the docs:

@derkv-github
Copy link

The problem is that regexp_split_to_table(indkey::text, ' ')::smallint AS attnum returns the relative column numbers of the columns in the table. For example column number 10 and 11 if your index is created on these columns

The column pg_attribute.attnum contains the relative columns in the index, which always starts at 1. When you join the on columns from regexp_split_to_table(indkey::text, ' ') with pg_attribute.attnum you and up with a lot of missing lines. In the case where the index is on column 10 and 11 of the table, you remove the index completely from the resultset because the is no 10th and 11th column in the index.

Solution

  • Remove line 11 regexp_split_to_table(indkey::text, ' ')::smallint AS attnum,
  • Change the join condition on line 35 to JOIN btree_index_atts AS ind_atts ON pg_attribute.attrelid = ind_atts.indexrelid ie remove the join condition pg_attribute.attnum = ind_atts.attnum. This way you join all the columns in the index.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants