Commit a1110e70 authored by unknown's avatar unknown
Browse files

better fix for bug#7242 (crash in prepared INSERT ... UPDATE)


sql/sql_insert.cc:
  cleanup
parent 05c65b91
Loading
Loading
Loading
Loading
+4 −5
Original line number Diff line number Diff line
@@ -427,6 +427,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
    thd			- thread handler
    table_list		- global table list
    insert_table_list	- local table list of INSERT SELECT_LEX
    values              - values to insert. NULL for INSERT ... SELECT

  RETURN VALUE
    0  - OK
@@ -454,10 +455,8 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
       (setup_fields(thd, 0, insert_table_list, update_fields, 1, 0, 0) ||
        setup_fields(thd, 0, insert_table_list, update_values, 1, 0, 0))))
    DBUG_RETURN(-1);
  if ((thd->lex->sql_command==SQLCOM_INSERT ||
       thd->lex->sql_command==SQLCOM_REPLACE) &&
      find_real_table_in_list(table_list->next, 
			      table_list->db, table_list->real_name))
  if (values && find_real_table_in_list(table_list->next, table_list->db,
                                        table_list->real_name))
  {
    my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name);
    DBUG_RETURN(-1);
+4 −26
Original line number Diff line number Diff line
@@ -908,6 +908,7 @@ static int mysql_test_insert(Prepared_statement *stmt,
    uint value_count;
    ulong counter= 0;

    table_list->table->insert_values=(byte *)1; // don't allocate insert_values
    if ((res= mysql_prepare_insert(thd, table_list, insert_table_list,
				   table_list->table, fields, values,
				   update_fields, update_values, duplic)))
@@ -934,6 +935,7 @@ static int mysql_test_insert(Prepared_statement *stmt,
  res= 0;
error:
  lex->unit.cleanup();
  table_list->table->insert_values=0;
  DBUG_RETURN(res);
}

@@ -1513,28 +1515,6 @@ static bool init_param_array(Prepared_statement *stmt)
  return 0;
}


/* Init statement before execution */

static void cleanup_stmt_for_execute(Prepared_statement *stmt)
{
  THD *thd= stmt->thd;
  LEX *lex= stmt->lex;
  SELECT_LEX *sl= lex->all_selects_list;

  for (; sl; sl= sl->next_select_in_list())
  {
    for (TABLE_LIST *tables= (TABLE_LIST*) sl->table_list.first;
	 tables;
	 tables= tables->next)
    {
      if (tables->table)
        tables->table->insert_values= 0;
    }
  }
}


/*
  Given a query string with parameter markers, create a Prepared Statement
  from it and send PS info back to the client.
@@ -1635,7 +1615,6 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,

  if (!error)
    error= send_prepare_results(stmt, test(name));
  cleanup_stmt_for_execute(stmt);

  /* restore to WAIT_PRIOR: QUERY_PRIOR is set inside alloc_query */
  if (!(specialflag & SPECIAL_NO_PRIOR))
@@ -1926,7 +1905,6 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt,
  reset_stmt_params(stmt);
  close_thread_tables(thd);                    // to close derived tables
  thd->set_statement(&thd->stmt_backup);
  cleanup_stmt_for_execute(stmt);
  DBUG_VOID_RETURN;
}