Bug #259 DELETE with. ORDER BY and LIMIT crash
Submitted: 9 Apr 2003 5:31 Modified: 9 Apr 2003 8:18
Reporter: Alexander Keremidarski Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server Severity:S2 (Serious)
Version:4.1 OS:Any
Assigned to: CPU Architecture:Any

[9 Apr 2003 5:31] Alexander Keremidarski
Description:
When DELETE specifies both ORDER BY <anything> and LIMIT <any number> 

MySQL 4.1 crashes at:

sql_select.cc:7160

static int
find_order_in_list(THD *thd, Item **ref_pointer_array,
    		   TABLE_LIST *tables,ORDER *order, List<Item> &fields,
    		   List<Item> &all_fields)
...

  uint el= all_fields.elements;
  all_fields.push_front(it);		        // Add new field to field list
  ref_pointer_array[el]= it;
  ^^^^^^^^^^^^^^^^^^^^^^^^^

  order->item= ref_pointer_array + el;
  return 0;
}

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1105262656 (LWP 22157)]
0x0817efc4 in find_order_in_list (thd=0x8b18310, ref_pointer_array=0x0, tables=0x0, order=0x8b21110, fields=@0x41e0ee8c, all_fields=@0x41e0ee8c) at sql_select.cc:7160

(gdb) bt
#0  0x0817efc4 in find_order_in_list (thd=0x8b18310, ref_pointer_array=0x0, tables=0x0, order=0x8b21110, fields=@0x41e0ee8c, all_fields=@0x41e0ee8c) at sql_select.cc:7160
#1  0x0817f06d in setup_order(THD*, Item**, st_table_list*, List<Item>&, List<Item>&, st_order*) (thd=0x41e0ee8c, ref_pointer_array=0x0, tables=0x41e0eeac, fields=@0x41e0ee9c, all_fields=@0x8b21110, order=0x8b210c0) at sql_select.cc:7189
#2  0x0818f457 in mysql_delete(THD*, st_table_list*, Item*, st_order*, unsigned long long, unsigned long) (thd=0x8b18310, table_list=0x8b21060, conds=0x0, order=0x8b21110, limit=1, options=0) at sql_delete.cc:129
#3  0x0814f4f0 in mysql_execute_command(THD*) (thd=0x8b18310) at sql_parse.cc:2369
#4  0x08152049 in mysql_parse(THD*, char*, unsigned) (thd=0x8b18310, inBuf=0x8b21000 "delete from test order by id limit 1", length=145851464) at sql_parse.cc:3375
#5  0x0814c1fd in dispatch_command(enum_server_command, THD*, char*, unsigned) (command=COM_QUERY, thd=0x8b18310, packet=0x8b1cfc9 "delete from test order by id limit 1", packet_length=37) at sql_parse.cc:1249
#6  0x0814ba7a in do_command(THD*) (thd=0x8b18310) at sql_parse.cc:1049
#7  0x0814afa2 in handle_one_connection (arg=0x0) at sql_parse.cc:838
#8  0x400422b6 in start_thread () from /lib/tls/libpthread.so.0

How to repeat:
CREATE TABLE `test` (
  `id` int(11) default NULL
)

INSERT INTO test VALUES(1), (2);

DELETE FROM test ORDER BY RAND() LIMIT 1;
[9 Apr 2003 8:18] MySQL Verification Team
Thank you for your bug report, which helped us fix a crashing bug. 

This is a patch:
===== sql/sql_delete.cc 1.100 vs edited =====
*** /tmp/sql_delete.cc-1.100-13318      Thu Apr  3 13:47:38 2003
--- edited/sql/sql_delete.cc    Wed Apr  9 18:10:40 2003
***************
*** 126,137 ****
  
      table->io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
                                               MYF(MY_FAE | MY_ZEROFILL));
!     if (setup_order(thd, 0, &tables, fields, all_fields, order) ||
!         !(sortorder=make_unireg_sortorder(order, &length)) ||
!         (table->found_records = filesort(thd, table, sortorder, length,
!                                         (SQL_SELECT *) 0, HA_POS_ERROR,
!                                        &examined_rows))
!         == HA_POS_ERROR)
      {
        delete select;
        free_underlaid_joins(thd, &thd->lex.select_lex);
--- 126,140 ----
  
      table->io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
                                               MYF(MY_FAE | MY_ZEROFILL));
!       if (setup_ref_array(thd, &thd->lex.select_lex.ref_pointer_array,
!                       all_fields.elements)||
!         setup_order(thd, thd->lex.select_lex.ref_pointer_array, &tables, 
!                     fields, all_fields, order) ||
!         !(sortorder=make_unireg_sortorder(order, &length)) ||
!         (table->found_records = filesort(thd, table, sortorder, length,
!                                          (SQL_SELECT *) 0, HA_POS_ERROR,
!                                          &examined_rows))
!         == HA_POS_ERROR)
      {
        delete select;
        free_underlaid_joins(thd, &thd->lex.select_lex);