[MDEV-10669] Crash in SELECT with window function used Created: 2016-08-26 Updated: 2016-10-27 Resolved: 2016-10-27 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Optimizer - Window functions |
| Affects Version/s: | 10.2.1, 10.2.2 |
| Fix Version/s: | 10.2.2 |
| Type: | Bug | Priority: | Critical |
| Reporter: | Valerii Kravchuk | Assignee: | Sergei Petrunia |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | None | ||
| Attachments: |
|
||||||||
| Issue Links: |
|
||||||||
| Description |
|
Simple window function used together with IFNULL in the SELECT ... list leads to repeatable crash:
|
| Comments |
| Comment by Valerii Kravchuk [ 2016-08-26 ] | ||||||||||||||||||||||||||||||||||||
|
IFNULL does not really matter it seems:
No crashing without OVER(PARTITION BY t.b): MariaDB [test]> SELECT (CASE WHEN sum(t.a) =0 then null else null end) as a from t;
------
------ | ||||||||||||||||||||||||||||||||||||
| Comment by Vicențiu Ciorbaru [ 2016-09-15 ] | ||||||||||||||||||||||||||||||||||||
|
The problem lies within the CASE WHEN expression.
When executing this query, we're creating a temporary table to store the window function results. The problem arises because our window function is hidden beneath an Item_func_case. When creating the temporary table fields, we only create one field, which represents the Item_func_case result value. Unfortunately, we do not create an extra field, specifically for the window function hidden inside. Looking at Item_func_case implementation and based on how window functions are supposed to be computed, the only practical approach to implementing this that I see is: 1. Create extra fields for each "inner" window function. This is the most straightforward and feels the most direct. The downside/tricky part is that we have to add another extra computation step, of resolving any items whose results are based on window function values. This however seems worth it as we could then allow for computing expressions with window functions. Note, the following does not work either:
A fix for this kind of problem would enable expressions such as those to also work. | ||||||||||||||||||||||||||||||||||||
| Comment by Igor Babaev [ 2016-09-15 ] | ||||||||||||||||||||||||||||||||||||
|
Vicentiu, | ||||||||||||||||||||||||||||||||||||
| Comment by Vicențiu Ciorbaru [ 2016-09-15 ] | ||||||||||||||||||||||||||||||||||||
|
Igor, that is indeed a good idea, it is actually what Sergey Petrunia also pointed at. Also, take a look at Here is however a peculiarity:
| ||||||||||||||||||||||||||||||||||||
| Comment by Vicențiu Ciorbaru [ 2016-09-15 ] | ||||||||||||||||||||||||||||||||||||
|
After discussion with Sergey Petrunia, the last query should be thought as function call with 3 expresssions: SELECT case(t.a=0, SUM(t.b), SUM(t.a)) With such a use case we should perform aggregation. Given MySQL extension that we allow aggregates and non-aggregates without group by, we return the value for a random row within the group. In this case, the group is the whole table and we return the value of the case function for either the first or the second row. The MariaDB knowledge base is lacking in this regard, will update it. | ||||||||||||||||||||||||||||||||||||
| Comment by Vicențiu Ciorbaru [ 2016-09-17 ] | ||||||||||||||||||||||||||||||||||||
|
Hi Sergey! Please review the additional patch that adds on top of Ex: ifnull(1+sum(a) over (), 0). This is the latest patch: | ||||||||||||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2016-09-17 ] | ||||||||||||||||||||||||||||||||||||
|
The patch works. Let's take this query as an example (It crashes before this patch, it works after):
The results of split_sum_func calls are as follows: | ||||||||||||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2016-10-27 ] | ||||||||||||||||||||||||||||||||||||
|
The fix was pushed into MariaDB 10.2.2. |