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
Postresql index with type casting using CAST AS is non-rollbackable #32621
Comments
Note: I'll make a reproducible test case with active_record_gem.rb asap. |
Reproduced case for 5.2: https://gist.github.com/abaldwin88/c24db432b7b351fafe56797b97ae6a54 Here's one against master: https://gist.github.com/abaldwin88/30be7716414315102a14d56bfb186721 I'm going to take a stab at opening a PR in the next couple days |
When creating an index in Postgres `CAST(created_at AS date)` is converted to `((created_at)::date)`. This difference causes the `index_name` method to return 'index_payments_on_CAST_created_at_AS_date' when the index is created with the CAST statement and 'index_payments_on_created_at_date' when the postgres shorthand syntax is passed in during removal. By adding an additional check against the index name we are able to handle this scenario appropriately. Fixes rails#32621
This issue has been automatically marked as stale because it has not been commented on for at least three months. |
For posterity -- The reproduction script is passing against version 7.0.5 (And may potentially succeed for versions after 5.2) |
Steps to reproduce
The requirement: adding typecasted index, namely created_at typecasted to DATE type because we're calculating daily statistics and therefore choosing rows with
WHERE payments.created_at::date='2018-03-01'
.Adding a migration with
add_index :payments, "CAST(created_at AS date)"
creates an index and the following entry in schema.rb:
t.index "((created_at)::date)", name: "index_payments_on_CAST_created_at_AS_date"
So the migration engine was smart enough to shorthand
CAST AS
syntax into::
syntax, BUT puts the wrong name of newly created index into schema.rb. The actual name of index in the database is also generated based on shorthand form (which is nice and consistent), it'sindex_payments_on_created_at_date
in this case.Unfortunately the naming inconsistency causes the migration to be non-rollbackable, because
Or to put it shortly, the index with given name does not exist.
WORKAROUND: use shorthand form in migration, in this case
add_index :payments, "((created_at)::date)"
which creates a proper entry in schema.rb:
t.index "((created_at)::date)", name: "index_payments_on_created_at_date"
and rolls back like a charm.
Expected behavior
CAST AS
form should generate rollback-able migrations.System configuration
Rails version: 5.1.5
Ruby version: 2.5.0
The text was updated successfully, but these errors were encountered: