Bug #46680 Assertion failed in file item_subselect.cc, line 305 crashing on HAVING subquery
Submitted: 12 Aug 2009 20:21 Modified: 22 Nov 2010 1:22
Reporter: Patrick Crews Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Optimizer Severity:S3 (Non-critical)
Version:5.4/6.0 OS:Any
Assigned to: Jørgen Løland CPU Architecture:Any
Tags: crashing bug, having, materialization, optimizer_switch, subquery

[12 Aug 2009 20:21] Patrick Crews
Description:
A simple query that has a subquery in the HAVING clause is causing the following crash:
Assertion failed: (exec_method != MATERIALIZATION || (exec_method == MATERIALIZATION && engine->engine_type() == subselect_engine::HASH_SJ_ENGINE)), function exec, file item_subselect.cc, line 305.

This only occurs when materialization is on.

The query:
SELECT  MIN( table2 .`pk`  )  
FROM C table2  JOIN D table3  ON table2 .`varchar_key`  
WHERE table3 .`int_key`  AND 'j' 
HAVING ( 'r' , 'o' )  IN (  
SELECT `varchar_nokey`  , `varchar_key`  
FROM C  )   ;

partial  backtrace (full crash output attached as separate file):
# 14:12:04 #0  0x90f03402 in __assert_rtn ()
# 14:12:04 
# 14:12:04 Thread 11 (core thread 10):
# 14:12:04 #0  0x90efe136 in clock_get_attributes ()
# 14:12:04 #1  0x90ef7013 in usleep$NOCANCEL$UNIX2003 ()
# 14:12:04 #2  0x90f0e685 in abort ()
# 14:12:04 #3  0x90f033db in __assert_rtn ()
# 14:12:04 #4  0x000aba0a in Item_in_subselect::exec (this=0x132a430) at item_subselect.cc:303
# 14:12:04 #5  0x000a8aa4 in Item_in_subselect::val_bool (this=0x132a430) at item_subselect.cc:925
# 14:12:04 #6  0x00071d18 in Item::val_bool_result (this=0x132a430) at item.h:750
# 14:12:04 #7  0x0006542b in Item_in_optimizer::val_int (this=0x132b448) at item_cmpfunc.cc:1612
# 14:12:04 #8  0x001b8cf5 in return_zero_rows (join=0x19fa028, result=0x132a540, tables=0x124cdc0, fields=@0x124aaa8, send_row=true, select_options=2147764736, info=0x6a14a0 "no matching row in const table", having=0x132b448) at sql_select.cc:10895
# 14:12:04 #9  0x001b944b in JOIN::exec (this=0x19fa028) at sql_select.cc:2404
# 14:12:04 #10 0x001bb573 in mysql_select (thd=0x1249818, rref_pointer_array=0x124ab18, tables=0x124cdc0, wild_num=0, fields=@0x124aaa8, conds=0x1328108, og_num=0, order=0x0, group=0x0, having=0x132a430, proc_param=0x0, select_options=2147764736, result=0x132a540, unit=0x124a778, select_lex=0x124aa14) at sql_select.cc:3091
# 14:12:04 #11 0x001bb8c5 in handle_select (thd=0x1249818, lex=0x124a71c, result=0x132a540, setup_tables_done_option=0) at sql_select.cc:306
# 14:12:04 #12 0x0010f608 in execute_sqlcom_select (thd=0x1249818, all_tables=0x124cdc0) at sql_parse.cc:4927
# 14:12:04 #13 0x00115aba in mysql_execute_command (thd=0x1249818) at sql_parse.cc:2112
# 14:12:04 #14 0x0011f603 in mysql_parse (thd=0x1249818, inBuf=0x124b828 "SELECT   MIN( table2 . `int_key` ) AS field1 , MIN( table2 . `pk` ) AS field2 , CONCAT ( table2 . `varchar_key` , table2 . `varchar_nokey` ) AS field3 , ( ( table2 . `pk` ) - ( table2 . `int_key` ) ) "..., length=969, found_semicolon=0xb0512e14) at sql_parse.cc:5942
# 14:12:04 #15 0x00120180 in dispatch_command (command=COM_QUERY, thd=0x1249818, packet=0x19f0019 " SELECT   MIN( table2 . `int_key` ) AS field1 , MIN( table2 . `pk` ) AS field2 , CONCAT ( table2 . `varchar_key` , table2 . `varchar_nokey` ) AS field3 , ( ( table2 . `pk` ) - ( table2 . `int_key` ) )"..., packet_length=971) at sql_parse.cc:1062
# 14:12:04 #16 0x00121588 in do_command (thd=0x1249818) at sql_parse.cc:744
# 14:12:04 #17 0x0010cf33 in handle_one_connection (arg=0x1249818) at sql_connect.cc:1163
# 14:12:04 #18 0x90e53155 in _pthread_start ()
# 14:12:04 #19 0x90e53012 in thread_start ()

How to repeat:
Run the attached test case - this is the simplified query.  Will attach the full rqg-generated test case that contains the original and simplified queries.

Toggle the optimizer_switch value for materialization on and off and observe that the crash will disappear:

/*!50400 SET SESSION optimizer_switch = 'firstmatch=on,index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,loosescan=on,materialization=on,semijoin=on' */;
/*!50400 SET SESSION optimizer_use_mrr = 'disable' */;
/*!50400 SET SESSION engine_condition_pushdown = 0 */;
/*!50400 SET SESSION join_cache_level = 1 */;

#/* Begin test case for query 0 */

--disable_warnings
DROP TABLE /*! IF EXISTS */ D;
DROP TABLE /*! IF EXISTS */ C;
--enable_warnings

CREATE TABLE `D` (
  `pk` int(11) NOT NULL AUTO_INCREMENT,
  `int_key` int(11) DEFAULT NULL,
  `varchar_key` varchar(1) DEFAULT NULL,
  `varchar_nokey` varchar(1) DEFAULT NULL,
  PRIMARY KEY (`pk`),
  KEY `int_key` (`int_key`),
  KEY `varchar_key` (`varchar_key`,`int_key`)
) ENGINE=MyISAM AUTO_INCREMENT=101 DEFAULT CHARSET=latin1;
INSERT INTO `D` VALUES (1,0,'c','c'),(2,0,'o','o'),(3,7,'c','c'),(4,8,'d','d'),(5,4,'v','v'),(6,6,'m','m'),(7,5,'j','j'),(8,NULL,'f','f'),(9,NULL,'n','n'),(10,8,'z','z'),(11,8,'h','h'),(12,8,'q','q'),(13,1,'w','w'),(14,1,'z','z'),(15,5,'j','j'),(16,2,'a','a'),(17,7,'m','m'),(18,6,'n','n'),(19,4,'e','e'),(20,7,'u','u'),(21,0,'s','s'),(22,9,'u','u'),(23,3,'r','r'),(24,5,'g','g'),(25,1,'o','o'),(26,1,'w','w'),(27,5,'b','b'),(28,9,NULL,NULL),(29,2,'y','y'),(30,5,'y','y'),(31,248,'u','u'),(32,0,'p','p'),(33,8,'s','s'),(34,1,'e','e'),(35,255,'d','d'),(36,9,'d','d'),(37,9,'c','c'),(38,3,'b','b'),(39,9,'t','t'),(40,6,NULL,NULL),(41,4,'y','y'),(42,60,'c','c'),(43,7,'d','d'),(44,1,'x','x'),(45,6,'p','p'),(46,4,'e','e'),(47,NULL,'g','g'),(48,8,'x','x'),(49,0,'s','s'),(50,8,'e','e'),(51,151,'l','l'),(52,7,'p','p'),(53,6,'h','h'),(54,NULL,'m','m'),(55,23,'n','n'),(56,2,'v','v'),(57,4,'b','b'),(58,NULL,'x','x'),(59,NULL,'r','r'),(60,77,'t','t'),(61,NULL,'w','w'),(62,NULL,'w','w'),(63,7,'k','k'),(64,1,'a','a'),(65,9,'t','t'),(66,6,'z','z'),(67,2,'e','e'),(68,3,'q','q'),(69,0,'e','e'),(70,NULL,'v','v'),(71,6,'d','d'),(72,3,'u','u'),(73,195,'o','o'),(74,5,'b','b'),(75,2,'c','c'),(76,7,'q','q'),(77,25,NULL,NULL),(78,NULL,'h','h'),(79,0,'d','d'),(80,98,'w','w'),(81,6,'m','m'),(82,5,'i','i'),(83,0,'w','w'),(84,3,'f','f'),(85,1,'k','k'),(86,1,'v','v'),(87,147,'c','c'),(88,3,'y','y'),(89,3,'h','h'),(90,NULL,NULL,NULL),(91,2,'t','t'),(92,1,'l','l'),(93,8,'a','a'),(94,8,'r','r'),(95,8,'s','s'),(96,0,'z','z'),(97,1,'j','j'),(98,8,'c','c'),(99,5,'f','f'),(100,4,'g','g');
CREATE TABLE `C` (
  `pk` int(11) NOT NULL AUTO_INCREMENT,
  `int_key` int(11) DEFAULT NULL,
  `varchar_key` varchar(1) DEFAULT NULL,
  `varchar_nokey` varchar(1) DEFAULT NULL,
  PRIMARY KEY (`pk`),
  KEY `int_key` (`int_key`),
  KEY `varchar_key` (`varchar_key`,`int_key`)
) ENGINE=MyISAM AUTO_INCREMENT=21 DEFAULT CHARSET=latin1;
INSERT INTO `C` VALUES (1,9,'m','m'),(2,3,'m','m'),(3,9,'k','k'),(4,NULL,'r','r'),(5,9,'t','t'),(6,3,'j','j'),(7,8,'u','u'),(8,8,'h','h'),(9,53,'o','o'),(10,0,NULL,NULL),(11,5,'k','k'),(12,166,'e','e'),(13,3,'n','n'),(14,0,'t','t'),(15,1,'c','c'),(16,9,'m','m'),(17,5,'y','y'),(18,6,'f','f'),(19,2,'d','d'),(20,NULL,'r','r');

 
SELECT  MIN( table2 .`pk`  )  
FROM C table2  JOIN D table3  ON table2 .`varchar_key`  
WHERE table3 .`int_key`  AND 'j' 
HAVING ( 'r' , 'o' )  IN (  
SELECT `varchar_nokey`  , `varchar_key`  
FROM C  )   ;

DROP TABLE D;
DROP TABLE C;
#/* End of test case for query 0 */

Suggested fix:
Ensure correct query processing regardless of optimizer settings.
[12 Aug 2009 20:22] Patrick Crews
backtrace information for the bug (produced by rqg)

Attachment: bug46680_backtrace.txt (text/plain), 15.53 KiB.

[12 Aug 2009 20:22] Patrick Crews
full MTR test case with original and simplified queries

Attachment: bug46680_test.txt (text/plain), 7.75 KiB.

[29 Sep 2009 9:19] Jørgen Løland
The following is a simplified test that also reproduces the problem:

CREATE TABLE t1 (
  pk int(11) NOT NULL AUTO_INCREMENT,
  varchar_nokey varchar(1) DEFAULT NULL,
  PRIMARY KEY (pk)
) ENGINE=MyISAM AUTO_INCREMENT=101 DEFAULT CHARSET=latin1;

INSERT INTO t1 VALUES (1,'c'), (2, NULL);

CREATE TABLE t2 (
  pk int(11) NOT NULL AUTO_INCREMENT,
  varchar_nokey varchar(1) DEFAULT NULL,
  PRIMARY KEY (pk)
) ENGINE=MyISAM AUTO_INCREMENT=21 DEFAULT CHARSET=latin1;

INSERT INTO t2 VALUES 
(3,'m'),(4,NULL);

SELECT MIN(t2.pk)
FROM t2 JOIN t1 ON t1.pk=t2.pk
WHERE 'j'
HAVING ('m') IN ( 
SELECT varchar_nokey
FROM t2);
[29 Sep 2009 9:27] Jørgen Løland
The following properties hold for queries that fail like this bug:

 - Has one or more aggregate functions in the SELECT list
 - Has an impossible WHERE condition
 - Does not have GROUP BY clause
 - Has a subquery in the HAVING clause
[29 Sep 2009 9:32] Jørgen Løland
The result when running the simplified query above on MySQL 5.1:

mysql> SELECT MIN(t2.pk) 
>      FROM t2 JOIN t1 ON t1.pk=t2.pk 
>      WHERE 'j' HAVING ('m') IN (
>         SELECT varchar_nokey
>         FROM t2
>      );
MIN(t2.pk)
NULL
Warnings:
Warning 1292    Truncated incorrect INTEGER value: 'j'
[29 Sep 2009 11:27] Jørgen Løland
The problem occurs when the optimizer finds an impossible WHERE
clause (sets zero_result_cause @ sql_select.cc:1508) which in
turn shortcuts JOIN::optimize halfway through execution by
calling return_zero_rows() around line 2400. 

The call to return_zero_rows() happens before the subqueries have
been setup properly (for non-shortcuted queries, this happens in
the call to setup_subquery_materialization() @
sql_select.cc:1930 (still inside JOIN::optimize function)). In
return_zero_rows(), this line:

10908   if (having && having->val_int() == 0)

triggers the execution of the subselect. Since the subselect has
not been initialized, the assertion fails.

Suggested fix: call setup_subquery_materialization() before
calling having->val_int() on line 10908.

I consider these locations to be good candidates for setting up
the subquery:

1) Before calling return_zero_rows()

@@ -2392,6 +2392,7 @@ JOIN::exec()
 
   if (zero_result_cause)
   {
+    setup_subquery_materialization();
     (void) return_zero_rows(this, result, select_lex->leaf_tables,
                             *columns_list,
 			    send_row_on_empty_set(),

2) Right before calling having->val_int()

@@ -10905,8 +10906,12 @@ return_zero_rows(JOIN *join, select_resu
   {
     for (TABLE_LIST *table= tables; table; table= table->next_leaf)
       mark_as_null_row(table->table);		// All fields are NULL
-    if (having && having->val_int() == 0)
-      send_row=0;
+    if (having) 
+    {
+      setup_subquery_materialization();
+      if (having->val_int() == 0)
+	send_row=0;
+    }
[29 Sep 2009 11:31] Jørgen Løland
There is a typo in alternative 2) above; it should be:

join->setup_subquery_materialization();
[30 Sep 2009 8:11] Jørgen Løland
The above comment should be 

"The problem occurs when the optimizer finds an impossible WHERE clause (sets zero_result_cause @ sql_select.cc:1508) which in turn shortcuts JOIN::optimize halfway through execution." 

return_zero_rows() is later called from JOIN::exec(), not JOIN::optimize()

The same argument applies, though: JOIN::optimize didn't setup the subselects properly because setup_subquery_materialization() was not called. This should be fixed in JOIN::optimize(), not in exec(). Hence, this seems to be the preferred location to setup the subqueries and thereby fix the bug:

3)
+++ sql/sql_select.cc	2009-09-30 07:45:49 +0000
@@ -1509,6 +1509,7 @@ JOIN::optimize()
                            "Impossible HAVING" : "Impossible WHERE";
       tables= 0;
       error= 0;
+      setup_subquery_materialization();
       DBUG_RETURN(0);
     }
   }

I.e., right before JOIN::optimize shourtcuts optimization because it found an impossible WHERE.
[30 Sep 2009 11:06] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/85188

3631 Jorgen Loland	2009-09-30
      Bug#46680 - Assertion failed in file item_subselect.cc, 
                  line 305 crashing on HAVING subquery
      
      For queries with impossible WHERE clauses, the optimizer 
      shortcuts when it becomes clear that there are zero rows 
      that match the impossible WHERE. In this case, subselects 
      for which the optimizer has decided to use materialization 
      strategy are not setup properly.
      
      However, if the query also has one or more aggregate functions, 
      no GROUP BY clause and a subselect in the HAVING clause, the
      HAVING subselect has to be evaluated to decide if the query 
      should return zero rows (HAVING evaluates to false) or one 
      row with aggregates computed from NULL values. When the subquery 
      is evaluated, an ASSERT fails because exec() is called before
      the query has been properly initialized.
      
      This patch calls setup_subquery_materialization() in 
      JOIN:optimize() if the optimizer finds that WHERE contains an
      impossible condition.
     @ mysql-test/r/func_group.result
        Added regression test for BUG#46680
     @ mysql-test/t/func_group.test
        Added regression test for BUG#46680
     @ sql/sql_select.cc
        Call setup_subquery_materialization() in JOIN:optimize() if the optimizer finds that WHERE contains an impossible condition.
[8 Oct 2009 11:47] Jørgen Løland
Guilhem points out that there are other premature exits from JOIN::optimize() that happen before setup_subquery_materialization() is called around line 1931. These exits should be analyzed to see if subquery setup is also required here.

The locations are:

[1] @1503:
   zero_result_cause=  having_value == Item::COND_FALSE ?
                        "Impossible HAVING" : "Impossible WHERE";
   tables= 0;
   error= 0;
   DBUG_RETURN(0);

[2] @1550:
   DBUG_PRINT("info",("No matching min/max row"));
   zero_result_cause= "No matching min/max row";
   tables= 0;
   error=0;
   DBUG_RETURN(0);

[3] @1564:
   DBUG_PRINT("info",("No matching min/max row"));
   zero_result_cause= "No matching min/max row";
   tables= 0;
   error=0;
   DBUG_RETURN(0);

[4] @1600
  if (!tables_list)
  {
    DBUG_PRINT("info",("No tables"));
    error= 0;
    DBUG_RETURN(0);
  }

[5] @1630
   zero_result_cause= "no matching row in const table";
   DBUG_PRINT("error",("Error: %s", zero_result_cause));
   error= 0;
   DBUG_RETURN(0);

[6]
   zero_result_cause=
     "Impossible WHERE noticed after reading const tables";
   DBUG_RETURN(0);				// error == 0

In addition, this premature exit sets up subquery correctly: 
[7] @1571
   zero_result_cause= "Select tables optimized away";
   tables_list= 0;				// All tables resolved
   if (conds && !(thd->lex->describe & DESCRIBE_EXTENDED))
   {
     COND *table_independent_conds=
       make_cond_for_table(conds, PSEUDO_TABLE_BITS, 0, 0);
     DBUG_EXECUTE("where",
                  print_where(table_independent_conds,
                              "where after opt_sum_query()",
                              QT_ORDINARY););
     conds= table_independent_conds;
   }
   /* Create all structures needed for materialized subquery execution. */
   if (setup_subquery_materialization())
     DBUG_RETURN(1);
   // (...)
   // then into this if due to tables_list=0 above
   if (!tables_list)
   {
     DBUG_PRINT("info",("No tables"));
     error= 0;
     DBUG_RETURN(0);
   }
[8 Oct 2009 12:33] Jørgen Løland
I have found test cases that confirm that the ASSERT fires for cases [1], [2], [5], [6], [7] (if if setup_subquery_materialization() is commented out) above.

I cannot figure a way to enter [3]; I cannot see how opt_sum_query() can possibly return a negative value. However, since the return value is in some cases set to the return value from function calls (which return values from sub-function calls etc), I cannot say 100% sure that it cannot happen. 

As far as I can tell, [4] does not need to setup subqueries since it is only entered if there are no tables left to handle. Code inspection indicates that this is only true if a) there were no tables in the first place and hence no subquery to materialize, or b) the tables were optimized away. However, whenever tables_list is set to 0, the optimizer exits immediately and therefore never gets here (when considering the changes to [7] in the patch below).
[8 Oct 2009 14:26] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/86199

3649 Jorgen Loland	2009-10-08
      Bug#46680 - Assertion failed in file item_subselect.cc, 
                  line 305 crashing on HAVING subquery
            
      The optimizer exits prematurely in some cases when it becomes 
      clear that zero rows will satisfy the query. In these cases, 
      subselects for which the optimizer has decided to use 
      materialization strategy were not setup properly.
            
      However, if these query also had one or more aggregate functions, 
      no GROUP BY clause and a subselect in the HAVING clause, the
      HAVING subselect had to be evaluated to decide if the query 
      should return zero rows (HAVING evaluated to false) or one 
      row with aggregates computed from NULL values. When the subquery 
      was evaluated, an ASSERT failed because exec() was called before
      the subquery had been properly initialized.
     @ mysql-test/r/func_group.result
        Added regression test for BUG#46680
     @ mysql-test/t/func_group.test
        Added regression test for BUG#46680
     @ sql/sql_select.cc
        Call setup_subquery_materialization() in JOIN:optimize() if the optimizer decides to exit prematurely.
[9 Oct 2009 14:34] Guilhem Bichot
approved with minor comments sent by mail
[13 Oct 2009 7:14] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/86645

3650 Jorgen Loland	2009-10-13
      Bug#46680 - Assertion failed in file item_subselect.cc, 
                  line 305 crashing on HAVING subquery
                  
      The optimizer exits prematurely in some cases when it becomes 
      clear that zero rows will satisfy the query. In these cases, 
      subselects for which the optimizer has decided to use 
      materialization strategy were not setup properly.
                  
      However, if these query also had one or more aggregate functions, 
      no GROUP BY clause and a subselect in the HAVING clause, the
      HAVING subselect had to be evaluated to decide if the query 
      should return zero rows (HAVING evaluated to false) or one 
      row with aggregates computed from NULL values. When the subquery 
      was evaluated, an ASSERT failed because exec() was called before
      the subquery had been properly initialized.
     @ mysql-test/r/func_group.result
        Added regression test for BUG#46680
     @ mysql-test/t/func_group.test
        Added regression test for BUG#46680
     @ sql/sql_select.cc
        Call setup_subquery_materialization() in JOIN:optimize() if the optimizer decides to exit prematurely.
[13 Oct 2009 10:57] Jørgen Løland
Pushed to mysql-6.0-codebase-bugfixing
[31 Oct 2009 8:20] Bugs System
Pushed into 6.0.14-alpha (revid:alik@sun.com-20091031081410-qkxmjsdzjmj840aq) (version source revid:jorgen.loland@sun.com-20091013071623-dzu8vx13reye5ebj) (merge vers: 6.0.14-alpha) (pib:13)
[17 Nov 2009 23:09] Paul DuBois
Noted in 6.0.14 changelog.

The optimizer exited prematurely in some cases when it became clear
that zero rows would satisfy the query. In these cases, subqueries
for which the optimizer had decided to use a materialization strategy
were not set up properly.
[6 Apr 2010 12:58] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/105077

3061 oystein.grovlen@sun.com	2010-04-06
      Bug#46680 - Assertion failed in file item_subselect.cc, 
                  line 305 crashing on HAVING subquery
      
      (Backporting of revid:jorgen.loland@sun.com-20091013071623-dzu8vx13reye5ebj)
      
      The optimizer exits prematurely in some cases when it becomes 
      clear that zero rows will satisfy the query. In these cases, 
      subselects for which the optimizer has decided to use 
      materialization strategy were not setup properly.
                  
      However, if these query also had one or more aggregate functions, 
      no GROUP BY clause and a subselect in the HAVING clause, the
      HAVING subselect had to be evaluated to decide if the query 
      should return zero rows (HAVING evaluated to false) or one 
      row with aggregates computed from NULL values. When the subquery 
      was evaluated, an ASSERT failed because exec() was called before
      the subquery had been properly initialized.
     @ mysql-test/r/func_group.result
        Added regression test for BUG#46680
     @ mysql-test/t/func_group.test
        Added regression test for BUG#46680
     @ sql/sql_select.cc
        Call setup_subquery_materialization() in JOIN:optimize() if the optimizer decides to exit prematurely.
[16 Aug 2010 6:40] Bugs System
Pushed into mysql-next-mr (revid:alik@sun.com-20100816062819-bluwgdq8q4xysmlg) (version source revid:alik@sun.com-20100816062612-enatdwnv809iw3s9) (pib:20)
[13 Nov 2010 16:20] Bugs System
Pushed into mysql-trunk 5.6.99-m5 (revid:alexander.nozdrin@oracle.com-20101113155825-czmva9kg4n31anmu) (version source revid:vasil.dimov@oracle.com-20100629074804-359l9m9gniauxr94) (merge vers: 5.6.99-m4) (pib:21)
[22 Nov 2010 1:22] Paul DuBois
Bug is not in any released 5.6.x version. No changelog entry needed.