Commit 19e2ed76 authored by Sergey Petrunia's avatar Sergey Petrunia
Browse files

Automerge

parents 6cac08bc 7f16afcc
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -1103,6 +1103,24 @@ set @my_innodb_commit_concurrency=@@global.innodb_commit_concurrency;
set global innodb_commit_concurrency=0;
set global innodb_commit_concurrency=@my_innodb_commit_concurrency;

#
# Bug #37830: ORDER BY ASC/DESC - no difference
#

CREATE TABLE t1 (a int, b int, c int, PRIMARY KEY (a), KEY t1_b (b))
 ENGINE=InnoDB;

INSERT INTO t1 (a,b,c) VALUES (1,1,1), (2,1,1), (3,1,1), (4,1,1);
INSERT INTO t1 (a,b,c) SELECT a+4,b,c FROM t1;

# should be range access
EXPLAIN SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;

# should produce '8 7 6 5 4' for a
SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;

DROP TABLE t1;

--echo End of 5.0 tests

# Fix for BUG#19243 "wrong LAST_INSERT_ID() after ON DUPLICATE KEY
+15 −0
Original line number Diff line number Diff line
@@ -1362,6 +1362,21 @@ set global innodb_autoextend_increment=@my_innodb_autoextend_increment;
set @my_innodb_commit_concurrency=@@global.innodb_commit_concurrency;
set global innodb_commit_concurrency=0;
set global innodb_commit_concurrency=@my_innodb_commit_concurrency;
CREATE TABLE t1 (a int, b int, c int, PRIMARY KEY (a), KEY t1_b (b))
ENGINE=InnoDB;
INSERT INTO t1 (a,b,c) VALUES (1,1,1), (2,1,1), (3,1,1), (4,1,1);
INSERT INTO t1 (a,b,c) SELECT a+4,b,c FROM t1;
EXPLAIN SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	SIMPLE	t1	index	t1_b	PRIMARY	4	NULL	8	Using where
SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
a	b	c
8	1	1
7	1	1
6	1	1
5	1	1
4	1	1
DROP TABLE t1;
End of 5.0 tests
CREATE TABLE `t2` (
`k` int(11) NOT NULL auto_increment,
+12 −54
Original line number Diff line number Diff line
@@ -8560,7 +8560,8 @@ bool QUICK_RANGE_SELECT::row_in_ranges()

QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q,
                                     uint used_key_parts_arg)
 :QUICK_RANGE_SELECT(*q), rev_it(rev_ranges)
 :QUICK_RANGE_SELECT(*q), rev_it(rev_ranges),
  used_key_parts (used_key_parts_arg)
{
  QUICK_RANGE *r;

@@ -8602,8 +8603,9 @@ int QUICK_SELECT_DESC::get_next()
    int result;
    if (last_range)
    {						// Already read through key
      result = ((last_range->flag & EQ_RANGE)
		? file->index_next_same(record, last_range->min_key,
      result = ((last_range->flag & EQ_RANGE && 
                 used_key_parts <= head->key_info[index].key_parts) ? 
                file->index_next_same(record, last_range->min_key,
                                      last_range->min_length) :
                file->index_prev(record));
      if (!result)
@@ -8629,7 +8631,9 @@ int QUICK_SELECT_DESC::get_next()
      continue;
    }

    if (last_range->flag & EQ_RANGE)
    if (last_range->flag & EQ_RANGE &&
        used_key_parts <= head->key_info[index].key_parts)

    {
      result = file->index_read_map(record, last_range->max_key,
                                    last_range->max_keypart_map,
@@ -8638,6 +8642,8 @@ int QUICK_SELECT_DESC::get_next()
    else
    {
      DBUG_ASSERT(last_range->flag & NEAR_MAX ||
                  (last_range->flag & EQ_RANGE && 
                   used_key_parts > head->key_info[index].key_parts) ||
                  range_reads_after_key(last_range));
      result=file->index_read_map(record, last_range->max_key,
                                  last_range->max_keypart_map,
@@ -8735,54 +8741,6 @@ bool QUICK_SELECT_DESC::range_reads_after_key(QUICK_RANGE *range_arg)
}


/* TRUE if we are reading over a key that may have a NULL value */

#ifdef NOT_USED
bool QUICK_SELECT_DESC::test_if_null_range(QUICK_RANGE *range_arg,
					   uint used_key_parts)
{
  uint offset, end;
  KEY_PART *key_part = key_parts,
           *key_part_end= key_part+used_key_parts;

  for (offset= 0,  end = min(range_arg->min_length, range_arg->max_length) ;
       offset < end && key_part != key_part_end ;
       offset+= key_part++->store_length)
  {
    if (!memcmp((char*) range_arg->min_key+offset,
		(char*) range_arg->max_key+offset,
		key_part->store_length))
      continue;

    if (key_part->null_bit && range_arg->min_key[offset])
      return 1;				// min_key is null and max_key isn't
    // Range doesn't cover NULL. This is ok if there is no more null parts
    break;
  }
  /*
    If the next min_range is > NULL, then we can use this, even if
    it's a NULL key
    Example:  SELECT * FROM t1 WHERE a = 2 AND b >0 ORDER BY a DESC,b DESC;

  */
  if (key_part != key_part_end && key_part->null_bit)
  {
    if (offset >= range_arg->min_length || range_arg->min_key[offset])
      return 1;					// Could be null
    key_part++;
  }
  /*
    If any of the key parts used in the ORDER BY could be NULL, we can't
    use the key to sort the data.
  */
  for (; key_part != key_part_end ; key_part++)
    if (key_part->null_bit)
      return 1;					// Covers null part
  return 0;
}
#endif


void QUICK_RANGE_SELECT::add_info_string(String *str)
{
  KEY *key_info= head->key_info + index;
+1 −3
Original line number Diff line number Diff line
@@ -686,12 +686,10 @@ class QUICK_SELECT_DESC: public QUICK_RANGE_SELECT
  int get_type() { return QS_TYPE_RANGE_DESC; }
private:
  bool range_reads_after_key(QUICK_RANGE *range);
#ifdef NOT_USED
  bool test_if_null_range(QUICK_RANGE *range, uint used_key_parts);
#endif
  int reset(void) { rev_it.rewind(); return QUICK_RANGE_SELECT::reset(); }
  List<QUICK_RANGE> rev_ranges;
  List_iterator<QUICK_RANGE> rev_it;
  uint used_key_parts;
};


+24 −5
Original line number Diff line number Diff line
@@ -12508,6 +12508,9 @@ part_of_refkey(TABLE *table,Field *field)
  @note
    used_key_parts is set to correct key parts used if return value != 0
    (On other cases, used_key_part may be changed)
    Note that the value may actually be greater than the number of index 
    key parts. This can happen for storage engines that have the primary 
    key parts as a suffix for every secondary key.
  @retval
    1   key is ok.
@@ -12580,11 +12583,27 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
    reverse=flag;				// Remember if reverse
    key_part++;
  }
  *used_key_parts= on_primary_key ? table->key_info[idx].key_parts :
    (uint) (key_part - table->key_info[idx].key_part);
  if (reverse == -1 && !(table->file->index_flags(idx, *used_key_parts-1, 1) &
                         HA_READ_PREV))
  if (on_primary_key)
  {
    uint used_key_parts_secondary= table->key_info[idx].key_parts;
    uint used_key_parts_pk=
      (uint) (key_part - table->key_info[table->s->primary_key].key_part);
    *used_key_parts= used_key_parts_pk + used_key_parts_secondary;
    if (reverse == -1 &&
        (!(table->file->index_flags(idx, used_key_parts_secondary - 1, 1) &
           HA_READ_PREV) ||
         !(table->file->index_flags(table->s->primary_key,
                                    used_key_parts_pk - 1, 1) & HA_READ_PREV)))
      reverse= 0;                               // Index can't be used
  }
  else
  {
    *used_key_parts= (uint) (key_part - table->key_info[idx].key_part);
    if (reverse == -1 && 
        !(table->file->index_flags(idx, *used_key_parts-1, 1) & HA_READ_PREV))
      reverse= 0;                               // Index can't be used
  }
  DBUG_RETURN(reverse);
}