Commit 4ee0c217 authored by unknown's avatar unknown
Browse files

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

into  chilla.local:/home/mydev/mysql-5.1-axmrg


sql/lock.cc:
  Auto merged
sql/opt_range.cc:
  Auto merged
sql/sql_class.h:
  Auto merged
sql/sql_insert.cc:
  Auto merged
sql/sql_parse.cc:
  Auto merged
sql/sql_update.cc:
  Auto merged
sql/table.cc:
  Auto merged
storage/federated/ha_federated.cc:
  Auto merged
storage/myisam/mi_check.c:
  Auto merged
storage/myisam/mi_dynrec.c:
  Auto merged
storage/myisam/mi_locking.c:
  Auto merged
storage/myisam/mi_open.c:
  Auto merged
storage/myisam/mi_packrec.c:
  Auto merged
storage/myisam/mi_range.c:
  Auto merged
storage/myisam/mi_test1.c:
  Auto merged
storage/myisam/mi_update.c:
  Auto merged
storage/myisam/mi_write.c:
  Auto merged
storage/myisam/myisamdef.h:
  Auto merged
storage/myisam/rt_split.c:
  Auto merged
parents f20cb8d0 980a1d1e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -121,6 +121,7 @@ typedef struct st_thr_lock {
  void (*get_status)(void*, int);	/* When one gets a lock */
  void (*copy_status)(void*,void*);
  void (*update_status)(void*);		/* Before release of write */
  void (*restore_status)(void*);         /* Before release of read */
  my_bool (*check_status)(void *);
} THR_LOCK;

+16 −0
Original line number Diff line number Diff line
@@ -1603,6 +1603,22 @@ select * from t1;
a
42
drop table t1;
CREATE TABLE t1(a VARCHAR(16));
INSERT INTO t1 VALUES('aaaaaaaa'),(NULL);
UPDATE t1 AS ta1, t1 AS ta2 SET ta1.a='aaaaaaaaaaaaaaaa';
SELECT * FROM t1;
a
aaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaa
DROP TABLE t1;
CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES(1),(2);
UPDATE t1,t1 AS t2 SET t1.a=t1.a+2 WHERE t1.a=t2.a-1;
SELECT * FROM t1 ORDER BY a;
a
2
3
DROP TABLE t1;
End of 4.1 tests
create table t1 (c1 int) engine=myisam pack_keys=0;
create table t2 (c1 int) engine=myisam pack_keys=1;
+18 −0
Original line number Diff line number Diff line
@@ -977,6 +977,24 @@ connection default;
select * from t1;
drop table t1;

#
# BUG#21310 - Trees in SQL causing a "crashed" table with MyISAM storage
#             engine
#

# A simplified test case that reflect crashed table issue.
CREATE TABLE t1(a VARCHAR(16));
INSERT INTO t1 VALUES('aaaaaaaa'),(NULL);
UPDATE t1 AS ta1, t1 AS ta2 SET ta1.a='aaaaaaaaaaaaaaaa';
SELECT * FROM t1;
DROP TABLE t1;

# A test case that reflect wrong result set.
CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES(1),(2);
UPDATE t1,t1 AS t2 SET t1.a=t1.a+2 WHERE t1.a=t2.a-1;
SELECT * FROM t1 ORDER BY a;
DROP TABLE t1;
--echo End of 4.1 tests

#
+10 −2
Original line number Diff line number Diff line
@@ -757,8 +757,16 @@ void thr_unlock(THR_LOCK_DATA *data)
  }
  else
    lock->write.last=data->prev;
  if (lock_type >= TL_WRITE_CONCURRENT_INSERT && lock->update_status)
  if (lock_type >= TL_WRITE_CONCURRENT_INSERT)
  {
    if (lock->update_status)
      (*lock->update_status)(data->status_param);
  }
  else
  {
    if (lock->restore_status)
      (*lock->restore_status)(data->status_param);
  }
  if (lock_type == TL_READ_NO_INSERT)
    lock->read_no_write_count--;
  data->type=TL_UNLOCK;				/* Mark unlocked */
+61 −74
Original line number Diff line number Diff line
@@ -24,8 +24,6 @@
#include "sp_head.h"
#include "sql_trigger.h"

static bool safe_update_on_fly(JOIN_TAB *join_tab);

/* Return 0 if row hasn't changed */

static bool compare_record(TABLE *table)
@@ -1160,27 +1158,71 @@ int multi_update::prepare(List<Item> &not_used_values,
  for (i=0 ; i < table_count ; i++)
    set_if_bigger(max_fields, fields_for_table[i]->elements);
  copy_field= new Copy_field[max_fields];
  DBUG_RETURN(thd->is_fatal_error != 0);
}


/*
    Mark all copies of tables that are updates to ensure that
    init_read_record() will not try to enable a cache on them
  Check if table is safe to update on fly

  SYNOPSIS
    safe_update_on_fly()
    thd                 Thread handler
    join_tab            How table is used in join
    all_tables          List of tables

    The problem is that for queries like
  NOTES
    We can update the first table in join on the fly if we know that
    a row in this table will never be read twice. This is true under
    the following conditions:

    UPDATE t1, t1 AS t2 SET t1.b=t2.c WHERE t1.a=t2.a;
    - We are doing a table scan and the data is in a separate file (MyISAM) or
      if we don't update a clustered key.

    the row buffer may contain things that doesn't match what is on disk
    which will cause an error when reading a row.
    (This issue is mostly relevent for MyISAM tables)
    - We are doing a range scan and we don't update the scan key or
      the primary key for a clustered table handler.

    - Table is not joined to itself.

    This function gets information about fields to be updated from
    the TABLE::write_set bitmap.

  WARNING
    This code is a bit dependent of how make_join_readinfo() works.

  RETURN
    0		Not safe to update
    1		Safe to update
*/
  for (table_ref= leaves;  table_ref; table_ref= table_ref->next_leaf)

static bool safe_update_on_fly(THD *thd, JOIN_TAB *join_tab,
                               TABLE_LIST *table_ref, TABLE_LIST *all_tables)
{
    TABLE *table=table_ref->table;
    if ((tables_to_update & table->map) &&
        unique_table(thd, table_ref, update_tables))
      table->no_cache= 1;			// Disable row cache
  TABLE *table= join_tab->table;
  if (unique_table(thd, table_ref, all_tables))
    return 0;
  switch (join_tab->type) {
  case JT_SYSTEM:
  case JT_CONST:
  case JT_EQ_REF:
    return TRUE;				// At most one matching row
  case JT_REF:
  case JT_REF_OR_NULL:
    return !is_key_used(table, join_tab->ref.key, table->write_set);
  case JT_ALL:
    /* If range search on index */
    if (join_tab->quick)
      return !join_tab->quick->is_keys_used(table->write_set);
    /* If scanning in clustered key */
    if ((table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
	table->s->primary_key < MAX_KEY)
      return !is_key_used(table, table->s->primary_key, table->write_set);
    return TRUE;
  default:
    break;					// Avoid compler warning
  }
  DBUG_RETURN(thd->is_fatal_error != 0);
  return FALSE;

}


@@ -1220,7 +1262,7 @@ multi_update::initialize_tables(JOIN *join)
      table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
    if (table == main_table)			// First table in join
    {
      if (safe_update_on_fly(join->join_tab))
      if (safe_update_on_fly(thd, join->join_tab, table_ref, all_tables))
      {
	table_to_update= main_table;		// Update table on the fly
	continue;
@@ -1272,61 +1314,6 @@ multi_update::initialize_tables(JOIN *join)
  DBUG_RETURN(0);
}

/*
  Check if table is safe to update on fly

  SYNOPSIS
    safe_update_on_fly
    join_tab		How table is used in join

  NOTES
    We can update the first table in join on the fly if we know that
    a row in this table will never be read twice. This is true under
    the following conditions:

    - We are doing a table scan and the data is in a separate file (MyISAM) or
      if we don't update a clustered key.

    - We are doing a range scan and we don't update the scan key or
      the primary key for a clustered table handler.

    This function gets information about fields to be updated from
    the TABLE::write_set bitmap.

  WARNING
    This code is a bit dependent of how make_join_readinfo() works.

  RETURN
    0		Not safe to update
    1		Safe to update
*/

static bool safe_update_on_fly(JOIN_TAB *join_tab)
{
  TABLE *table= join_tab->table;
  switch (join_tab->type) {
  case JT_SYSTEM:
  case JT_CONST:
  case JT_EQ_REF:
    return TRUE;				// At most one matching row
  case JT_REF:
  case JT_REF_OR_NULL:
    return !is_key_used(table, join_tab->ref.key, table->write_set);
  case JT_ALL:
    /* If range search on index */
    if (join_tab->quick)
      return !join_tab->quick->is_keys_used(table->write_set);
    /* If scanning in clustered key */
    if ((table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
	table->s->primary_key < MAX_KEY)
      return !is_key_used(table, table->s->primary_key, table->write_set);
    return TRUE;
  default:
    break;					// Avoid compler warning
  }
  return FALSE;
}


multi_update::~multi_update()
{
Loading