{"action":"created","issue":{"url":"https://api.github.com/repos/rails/rails/issues/19090","labels_url":"https://api.github.com/repos/rails/rails/issues/19090/labels{/name}","comments_url":"https://api.github.com/repos/rails/rails/issues/19090/comments","events_url":"https://api.github.com/repos/rails/rails/issues/19090/events","html_url":"https://github.com/rails/rails/pull/19090","id":59065048,"number":19090,"title":"Add support for PostgreSQL operator classes to add_index","user":{"login":"grn","id":90490,"avatar_url":"https://avatars.githubusercontent.com/u/90490?v=3","gravatar_id":"","url":"https://api.github.com/users/grn","html_url":"https://github.com/grn","followers_url":"https://api.github.com/users/grn/followers","following_url":"https://api.github.com/users/grn/following{/other_user}","gists_url":"https://api.github.com/users/grn/gists{/gist_id}","starred_url":"https://api.github.com/users/grn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/grn/subscriptions","organizations_url":"https://api.github.com/users/grn/orgs","repos_url":"https://api.github.com/users/grn/repos","events_url":"https://api.github.com/users/grn/events{/privacy}","received_events_url":"https://api.github.com/users/grn/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":13,"created_at":"2015-02-26T12:25:26Z","updated_at":"2015-02-27T22:07:37Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/rails/rails/pulls/19090","html_url":"https://github.com/rails/rails/pull/19090","diff_url":"https://github.com/rails/rails/pull/19090.diff","patch_url":"https://github.com/rails/rails/pull/19090.patch"},"body":"# Use case\r\n\r\nI needed to use trigrams when `SELECT`-ing from a table. I want to use `schema.rb`. Unfortunately this wasn't possible to create an appropriate index. The required query is:\r\n\r\n```sql\r\nCREATE INDEX users_name ON users USING gist (name gist_trgm_ops);\r\n```\r\n\r\nThe `gist_trgm_ops` after `name` is the [operator class](http://www.postgresql.org/docs/current/static/indexes-opclass.html) to use when using the index. Currently it's possible to specify `... USING gist (name)` but there's no way of adding the operator class after `name`.\r\n\r\nPostgreSQL is the *only* affected database. Other databases are not affected.\r\n\r\n# Solution\r\n\r\nOperator classes can be explicitly specified in `add_index` as:\r\n\r\n```ruby\r\nadd_index :users, :name, using: :gist, opclasses: {name: :gist_trgm_ops}\r\n```\r\n\r\n# Changes\r\n\r\n* added `opclasses` to `IndexDefinition` and made it a valid `add_index` option\r\n* added support for `opclasses` to `SchemaDumper`\r\n* test cases for the changes above\r\n\r\n# Issues\r\n\r\nBelow are issues I run into. I present my decision and a rationale for it. Any feedback is welcome! Hopefully some improvement is possible.\r\n\r\n## Syntax\r\n\r\nI wasn't sure what's the best syntax. I considered\r\n\r\n```ruby\r\nadd_index :users, {name: :gist_trgm_ops}, using: :gist\r\n```\r\n\r\nbut it places PostgreSQL-specific data where the user might not expect it.\r\n\r\nI decided to use a new option as this makes the implementation *very* simple and makes the opclasses used explicit. The tradeoff is that the column names must be specified twice.\r\n\r\n## Extraneous whitespace\r\n\r\nThere's always a space after a column name used in the index even when no operator class is specified. For example `... USING gist (name)` is turned into `... USING gist (name )`. I decided that this makes the code simpler at the expense of a tiny ugliness in the test suite. Additionally multiple spaces already appear in some statements, e.g. `CREATE  INDEX` when `UNIQE` is *not* present."},"comment":{"url":"https://api.github.com/repos/rails/rails/issues/comments/76481131","html_url":"https://github.com/rails/rails/pull/19090#issuecomment-76481131","issue_url":"https://api.github.com/repos/rails/rails/issues/19090","id":76481131,"user":{"login":"sgrif","id":1529387,"avatar_url":"https://avatars.githubusercontent.com/u/1529387?v=3","gravatar_id":"","url":"https://api.github.com/users/sgrif","html_url":"https://github.com/sgrif","followers_url":"https://api.github.com/users/sgrif/followers","following_url":"https://api.github.com/users/sgrif/following{/other_user}","gists_url":"https://api.github.com/users/sgrif/gists{/gist_id}","starred_url":"https://api.github.com/users/sgrif/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sgrif/subscriptions","organizations_url":"https://api.github.com/users/sgrif/orgs","repos_url":"https://api.github.com/users/sgrif/repos","events_url":"https://api.github.com/users/sgrif/events{/privacy}","received_events_url":"https://api.github.com/users/sgrif/received_events","type":"User","site_admin":false},"created_at":"2015-02-27T22:07:37Z","updated_at":"2015-02-27T22:07:37Z","body":"I think it should be:\r\n\r\n```\r\nadd_index :users, :name, using: \"gist (name gist_trgm_ops)\"\r\n```\r\n\r\nSimply so we can continue to have the column name for index naming purposes.."}}