-
Notifications
You must be signed in to change notification settings - Fork 21.3k
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
Don't check type
on add_column
via column_exists?`
#42212
Don't check type
on add_column
via column_exists?`
#42212
Conversation
Welp that didn't work for postgres - looking into that. |
I originally added the `type` to the `column_exists?` check in `add_column` because I thought it would be useful to still raise if you tried to add a column with a different type. It seemed bad to silently ignore. The `type` check works fine for standard, non-type casted types like `string`, but migrations that use types like `blob` in mysql/sqlite3 or `char` in postgres cast these to other types. When `c.type == type.to_sym` is called in those cases they won't match. For example `c.type` for a `blob` column will return `binary` so the comparison won't match. I attempted to cast the `type` passed in but that's error prone because for dbs like postgres we need _a lot_ more information than just a type to determine how to cast it. I also tried going the other way but the column doesn't store the original type, just the type casted type (as type) and the sql type which is a string representation of type that doesn't always match the original. This functionality was originally extracted from GitHub and when I looked back at our old implementation I found that we originally weren't passing type. This came up in a migration for enterprise that wasn't properly handling the `if_not_exists` because our `type` check was comparing `binary` to `mediumblob`. I think it makes the most sense to leave the public `column_exists?` method as is and remove the `type` check from `column_exists?` in the `add_column` method.
8e41573
to
627da23
Compare
type
on add_column
via column_exists?`
I reimplemented this differently than my original commit said. I dropped the casting altogether and am just checking for the same column name on the table. This has a slight behavior change in that we no longer will raise if you try to add the same column name with a different type, but I think that's rare. |
I agree with what you did. Also, I think it's consistent with the def remove_column(table_name, column_name, type = nil, **options)
return if options[:if_exists] == true && !column_exists?(table_name, column_name)
.
.
. Note: I don't like the naming of the option |
I followed existing options on create/drop table when I implemented this. It doesn't make sense to have different options. |
I originally added the
type
to thecolumn_exists?
check inadd_column
because I thought it would be useful to still raise if youtried to add a column with a different type. It seemed bad to silently
ignore.
The
type
check works fine for standard, non-type casted types likestring
, but migrations that use types likeblob
in mysql/sqlite3 orchar
in postgres cast these to other types. Whenc.type == type.to_sym
is called in those cases they won't match. For examplec.type
for ablob
column will returnbinary
so the comparisonwon't match. I attempted to cast the
type
passed in but that's errorprone because for dbs like postgres we need a lot more information
than just a type to determine how to cast it. I also tried going the
other way but the column doesn't store the original type, just the type
casted type (as type) and the sql type which is a string representation
of type that doesn't always match the original.
This functionality was originally extracted from GitHub and when I
looked back at our old implementation I found that we originally weren't
passing type. This came up in a migration for enterprise that wasn't
properly handling the
if_not_exists
because ourtype
check wascomparing
binary
tomediumblob
. I think it makes the most sense toleave the public
column_exists?
method as is and remove thetype
check from
column_exists?
in theadd_column
method.