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
SQLite adapter allows indexes on non-existent columns #27782
Comments
From D. Richard Hipp, the creator of SQLite, in an email response on the mailing list to my inquiry:
So there you have it. I will work on this and issue a PR within the week. EDIT: I got some clarity about what's going on. Consider these three cases again: CREATE INDEX index_reports_on_yearz_doesnt_exist ON reports (yearz_doesnt_exist);
CREATE INDEX index_reports_on_yearz_doesnt_exist ON reports ('yearz_doesnt_exist');
CREATE INDEX index_reports_on_yearz_doesnt_exist ON reports ("yearz_doesnt_exist");
The point is that the proper solution here is to not use any quotes for column names when creating indexes in SQLite. Double quotes have unreliable behavior and single quotes' behavior is reliable but also probably a bug. |
@earksiinni Agree that we should change Rails to better suit SQLite. Please do send a PR! |
This issue has been automatically marked as stale because it has not been commented on for at least three months. |
Ref: rails/rails#45101 Ref: rails/rails#27782 Ref: https://www.sqlite.org/quirks.html#double_quoted_string_literals_are_accepted Sqlite has a really unfortunate behavior around double quotes. It first tries to consider them as column names, but if they don't exist it then consider them as string literals. Because of this, typos can silently go unnoticed. It would be very useful for Active Record if this behavior could be disabled.
Ref: rails/rails#45101 Ref: rails/rails#27782 Ref: https://www.sqlite.org/quirks.html#double_quoted_string_literals_are_accepted Sqlite has a really unfortunate behavior around double quotes. It first tries to consider them as column names, but if they don't exist it then consider them as string literals. Because of this, typos can silently go unnoticed. It would be very useful for Active Record if this behavior could be disabled.
Ref: rails/rails#45101 Ref: rails/rails#27782 Ref: https://www.sqlite.org/quirks.html#double_quoted_string_literals_are_accepted Sqlite has a really unfortunate behavior around double quotes. It first tries to consider them as column names, but if they don't exist it then consider them as string literals. Because of this, typos can silently go unnoticed. It would be very useful for Active Record if this behavior could be disabled.
Steps to reproduce
(Or place
add_index
within thecreate_table
block ast.add_index :yearz_doesnt_exist
.)Expected behavior
The migration should fail and a new index shouldn't be created.
Actual behavior
The migration succeeds and a new index is created. Moreover, if you log STDOUT, you'll see the SQL changes:
After some experimentation, I found the problematic line:
CREATE INDEX "index_reports_on_yearz_doesnt_exist" ON "reports" ("yearz_doesnt_exist")
The problem lies in the double quotes around the column name. For whatever reason, in SQLite, the following statements behave differently:The first two will fail but the last will succeed. I've written to the SQLite mailing list asking why this is, but until I receive a response, you may be interested to know the output of
index_list
andindex_info
:Note that the output from index_info indicates that our index is on column -2, which of course doesn't exist. Very weird.
This may well be a SQLite problem. On the other hand, using double quotes in SQL when it isn't necessary is usually frowned upon. Here's the relevant code from the abstract connector in Rails:
Note that the Postgres connector seems to do this a little differently:
What probably needs to be done is that SQLite-specific code for adding indexes needs to be written. I'm happy to take a crack at it and submit a PR.
System configuration
Rails version: 4.2.7
Ruby version: 2.3.3p222
SQLite version: 3.14.0
The text was updated successfully, but these errors were encountered: