Skip to content

Remove explicit cast from index condition

What does this MR do and why?

Remove the explicit cast to timestamp with time zone when comparing a static value against the events.created_at column in an index definition.

If an installation has this column wrongly defined as timestamp without time zone, comparing it with a timestamp with time zone will cause index creation to fail with PG::InvalidObjectDefinition: ERROR: functions in index predicate must be marked IMMUTABLE

By removing the explicit cast, postgres seems to automatically cast the timestamp string to the correct type to match the column.

We came across this in #345416, and it could be a good idea to fix this more broadly, since older self-managed installations may have the same schema differences. We also ran into a similar, but somewhat different issue with this before in !68784 (merged)

How to set up and validate locally

  1. Re-run the migration with the cast removed:
    rails db:migrate:redo VERSION=20211103162025
  2. Verify the index exists and is correct:
     \d+ index_events_on_created_at_and_id
                      Index "public.index_events_on_created_at_and_id"
       Column   |           Type           | Key? | Definition | Storage | Stats target
    ------------+--------------------------+------+------------+---------+--------------
     created_at | timestamp with time zone | yes  | created_at | plain   |
     id         | bigint                   | yes  | id         | plain   |
    btree, for table "public.events", predicate (created_at > '2021-08-27 00:00:00+00'::timestamp with time zone)
  3. Change the column type to timestamp without time zone
    drop index index_events_on_created_at_and_id; -- first we have to drop the index
    alter table events alter column created_at type timestamp without time zone;
  4. Re-run the migration again as in step 1.
  5. Verify the index exists and is correct:
    \d+ index_events_on_created_at_and_id
                       Index "public.index_events_on_created_at_and_id"
       Column   |            Type             | Key? | Definition | Storage | Stats target
    ------------+-----------------------------+------+------------+---------+--------------
     created_at | timestamp without time zone | yes  | created_at | plain   |
     id         | bigint                      | yes  | id         | plain   |
    btree, for table "public.events", predicate (created_at > '2021-08-27 00:00:00'::timestamp without time zone)

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Patrick Bair

Merge request reports

Loading