-
Notifications
You must be signed in to change notification settings - Fork 11.2k
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: "too many terms in compound SELECT" when inserting lots of records at once #25262
Comments
What query are you executing? |
Just a regular batch insert of ~700 entries. The exact context can be seen here: dos1/movim@306de37 - where Keep in mind that the only way to do batch inserts in SQLite is to do it via compound SELECT, so the error message makes sense. There is an alternative syntax available, but it's just a syntax sugar. (btw. it's not my code, I know about it [or Laravel] only as much as I debugged, which led me to filling this bug) |
We could fix it by using the standard syntax: Ideally, we would detect the SQLite version and use the legacy syntax if required. But the problem is that we don't have access to the database version inside the grammar. Replacing the old syntax completly would be a breaking change. And you can bet that some hosting services still use ancient SQLite versions... This is another use case for version-specific grammars (laravel/ideas#870). |
@staudenmeir That syntax you mention is implemented in SQLite as just a syntax sugar and falls under the same limit as the old one. |
The syntax works for me. Do you get an error? |
Oh, looks like it was fixed in 3.8.8. So that would be the version you would want to check against.
|
@laurencei Any info on why has it been closed? I just looked at the SQLiteGrammar.php file on master branch and I don't see any relevant update there. |
You said it was fixed in 3.8.8? So they just need to update SQLite? |
@laurencei Oh, no, it was a reply to the previous comment referring to the alternative syntax to the one used now by Laravel (before 3.8.8 it was just a syntax sugar, so changing it in Laravel won't fix the issue for the older ones). So, if Laravel is fine with requiring 3.8.8+, the syntax can simply be changed, otherwise it should do a version check and construct multiple INSERT queries on older ones (or just ignore that and leave this bug for the users of older SQLite versions). To sum up, this is a Laravel bug that happens on the newest SQLite. Any specific SQLite versions were only mentioned when discussing a way to fix it. |
(if you're fine with requiring SQLite 3.8.8 [or 3.7.11 if you don't mind this bug still happening for some people], I should even manage to make a PR with the fix :P) |
...it kind of feels like a real edge case, that if someone runs into it - the easiest/obvious solution is to update to SQLite 3.8.8? Changing the SQL statement just to handle this single case might have a performance impact for other users not affected by it? |
Uhm, no, please read the whole discussion again. This happens for every SQLite version right now, it's just a fix proposed in #25262 (comment) that will require SQLite 3.8.8 to actually fix anything. |
Ok... now I see. Well - seems like the best option is submit a PR for this and see what Taylor thinks. |
This bumps the version of SQLite dependency to 3.7.11, released March 2012. Using a default syntax for the INSERT INTO clause fixes an issue described in the bug laravel#25262, but only when used with SQLite 3.8.8 (released January 2015) or newer. Closes laravel#25262
Submitted :) |
This bumps the version of SQLite dependency to 3.7.11, released March 2012. Using a default syntax for the INSERT INTO clause fixes an issue described in the bug laravel#25262, but only when used with SQLite 3.8.8 (released January 2015) or newer. The DEFAULT VALUES case needs to be still handled though, just like in the PostgresGrammar. Closes laravel#25262
This bumps the version of SQLite dependency to 3.7.11, released March 2012. Using a default syntax for the INSERT INTO clause fixes an issue described in the bug #25262, but only when used with SQLite 3.8.8 (released January 2015) or newer. The DEFAULT VALUES case needs to be still handled though, just like in the PostgresGrammar. Closes #25262
Please close the issue. |
SQLite has a hard limit of 500 terms in a compound SELECT (see: https://stackoverflow.com/a/9527898). The limit can be configured by the user to be lower, but not greater.
Laravel doesn't take that into account, resulting in an "too many terms in compound SELECT" error when trying to insert more than 500 entries at once.
framework/src/Illuminate/Database/Query/Grammars/SQLiteGrammar.php
Lines 146 to 187 in fe68aa9
A possible solution would be to split up big datasets into multiple queries (at most
SQLITE_MAX_COMPOUND_SELECT
) in SQLiteGrammar's compileInsert function. Another one would be to simply wrap many inserts into a single transaction regardless of the dataset size, which should perform similarly performance-wise.The current limit on the database can be checked with
sqlite3_limit(db, SQLITE_MAX_COMPOUND_SELECT, -1)
function, as described in https://www.sqlite.org/c3ref/limit.htmlThe text was updated successfully, but these errors were encountered: