Commit 282ec5bd authored by unknown's avatar unknown
Browse files

Merge bk-internal.mysql.com:/home/bk/mysql-4.1

into mysql.com:/home/kostja/work/mysql-4.1-4912


sql/item_cmpfunc.cc:
  Auto merged
sql/mysql_priv.h:
  Auto merged
sql/sql_base.cc:
  Auto merged
sql/sql_class.h:
  Auto merged
sql/sql_parse.cc:
  Auto merged
sql/sql_prepare.cc:
  Auto merged
sql/sql_select.cc:
  Auto merged
parents ae99cc1f 095b686c
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -219,3 +219,10 @@ Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length I
t1	MyISAM	9	Dynamic	0	0	0	4294967295	1024	0	NULL	#	#	#	latin1_swedish_ci	NULL		
deallocate prepare stmt1 ;
drop table t1;
create table t1(a varchar(2), b varchar(3));
prepare stmt1 from "select a, b from t1 where (not (a='aa' and b < 'zzz'))";
execute stmt1;
a	b
execute stmt1;
a	b
deallocate prepare stmt1;
+12 −0
Original line number Diff line number Diff line
@@ -206,3 +206,15 @@ execute stmt1;
show table status from test like 't1%' ;
deallocate prepare stmt1 ;
drop table t1;

#
# Bug#4912 "mysqld crashs in case a statement is executed a second time":
# negation elimination should and prepared statemens
# 

create table t1(a varchar(2), b varchar(3));
prepare stmt1 from "select a, b from t1 where (not (a='aa' and b < 'zzz'))";
execute stmt1;
execute stmt1;
deallocate prepare stmt1;
+1 −3
Original line number Diff line number Diff line
@@ -589,10 +589,8 @@ bool Item_in_optimizer::fix_left(THD *thd,
  /*
    If it is preparation PS only then we do not know values of parameters =>
    cant't get there values and do not need that values.

    TODO: during merge with 5.0 it should be changed on !thd->only_prepare()
  */
  if (!thd->current_statement)
  if (! thd->current_arena->is_stmt_prepare())
    cache->store(args[0]);
  if (cache->cols() == 1)
  {
+26 −24
Original line number Diff line number Diff line
@@ -125,7 +125,6 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref)
{
  DBUG_ASSERT(fixed == 0);
  engine->set_thd((thd= thd_param));
  stmt= thd->current_statement;

  char const *save_where= thd->where;
  int res;
@@ -306,7 +305,10 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
    return RES_OK;

  SELECT_LEX *select_lex= join->select_lex;
  Statement backup;

  /* Juggle with current arena only if we're in prepared statement prepare */
  Item_arena *arena= join->thd->current_arena;
  Item_arena backup;

  if (!select_lex->master_unit()->first_select()->next_select() &&
      !select_lex->table_list.elements &&
@@ -341,8 +343,8 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
    if (join->conds || join->having)
    {
      Item *cond;
      if (stmt)
	thd->set_n_backup_item_arena(stmt, &backup);
      if (arena->is_stmt_prepare())
	thd->set_n_backup_item_arena(arena, &backup);

      if (!join->having)
	cond= join->conds;
@@ -355,15 +357,15 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
					   new Item_null())))
	goto err;
    }
    if (stmt)
      thd->restore_backup_item_arena(stmt, &backup);
    if (arena->is_stmt_prepare())
      thd->restore_backup_item_arena(arena, &backup);
    return RES_REDUCE;
  }
  return RES_OK;

err:
  if (stmt)
    thd->restore_backup_item_arena(stmt, &backup);
  if (arena->is_stmt_prepare())
    thd->restore_backup_item_arena(arena, &backup);
  return RES_ERROR;
}

@@ -640,11 +642,11 @@ Item_in_subselect::single_value_transformer(JOIN *join,
  }

  SELECT_LEX *select_lex= join->select_lex;
  Statement backup;
  Item_arena *arena= join->thd->current_arena, backup;

  thd->where= "scalar IN/ALL/ANY subquery";
  if (stmt)
    thd->set_n_backup_item_arena(stmt, &backup);
  if (arena->is_stmt_prepare())
    thd->set_n_backup_item_arena(arena, &backup);

  if (select_lex->item_list.elements > 1)
  {
@@ -857,21 +859,21 @@ Item_in_subselect::single_value_transformer(JOIN *join,
	  push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
		       ER_SELECT_REDUCED, warn_buff);
	}
	if (stmt)
	  thd->restore_backup_item_arena(stmt, &backup);
	if (arena->is_stmt_prepare())
	  thd->restore_backup_item_arena(arena, &backup);
	DBUG_RETURN(RES_REDUCE);
      }
    }
  }

ok:
  if (stmt)
    thd->restore_backup_item_arena(stmt, &backup);
  if (arena->is_stmt_prepare())
    thd->restore_backup_item_arena(arena, &backup);
  DBUG_RETURN(RES_OK);

err:
  if (stmt)
    thd->restore_backup_item_arena(stmt, &backup);
  if (arena->is_stmt_prepare())
    thd->restore_backup_item_arena(arena, &backup);
  DBUG_RETURN(RES_ERROR);
}

@@ -885,12 +887,12 @@ Item_in_subselect::row_value_transformer(JOIN *join)
  {
    DBUG_RETURN(RES_OK);
  }
  Statement backup;
  Item_arena *arena= join->thd->current_arena, backup;
  Item *item= 0;

  thd->where= "row IN/ALL/ANY subquery";
  if (stmt)
    thd->set_n_backup_item_arena(stmt, &backup);
  if (arena->is_stmt_prepare())
    thd->set_n_backup_item_arena(arena, &backup);

  SELECT_LEX *select_lex= join->select_lex;

@@ -974,13 +976,13 @@ Item_in_subselect::row_value_transformer(JOIN *join)
    if (join->conds->fix_fields(thd, join->tables_list, 0))
      goto err;
  }
  if (stmt)
    thd->restore_backup_item_arena(stmt, &backup);
  if (arena->is_stmt_prepare())
    thd->restore_backup_item_arena(arena, &backup);
  DBUG_RETURN(RES_OK);

err:
  if (stmt)
    thd->restore_backup_item_arena(stmt, &backup);
  if (arena->is_stmt_prepare())
    thd->restore_backup_item_arena(arena, &backup);
  DBUG_RETURN(RES_ERROR);
}

+0 −2
Original line number Diff line number Diff line
@@ -36,8 +36,6 @@ class Item_subselect :public Item_result_field
protected:
  /* thread handler, will be assigned in fix_fields only */
  THD *thd;
  /* prepared statement, or 0 */
  Statement *stmt;
  /* substitution instead of subselect in case of optimization */
  Item *substitution;
  /* unit of subquery */
Loading