Changes between Initial Version and Version 1 of Ticket #25517
- Timestamp:
- Oct 6, 2015, 12:41:59 PM (9 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
Ticket #25517 – Description
initial v1 1 When running on sqlite, with a {{{Concat()}}} expression used in the query, the {{{ConcatPair.coalesce()}}}method is called every time the SQL is generated. This is normal, expected, and AFAIK, correct behavior.1 When running on sqlite, with a `Concat()` expression used in the query, the `ConcatPair.coalesce()` method is called every time the SQL is generated. This is normal, expected, and AFAIK, correct behavior. 2 2 3 The problem is that {{{ConcatPair.coalesce()}}} is NOT idempotent. So, EVERYtime the SQL is generated, each expression within the {{{ConcatPair}}} instance is wrapped with an additional `COALESCE()` SQL function. If generated enough times, the SQL can reach a point where it will crash the sqlite query parser.3 The problem is that `ConcatPair.coalesce()` is not idempotent. So, **//every//** time the SQL is generated, each expression within the {{{ConcatPair}}} instance is wrapped with an additional `COALESCE()` SQL function. If generated enough times, the SQL can reach a point where it will crash the sqlite query parser. 4 4 5 5 This problem may not manifest itself in a typical request/response context, as the SQL with the additional `COALESCE()` calls will work identically to the original and the SQL may not be re-generated a sufficient number of times to crash the parser. 6 6 7 However, in a long-running process (where this bug was found), it can be easily triggered. For example, say I have a "base" queryset with a {{{Concat()}}} within an {{{.annotate()}}}. I never actually evaluate this queryset, but I use it to construct other querysets which I do evaluate. Because all of these querysets share the same instance of Query._annotations, evaluating ANY of these querysets will add an additional level of COALESCE()to the SQL generated by the others.7 However, in a long-running process (where this bug was found), it can be easily triggered. For example, say I have a "base" queryset with a `Concat()` within an `.annotate()`. I never actually evaluate this queryset, but I use it to construct other querysets which I do evaluate. Because all of these querysets share the same instance of Query._annotations, evaluating ANY of these querysets will add an additional level of `COALESCE()` to the SQL generated by the others. 8 8 9 9 I have a fix coded. I will submit a PR shortly.