List:Commits« Previous MessageNext Message »
From:Sergei Golubchik Date:January 29 2007 10:40am
Subject:bk commit into 5.1 tree (serg:1.2415)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of serg. When serg does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-01-29 10:40:26+01:00, serg@stripped +58 -0
  WL#3700: Handler API change: all index search methods - that is,
  index_read(), index_read_idx(), index_read_last(), and
  records_in_range() - instead of 'uint keylen' argument take
  'ulonglong keypart_map', a bitmap showing which keyparts are
  present in the key value.
  Fallback method is provided for handlers that are lagging behind.

  include/heap.h@stripped, 2007-01-29 10:40:16+01:00, serg@stripped +1 -1
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  include/my_base.h@stripped, 2007-01-29 10:40:16+01:00, serg@stripped +5 -3
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  include/myisam.h@stripped, 2007-01-29 10:40:16+01:00, serg@stripped +3 -4
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  include/myisammrg.h@stripped, 2007-01-29 10:40:16+01:00, serg@stripped +3 -3
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/event_db_repository.cc@stripped, 2007-01-29 10:40:17+01:00, serg@stripped +2 -4
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/ha_ndbcluster.cc@stripped, 2007-01-29 10:40:17+01:00, serg@stripped +3 -17
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/ha_ndbcluster.h@stripped, 2007-01-29 10:40:17+01:00, serg@stripped +0 -2
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/ha_partition.cc@stripped, 2007-01-29 10:40:17+01:00, serg@stripped +14 -41
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/ha_partition.h@stripped, 2007-01-29 10:40:17+01:00, serg@stripped +5 -5
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/handler.cc@stripped, 2007-01-29 10:40:17+01:00, serg@stripped +19 -17
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/handler.h@stripped, 2007-01-29 10:40:17+01:00, serg@stripped +33 -5
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/item_subselect.cc@stripped, 2007-01-29 10:40:17+01:00, serg@stripped +4 -2
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/key.cc@stripped, 2007-01-29 10:40:17+01:00, serg@stripped +9 -5
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/log.cc@stripped, 2007-01-29 10:40:17+01:00, serg@stripped +1 -1
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/log_event.cc@stripped, 2007-01-29 10:40:18+01:00, serg@stripped +3 -5
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/mysql_priv.h@stripped, 2007-01-29 10:40:18+01:00, serg@stripped +1 -1
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/opt_range.cc@stripped, 2007-01-29 10:40:18+01:00, serg@stripped +147 -96
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/opt_range.h@stripped, 2007-01-29 10:40:18+01:00, serg@stripped +16 -7
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/opt_sum.cc@stripped, 2007-01-29 10:40:18+01:00, serg@stripped +11 -7
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/slave.cc@stripped, 2007-01-29 10:40:18+01:00, serg@stripped +2 -0
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/slave.h@stripped, 2007-01-29 10:40:18+01:00, serg@stripped +0 -2
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/sp.cc@stripped, 2007-01-29 10:40:18+01:00, serg@stripped +2 -5
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/sql_acl.cc@stripped, 2007-01-29 10:40:18+01:00, serg@stripped +12 -19
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/sql_handler.cc@stripped, 2007-01-29 10:40:19+01:00, serg@stripped +4 -2
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/sql_help.cc@stripped, 2007-01-29 10:40:19+01:00, serg@stripped +2 -3
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/sql_insert.cc@stripped, 2007-01-29 10:40:19+01:00, serg@stripped +1 -3
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/sql_plugin.cc@stripped, 2007-01-29 10:40:19+01:00, serg@stripped +1 -2
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/sql_select.cc@stripped, 2007-01-29 10:40:19+01:00, serg@stripped +10 -6
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/sql_select.h@stripped, 2007-01-29 10:40:19+01:00, serg@stripped +5 -0
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/sql_servers.cc@stripped, 2007-01-29 10:40:19+01:00, serg@stripped +5 -8
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/sql_servers.h@stripped, 2007-01-29 10:40:19+01:00, serg@stripped +0 -1
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/sql_udf.cc@stripped, 2007-01-29 10:40:19+01:00, serg@stripped +1 -2
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/table.cc@stripped, 2007-01-29 10:40:19+01:00, serg@stripped +29 -5
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/table.h@stripped, 2007-01-29 10:40:20+01:00, serg@stripped +1 -0
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  sql/tztime.cc@stripped, 2007-01-29 10:40:20+01:00, serg@stripped +5 -7
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  storage/blackhole/ha_blackhole.cc@stripped, 2007-01-29 10:40:20+01:00, serg@stripped +6
-3
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  storage/blackhole/ha_blackhole.h@stripped, 2007-01-29 10:40:20+01:00, serg@stripped +4 -3
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  storage/example/ha_example.cc@stripped, 2007-01-29 10:40:20+01:00, serg@stripped +2 -3
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  storage/example/ha_example.h@stripped, 2007-01-29 10:40:20+01:00, serg@stripped +1 -1
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  storage/federated/ha_federated.cc@stripped, 2007-01-29 10:40:20+01:00, serg@stripped +1
-4
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  storage/heap/ha_heap.cc@stripped, 2007-01-29 10:40:20+01:00, serg@stripped +7 -6
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  storage/heap/ha_heap.h@stripped, 2007-01-29 10:40:20+01:00, serg@stripped +5 -5
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  storage/heap/heapdef.h@stripped, 2007-01-29 10:40:20+01:00, serg@stripped +1 -1
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  storage/heap/hp_hash.c@stripped, 2007-01-29 10:40:20+01:00, serg@stripped +3 -9
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  storage/heap/hp_rkey.c@stripped, 2007-01-29 10:40:20+01:00, serg@stripped +2 -2
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  storage/innobase/handler/ha_innodb.cc@stripped, 2007-01-29 10:40:20+01:00, serg@stripped
+8 -8
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  storage/myisam/ha_myisam.cc@stripped, 2007-01-29 10:40:21+01:00, serg@stripped +15 -11
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  storage/myisam/ha_myisam.h@stripped, 2007-01-29 10:40:21+01:00, serg@stripped +5 -5
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  storage/myisam/mi_check.c@stripped, 2007-01-29 10:40:21+01:00, serg@stripped +1 -1
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  storage/myisam/mi_key.c@stripped, 2007-01-29 10:40:21+01:00, serg@stripped +14 -37
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  storage/myisam/mi_range.c@stripped, 2007-01-29 10:40:21+01:00, serg@stripped +18 -24
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  storage/myisam/mi_rkey.c@stripped, 2007-01-29 10:40:21+01:00, serg@stripped +8 -9
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  storage/myisam/myisamdef.h@stripped, 2007-01-29 10:40:21+01:00, serg@stripped +3 -2
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  storage/myisam/rt_test.c@stripped, 2007-01-29 10:40:21+01:00, serg@stripped +1 -1
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  storage/myisam/sp_test.c@stripped, 2007-01-29 10:40:21+01:00, serg@stripped +1 -1
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  storage/myisammrg/ha_myisammrg.cc@stripped, 2007-01-29 10:40:21+01:00, serg@stripped +9
-6
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  storage/myisammrg/ha_myisammrg.h@stripped, 2007-01-29 10:40:21+01:00, serg@stripped +5 -5
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

  storage/myisammrg/myrg_rkey.c@stripped, 2007-01-29 10:40:21+01:00, serg@stripped +3 -3
    WL#3700: Handler API change: all index search methods - that is,
    index_read(), index_read_idx(), index_read_last(), and
    records_in_range() - instead of 'uint keylen' argument take
    'ulonglong keypart_map', a bitmap showing which keyparts are
    present in the key value.
    Fallback method is provided for handlers that are lagging behind.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	serg
# Host:	janus.mylan
# Root:	/usr/home/serg/Abk/mysql-5.1

--- 1.17/storage/heap/heapdef.h	2007-01-29 10:40:34 +01:00
+++ 1.18/storage/heap/heapdef.h	2007-01-29 10:40:34 +01:00
@@ -100,7 +100,7 @@ extern int hp_close(register HP_INFO *in
 extern void hp_clear(HP_SHARE *info);
 extern void hp_clear_keys(HP_SHARE *info);
 extern uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old, 
-			   uint k_len);
+                    ulonglong keypart_map);
 #ifdef THREAD
 extern pthread_mutex_t THR_LOCK_heap;
 #else

--- 1.47/storage/heap/hp_hash.c	2007-01-29 10:40:34 +01:00
+++ 1.48/storage/heap/hp_hash.c	2007-01-29 10:40:34 +01:00
@@ -784,30 +784,26 @@ uint hp_rb_make_key(HP_KEYDEF *keydef, b
 
 
 uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old,
-                    uint k_len)
+                    ulonglong keypart_map)
 {
   HA_KEYSEG *seg, *endseg;
   uchar *start_key= key;
   
   for (seg= keydef->seg, endseg= seg + keydef->keysegs;
-       seg < endseg && (int) k_len > 0; old+= seg->length, seg++)
+       seg < endseg && keypart_map; old+= seg->length, seg++)
   {
     uint char_length;
+    keypart_map>>= 1;
     if (seg->null_bit)
     {
-      k_len--;
       if (!(*key++= (char) 1 - *old++))
-      {
-        k_len-= seg->length;
         continue;
       }
-    }
     if (seg->flag & HA_SWAP_KEY)
     {
       uint length= seg->length;
       byte *pos= (byte*) old + length;
       
-      k_len-= length;
       while (length--)
       {
 	*key++= *--pos;
@@ -822,7 +818,6 @@ uint hp_rb_pack_key(HP_KEYDEF *keydef, u
       CHARSET_INFO *cs= seg->charset;
       char_length= length/cs->mbmaxlen;
 
-      k_len-= 2+length;
       old+= 2;
       set_if_smaller(length,tmp_length);	/* Safety */
       FIX_LENGTH(cs, old, length, char_length);
@@ -843,7 +838,6 @@ uint hp_rb_pack_key(HP_KEYDEF *keydef, u
     }
     memcpy(key, old, (size_t) char_length);
     key+= seg->length;
-    k_len-= seg->length;
   }
   return (uint) (key - start_key);
 }

--- 1.19/storage/heap/hp_rkey.c	2007-01-29 10:40:34 +01:00
+++ 1.20/storage/heap/hp_rkey.c	2007-01-29 10:40:34 +01:00
@@ -16,7 +16,7 @@
 #include "heapdef.h"
 
 int heap_rkey(HP_INFO *info, byte *record, int inx, const byte *key, 
-              uint key_len, enum ha_rkey_function find_flag)
+              ulonglong keypart_map, enum ha_rkey_function find_flag)
 {
   byte *pos;
   HP_SHARE *share= info->s;
@@ -38,7 +38,7 @@ int heap_rkey(HP_INFO *info, byte *recor
     custom_arg.keyseg= info->s->keydef[inx].seg;
     custom_arg.key_length= info->lastkey_len= 
       hp_rb_pack_key(keyinfo, (uchar*) info->lastkey,
-		     (uchar*) key, key_len);
+		     (uchar*) key, keypart_map);
     custom_arg.search_flag= SEARCH_FIND | SEARCH_SAME;
     /* for next rkey() after deletion */
     if (find_flag == HA_READ_AFTER_KEY)

--- 1.31/include/heap.h	2007-01-29 10:40:34 +01:00
+++ 1.32/include/heap.h	2007-01-29 10:40:34 +01:00
@@ -226,7 +226,7 @@ ha_rows hp_rb_records_in_range(HP_INFO *
                                key_range *max_key);
 int hp_panic(enum ha_panic_function flag);
 int heap_rkey(HP_INFO *info, byte *record, int inx, const byte *key, 
-              uint key_len, enum ha_rkey_function find_flag);
+              ulonglong keypart_map, enum ha_rkey_function find_flag);
 extern gptr heap_find(HP_INFO *info,int inx,const byte *key);
 extern int heap_check_heap(HP_INFO *info, my_bool print_status);
 extern byte *heap_position(HP_INFO *info);

--- 1.95/include/my_base.h	2007-01-29 10:40:34 +01:00
+++ 1.96/include/my_base.h	2007-01-29 10:40:34 +01:00
@@ -384,9 +384,10 @@ enum ha_base_keytype {
 #define HA_ERR_TABLE_NEEDS_UPGRADE 164  /* The table changed in storage engine */
 #define HA_ERR_TABLE_READONLY    165  /* The table is not writable */
 
-#define HA_ERR_AUTOINC_READ_FAILED 166/* Failed to get the next autoinc value */
-#define HA_ERR_AUTOINC_ERANGE    167  /* Failed to set the row autoinc value */
-#define HA_ERR_LAST              167  /*Copy last error nr.*/
+#define HA_ERR_AUTOINC_READ_FAILED 166   /* Failed to get next autoinc value */
+#define HA_ERR_AUTOINC_ERANGE    167     /* Failed to set row autoinc value */
+#define HA_ERR_GENERIC           168     /* Generic error */
+#define HA_ERR_LAST              168 /*Copy last error nr.*/
 /* Add error numbers before HA_ERR_LAST and change it accordingly. */
 #define HA_ERR_ERRORS            (HA_ERR_LAST - HA_ERR_FIRST + 1)
 
@@ -467,6 +468,7 @@ typedef struct st_key_range
 {
   const byte *key;
   uint length;
+  ulonglong keypart_map;
   enum ha_rkey_function flag;
 } key_range;
 

--- 1.80/include/myisam.h	2007-01-29 10:40:34 +01:00
+++ 1.81/include/myisam.h	2007-01-29 10:40:34 +01:00
@@ -274,9 +274,8 @@ extern struct st_myisam_info *mi_open(co
 				      uint wait_if_locked);
 extern int mi_panic(enum ha_panic_function function);
 extern int mi_rfirst(struct st_myisam_info *file,byte *buf,int inx);
-extern int mi_rkey(struct st_myisam_info *file,byte *buf,int inx,
-		   const byte *key,
-		   uint key_len, enum ha_rkey_function search_flag);
+extern int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key,
+            ulonglong keypart_map, enum ha_rkey_function search_flag);
 extern int mi_rlast(struct st_myisam_info *file,byte *buf,int inx);
 extern int mi_rnext(struct st_myisam_info *file,byte *buf,int inx);
 extern int mi_rnext_same(struct st_myisam_info *info, byte *buf);
@@ -303,7 +302,7 @@ extern int mi_extra(struct st_myisam_inf
 		    enum ha_extra_function function,
 		    void *extra_arg);
 extern int mi_reset(struct st_myisam_info *file);
-extern ha_rows mi_records_in_range(struct st_myisam_info *info,int inx,
+extern ha_rows mi_records_in_range(MI_INFO *info, int inx,
                                    key_range *min_key, key_range *max_key);
 extern int mi_log(int activate_log);
 extern int mi_is_changed(struct st_myisam_info *info);

--- 1.17/include/myisammrg.h	2007-01-29 10:40:34 +01:00
+++ 1.18/include/myisammrg.h	2007-01-29 10:40:34 +01:00
@@ -86,8 +86,8 @@ extern int myrg_rlast(MYRG_INFO *file,by
 extern int myrg_rnext(MYRG_INFO *file,byte *buf,int inx);
 extern int myrg_rprev(MYRG_INFO *file,byte *buf,int inx);
 extern int myrg_rnext_same(MYRG_INFO *file,byte *buf);
-extern int myrg_rkey(MYRG_INFO *file,byte *buf,int inx,const byte *key,
-		       uint key_len, enum ha_rkey_function search_flag);
+extern int myrg_rkey(MYRG_INFO *info,byte *buf,int inx, const byte *key,
+                     ulonglong keypart_map, enum ha_rkey_function search_flag);
 extern int myrg_rrnd(MYRG_INFO *file,byte *buf,ulonglong pos);
 extern int myrg_rsame(MYRG_INFO *file,byte *record,int inx);
 extern int myrg_update(MYRG_INFO *file,const byte *old,byte *new_rec);
@@ -100,7 +100,7 @@ extern int myrg_extra(MYRG_INFO *file,en
 		      void *extra_arg);
 extern int myrg_reset(MYRG_INFO *info);
 extern void myrg_extrafunc(MYRG_INFO *info,invalidator_by_filename inv);
-extern ha_rows myrg_records_in_range(MYRG_INFO *info,int inx,
+extern ha_rows myrg_records_in_range(MYRG_INFO *info, int inx,
                                      key_range *min_key, key_range *max_key);
 
 extern ulonglong myrg_position(MYRG_INFO *info);

--- 1.158/storage/myisam/mi_check.c	2007-01-29 10:40:34 +01:00
+++ 1.159/storage/myisam/mi_check.c	2007-01-29 10:40:34 +01:00
@@ -532,7 +532,7 @@ int chk_key(MI_CHECK *param, register MI
       mi_extra(info,HA_EXTRA_KEYREAD,0);
       bzero(info->lastkey,keyinfo->seg->length);
       if (!mi_rkey(info, info->rec_buff, key, (const byte*) info->lastkey,
-		   keyinfo->seg->length, HA_READ_KEY_EXACT))
+		   ULL(1), HA_READ_KEY_EXACT))
       {
 	/* Don't count this as a real warning, as myisamchk can't correct it */
 	uint save=param->warning_printed;

--- 1.55/storage/myisam/mi_key.c	2007-01-29 10:40:34 +01:00
+++ 1.56/storage/myisam/mi_key.c	2007-01-29 10:40:34 +01:00
@@ -206,7 +206,7 @@ uint _mi_make_key(register MI_INFO *info
     uint keynr		key number
     key			Store packed key here
     old			Not packed key
-    k_length		Length of 'old' to use
+    keypart_map         bitmap of used keyparts
     last_used_keyseg	out parameter.  May be NULL
 
    RETURN
@@ -216,34 +216,36 @@ uint _mi_make_key(register MI_INFO *info
 */
 
 uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
-		  uint k_length, HA_KEYSEG **last_used_keyseg)
+                  ulonglong keypart_map, HA_KEYSEG **last_used_keyseg)
 {
   uchar *start_key=key;
   HA_KEYSEG *keyseg;
   my_bool is_ft= info->s->keyinfo[keynr].flag & HA_FULLTEXT;
   DBUG_ENTER("_mi_pack_key");
 
-  for (keyseg=info->s->keyinfo[keynr].seg ;
-       keyseg->type && (int) k_length > 0;
-       old+=keyseg->length, keyseg++)
+  /* "one part" rtree key is 2*SPDIMS part key in MyISAM */
+  if (info->s->keyinfo[keynr].key_alg == HA_KEY_ALG_RTREE)
+    keypart_map= (ULL(1) << (2*SPDIMS)) - 1;
+
+  /* only key prefixes are supported */
+  DBUG_ASSERT(((keypart_map+1) & keypart_map) == 0);
+
+  for (keyseg= info->s->keyinfo[keynr].seg ; keyseg->type &&
keypart_map;
+       old+= keyseg->length, keyseg++)
   {
-    enum ha_base_keytype type=(enum ha_base_keytype) keyseg->type;
-    uint length=min((uint) keyseg->length,(uint) k_length);
+    enum ha_base_keytype type= (enum ha_base_keytype) keyseg->type;
+    uint length= keyseg->length;
     uint char_length;
     uchar *pos;
     CHARSET_INFO *cs=keyseg->charset;
 
+    keypart_map>>= 1;
     if (keyseg->null_bit)
     {
-      k_length--;
       if (!(*key++= (char) 1-*old++))			/* Copy null marker */
       {
-	k_length-=length;
         if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
-        {
-          k_length-=2;                                  /* Skip length */
           old+= 2;
-        }
 	continue;					/* Found NULL */
       }
     }
@@ -262,7 +264,6 @@ uint _mi_pack_key(register MI_INFO *info
 	while (pos < end && pos[0] == ' ')
 	  pos++;
       }
-      k_length-=length;
       length=(uint) (end-pos);
       FIX_LENGTH(cs, pos, length, char_length);
       store_key_length_inc(key,char_length);
@@ -274,7 +275,6 @@ uint _mi_pack_key(register MI_INFO *info
     {
       /* Length of key-part used with mi_rkey() always 2 */
       uint tmp_length=uint2korr(pos);
-      k_length-= 2+length;
       pos+=2;
       set_if_smaller(length,tmp_length);	/* Safety */
       FIX_LENGTH(cs, pos, length, char_length);
@@ -287,11 +287,8 @@ uint _mi_pack_key(register MI_INFO *info
     else if (keyseg->flag & HA_SWAP_KEY)
     {						/* Numerical column */
       pos+=length;
-      k_length-=length;
       while (length--)
-      {
 	*key++ = *--pos;
-      }
       continue;
     }
     FIX_LENGTH(cs, pos, length, char_length);
@@ -299,30 +296,10 @@ uint _mi_pack_key(register MI_INFO *info
     if (length > char_length)
       cs->cset->fill(cs, (char*) key+char_length, length-char_length, ' ');
     key+= length;
-    k_length-=length;
   }
   if (last_used_keyseg)
     *last_used_keyseg= keyseg;
 
-#ifdef NOT_USED
-  if (keyseg->type)
-  {
-    /* Part-key ; fill with ASCII 0 for easier searching */
-    length= (uint) -k_length;			/* unused part of last key */
-    do
-    {
-      if (keyseg->flag & HA_NULL_PART)
-	length++;
-      if (keyseg->flag & HA_SPACE_PACK)
-	length+=2;
-      else
-	length+= keyseg->length;
-      keyseg++;
-    } while (keyseg->type);
-    bzero((byte*) key,length);
-    key+=length;
-  }
-#endif
   DBUG_RETURN((uint) (key-start_key));
 } /* _mi_pack_key */
 

--- 1.21/storage/myisam/mi_range.c	2007-01-29 10:40:34 +01:00
+++ 1.22/storage/myisam/mi_range.c	2007-01-29 10:40:34 +01:00
@@ -21,13 +21,10 @@
 #include "myisamdef.h"
 #include "rt_index.h"
 
-static ha_rows _mi_record_pos(MI_INFO *info,const byte *key,uint key_len,
-			      enum ha_rkey_function search_flag);
-static double _mi_search_pos(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *key,
-			     uint key_len,uint nextflag,my_off_t pos);
-static uint _mi_keynr(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *page,
-		      uchar *keypos,uint *ret_max_key);
-
+static ha_rows _mi_record_pos(MI_INFO *, const byte *, ulonglong,
+                              enum ha_rkey_function);
+static double _mi_search_pos(MI_INFO *,MI_KEYDEF *,uchar *, uint,uint,my_off_t);
+static uint _mi_keynr(MI_INFO *info,MI_KEYDEF *,uchar *, uchar *,uint *);
 
 /*
   Estimate how many records there is in a given range
@@ -47,9 +44,8 @@ static uint _mi_keynr(MI_INFO *info,MI_K
     number	  Estimated number of rows
 */
   
-
-ha_rows mi_records_in_range(MI_INFO *info, int inx, key_range *min_key,
-                            key_range *max_key)
+ha_rows mi_records_in_range(MI_INFO *info, int inx,
+                            key_range *min_key, key_range *max_key)
 {
   ha_rows start_pos,end_pos,res;
   DBUG_ENTER("mi_records_in_range");
@@ -87,7 +83,7 @@ ha_rows mi_records_in_range(MI_INFO *inf
     }
     key_buff= info->lastkey+info->s->base.max_key_length;
     start_key_len= _mi_pack_key(info,inx, key_buff,
-                                (uchar*) min_key->key, min_key->length,
+                                (uchar*) min_key->key, min_key->keypart_map,
                                 (HA_KEYSEG**) 0);
     res= rtree_estimate(info, inx, key_buff, start_key_len,
                         myisam_read_vec[min_key->flag]);
@@ -97,14 +93,12 @@ ha_rows mi_records_in_range(MI_INFO *inf
 #endif
   case HA_KEY_ALG_BTREE:
   default:
-    start_pos= (min_key ?
-                _mi_record_pos(info, min_key->key, min_key->length, 
-                               min_key->flag) :
-                (ha_rows) 0);
-    end_pos=   (max_key ?
-                _mi_record_pos(info, max_key->key, max_key->length,
-                               max_key->flag) :
-                info->state->records+ (ha_rows) 1);
+    start_pos= (min_key ?  _mi_record_pos(info, min_key->key,
+                                          min_key->keypart_map, min_key->flag)
+                        : (ha_rows) 0);
+    end_pos=   (max_key ?  _mi_record_pos(info, max_key->key,
+                                          max_key->keypart_map, max_key->flag)
+                        : info->state->records + (ha_rows) 1);
     res= (end_pos < start_pos ? (ha_rows) 0 :
           (end_pos == start_pos ? (ha_rows) 1 : end_pos-start_pos));
     if (start_pos == HA_POS_ERROR || end_pos == HA_POS_ERROR)
@@ -122,21 +116,21 @@ ha_rows mi_records_in_range(MI_INFO *inf
 
 	/* Find relative position (in records) for key in index-tree */
 
-static ha_rows _mi_record_pos(MI_INFO *info, const byte *key, uint key_len,
+static ha_rows _mi_record_pos(MI_INFO *info, const byte *key,
+                              ulonglong keypart_map,
 			      enum ha_rkey_function search_flag)
 {
-  uint inx=(uint) info->lastinx, nextflag;
+  uint inx=(uint) info->lastinx, nextflag, key_len;
   MI_KEYDEF *keyinfo=info->s->keyinfo+inx;
   uchar *key_buff;
   double pos;
 
   DBUG_ENTER("_mi_record_pos");
   DBUG_PRINT("enter",("search_flag: %d",search_flag));
+  DBUG_ASSERT(keypart_map);
 
-  if (key_len == 0)
-    key_len=USE_WHOLE_KEY;
   key_buff=info->lastkey+info->s->base.max_key_length;
-  key_len=_mi_pack_key(info,inx,key_buff,(uchar*) key,key_len,
+  key_len=_mi_pack_key(info,inx,key_buff,(uchar*) key, keypart_map,
 		       (HA_KEYSEG**) 0);
   DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg,
 				    (uchar*) key_buff,key_len););

--- 1.29/storage/myisam/mi_rkey.c	2007-01-29 10:40:34 +01:00
+++ 1.30/storage/myisam/mi_rkey.c	2007-01-29 10:40:34 +01:00
@@ -21,8 +21,8 @@
 	/* Read a record using key */
 	/* Ordinary search_flag is 0 ; Give error if no record with key */
 
-int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
-	    enum ha_rkey_function search_flag)
+int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key,
+            ulonglong keypart_map, enum ha_rkey_function search_flag)
 {
   uchar *key_buff;
   MYISAM_SHARE *share=info->s;
@@ -30,8 +30,8 @@ int mi_rkey(MI_INFO *info, byte *buf, in
   HA_KEYSEG *last_used_keyseg;
   uint pack_key_length, use_key_length, nextflag;
   DBUG_ENTER("mi_rkey");
-  DBUG_PRINT("enter", ("base: %lx  buf: %lx  inx: %d  search_flag: %d",
-                       (long) info, (long) buf, inx, search_flag));
+  DBUG_PRINT("enter", ("base: %lx  buf: %lx  inx: %d  keyparts %lx search_flag: %d",
+                       (long) info, (long) buf, inx, keypart_map, search_flag));
 
   if ((inx = _mi_check_index(info,inx)) < 0)
     DBUG_RETURN(my_errno);
@@ -47,18 +47,17 @@ int mi_rkey(MI_INFO *info, byte *buf, in
       key is already packed!;  This happens when we are using a MERGE TABLE
     */
     key_buff=info->lastkey+info->s->base.max_key_length;
-    pack_key_length= key_len;
-    bmove(key_buff,key,key_len);
+    pack_key_length= keypart_map;
+    bmove(key_buff, key, pack_key_length);
     last_used_keyseg= 0;
   }
   else
   {
-    if (key_len == 0)
-      key_len=USE_WHOLE_KEY;
+    DBUG_ASSERT(keypart_map);
     /* Save the packed key for later use in the second buffer of lastkey. */
     key_buff=info->lastkey+info->s->base.max_key_length;
     pack_key_length=_mi_pack_key(info,(uint) inx, key_buff, (uchar*) key,
-				 key_len, &last_used_keyseg);
+				 keypart_map, &last_used_keyseg);
     /* Save packed_key_length for use by the MERGE engine. */
     info->pack_key_length= pack_key_length;
     DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE, keyinfo->seg,

--- 1.97/storage/myisam/myisamdef.h	2007-01-29 10:40:34 +01:00
+++ 1.98/storage/myisam/myisamdef.h	2007-01-29 10:40:34 +01:00
@@ -604,8 +604,9 @@ extern int _mi_dispose(MI_INFO *info,MI_
 extern my_off_t _mi_new(MI_INFO *info,MI_KEYDEF *keyinfo,int level);
 extern uint _mi_make_key(MI_INFO *info,uint keynr,uchar *key,
 			 const byte *record,my_off_t filepos);
-extern uint _mi_pack_key(MI_INFO *info,uint keynr,uchar *key,uchar *old,
-			 uint key_length, HA_KEYSEG **last_used_keyseg);
+extern uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key,
+                         uchar *old, ulonglong keypart_map,
+                         HA_KEYSEG **last_used_keyseg);
 extern int _mi_read_key_record(MI_INFO *info,my_off_t filepos,byte *buf);
 extern int _mi_read_cache(IO_CACHE *info,byte *buff,my_off_t pos,
 			  uint length,int re_read_if_possibly);

--- 1.106/storage/heap/ha_heap.cc	2007-01-29 10:40:34 +01:00
+++ 1.107/storage/heap/ha_heap.cc	2007-01-29 10:40:34 +01:00
@@ -238,34 +238,35 @@ int ha_heap::delete_row(const byte * buf
   return res;
 }
 
-int ha_heap::index_read(byte * buf, const byte * key, uint key_len,
+int ha_heap::index_read(byte * buf, const byte * key, ulonglong keypart_map,
 			enum ha_rkey_function find_flag)
 {
   DBUG_ASSERT(inited==INDEX);
   statistic_increment(table->in_use->status_var.ha_read_key_count,
 		      &LOCK_status);
-  int error = heap_rkey(file,buf,active_index, key, key_len, find_flag);
+  int error = heap_rkey(file,buf,active_index, key, keypart_map, find_flag);
   table->status = error ? STATUS_NOT_FOUND : 0;
   return error;
 }
 
-int ha_heap::index_read_last(byte *buf, const byte *key, uint key_len)
+int ha_heap::index_read_last(byte *buf, const byte *key, ulonglong keypart_map)
 {
   DBUG_ASSERT(inited==INDEX);
   statistic_increment(table->in_use->status_var.ha_read_key_count,
 		      &LOCK_status);
-  int error= heap_rkey(file, buf, active_index, key, key_len,
+  int error= heap_rkey(file, buf, active_index, key, keypart_map,
 		       HA_READ_PREFIX_LAST);
   table->status= error ? STATUS_NOT_FOUND : 0;
   return error;
 }
 
 int ha_heap::index_read_idx(byte * buf, uint index, const byte * key,
-			    uint key_len, enum ha_rkey_function find_flag)
+			    ulonglong keypart_map,
+                            enum ha_rkey_function find_flag)
 {
   statistic_increment(table->in_use->status_var.ha_read_key_count,
 		      &LOCK_status);
-  int error = heap_rkey(file, buf, index, key, key_len, find_flag);
+  int error = heap_rkey(file, buf, index, key, keypart_map, find_flag);
   table->status = error ? STATUS_NOT_FOUND : 0;
   return error;
 }

--- 1.50/storage/heap/ha_heap.h	2007-01-29 10:40:34 +01:00
+++ 1.51/storage/heap/ha_heap.h	2007-01-29 10:40:34 +01:00
@@ -75,11 +75,11 @@ public:
                                   ulonglong nb_desired_values,
                                   ulonglong *first_value,
                                   ulonglong *nb_reserved_values);
-  int index_read(byte * buf, const byte * key,
-		 uint key_len, enum ha_rkey_function find_flag);
-  int index_read_idx(byte * buf, uint idx, const byte * key,
-		     uint key_len, enum ha_rkey_function find_flag);
-  int index_read_last(byte * buf, const byte * key, uint key_len);
+  int index_read(byte * buf, const byte * key, ulonglong keypart_map,
+                 enum ha_rkey_function find_flag);
+  int index_read_last(byte *buf, const byte *key, ulonglong keypart_map);
+  int index_read_idx(byte * buf, uint index, const byte * key,
+                     ulonglong keypart_map, enum ha_rkey_function find_flag);
   int index_next(byte * buf);
   int index_prev(byte * buf);
   int index_first(byte * buf);

--- 1.206/storage/myisam/ha_myisam.cc	2007-01-29 10:40:34 +01:00
+++ 1.207/storage/myisam/ha_myisam.cc	2007-01-29 10:40:35 +01:00
@@ -1203,34 +1203,37 @@ int ha_myisam::delete_row(const byte * b
   return mi_delete(file,buf);
 }
 
-int ha_myisam::index_read(byte * buf, const byte * key,
-			  uint key_len, enum ha_rkey_function find_flag)
+int ha_myisam::index_read(byte *buf, const byte *key, ulonglong keypart_map,
+                          enum ha_rkey_function find_flag)
 {
   DBUG_ASSERT(inited==INDEX);
   statistic_increment(table->in_use->status_var.ha_read_key_count,
 		      &LOCK_status);
-  int error=mi_rkey(file,buf,active_index, key, key_len, find_flag);
+  int error=mi_rkey(file, buf, active_index, key, keypart_map, find_flag);
   table->status=error ? STATUS_NOT_FOUND: 0;
   return error;
 }
 
-int ha_myisam::index_read_idx(byte * buf, uint index, const byte * key,
-			      uint key_len, enum ha_rkey_function find_flag)
+int ha_myisam::index_read_idx(byte *buf, uint index, const byte *key,
+                              ulonglong keypart_map,
+                              enum ha_rkey_function find_flag)
 {
   statistic_increment(table->in_use->status_var.ha_read_key_count,
 		      &LOCK_status);
-  int error=mi_rkey(file,buf,index, key, key_len, find_flag);
+  int error=mi_rkey(file, buf, index, key, keypart_map, find_flag);
   table->status=error ? STATUS_NOT_FOUND: 0;
   return error;
 }
 
-int ha_myisam::index_read_last(byte * buf, const byte * key, uint key_len)
+int ha_myisam::index_read_last(byte *buf, const byte *key,
+                               ulonglong keypart_map)
 {
   DBUG_ENTER("ha_myisam::index_read_last");
   DBUG_ASSERT(inited==INDEX);
   statistic_increment(table->in_use->status_var.ha_read_key_count,
 		      &LOCK_status);
-  int error=mi_rkey(file,buf,active_index, key, key_len, HA_READ_PREFIX_LAST);
+  int error=mi_rkey(file, buf, active_index, key, keypart_map,
+                    HA_READ_PREFIX_LAST);
   table->status=error ? STATUS_NOT_FOUND: 0;
   DBUG_RETURN(error);
 }
@@ -1338,7 +1341,7 @@ int ha_myisam::info(uint flag)
     stats.index_file_length=info.index_file_length;
     stats.delete_length = info.delete_length;
     stats.check_time  = info.check_time;
-    stats. mean_rec_length=info.mean_reclength;
+    stats.mean_rec_length=info.mean_reclength;
   }
   if (flag & HA_STATUS_CONST)
   {
@@ -1698,8 +1701,9 @@ void ha_myisam::get_auto_increment(ulong
   key_copy(key, table->record[0],
            table->key_info + table->s->next_number_index,
            table->s->next_number_key_offset);
-  error= mi_rkey(file,table->record[1],(int) table->s->next_number_index,
-                 key,table->s->next_number_key_offset,HA_READ_PREFIX_LAST);
+  error= mi_rkey(file, table->record[1], (int) table->s->next_number_index,
+                 key, make_prev_keypart_map(table->s->next_number_keypart),
+                 HA_READ_PREFIX_LAST);
   if (error)
     nr= 1;
   else

--- 1.81/storage/myisam/ha_myisam.h	2007-01-29 10:40:35 +01:00
+++ 1.82/storage/myisam/ha_myisam.h	2007-01-29 10:40:35 +01:00
@@ -69,11 +69,11 @@ class ha_myisam: public handler
   int write_row(byte * buf);
   int update_row(const byte * old_data, byte * new_data);
   int delete_row(const byte * buf);
-  int index_read(byte * buf, const byte * key,
-		 uint key_len, enum ha_rkey_function find_flag);
-  int index_read_idx(byte * buf, uint idx, const byte * key,
-		     uint key_len, enum ha_rkey_function find_flag);
-  int index_read_last(byte * buf, const byte * key, uint key_len);
+  int index_read(byte *buf, const byte *key, ulonglong keypart_map,
+                 enum ha_rkey_function find_flag);
+  int index_read_idx(byte *buf, uint index, const byte *key,
+                     ulonglong keypart_map, enum ha_rkey_function find_flag);
+  int index_read_last(byte *buf, const byte *key, ulonglong keypart_map);
   int index_next(byte * buf);
   int index_prev(byte * buf);
   int index_first(byte * buf);

--- 1.111/storage/myisammrg/ha_myisammrg.cc	2007-01-29 10:40:35 +01:00
+++ 1.112/storage/myisammrg/ha_myisammrg.cc	2007-01-29 10:40:35 +01:00
@@ -145,30 +145,33 @@ int ha_myisammrg::delete_row(const byte 
 }
 
 int ha_myisammrg::index_read(byte * buf, const byte * key,
-			  uint key_len, enum ha_rkey_function find_flag)
+                             ulonglong keypart_map,
+                             enum ha_rkey_function find_flag)
 {
   statistic_increment(table->in_use->status_var.ha_read_key_count,
 		      &LOCK_status);
-  int error=myrg_rkey(file,buf,active_index, key, key_len, find_flag);
+  int error=myrg_rkey(file,buf,active_index, key, keypart_map, find_flag);
   table->status=error ? STATUS_NOT_FOUND: 0;
   return error;
 }
 
 int ha_myisammrg::index_read_idx(byte * buf, uint index, const byte * key,
-				 uint key_len, enum ha_rkey_function find_flag)
+				 ulonglong keypart_map,
+                                 enum ha_rkey_function find_flag)
 {
   statistic_increment(table->in_use->status_var.ha_read_key_count,
 		      &LOCK_status);
-  int error=myrg_rkey(file,buf,index, key, key_len, find_flag);
+  int error=myrg_rkey(file,buf,index, key, keypart_map, find_flag);
   table->status=error ? STATUS_NOT_FOUND: 0;
   return error;
 }
 
-int ha_myisammrg::index_read_last(byte * buf, const byte * key, uint key_len)
+int ha_myisammrg::index_read_last(byte * buf, const byte * key,
+                                  ulonglong keypart_map)
 {
   statistic_increment(table->in_use->status_var.ha_read_key_count,
 		      &LOCK_status);
-  int error=myrg_rkey(file,buf,active_index, key, key_len,
+  int error=myrg_rkey(file,buf,active_index, key, keypart_map,
 		      HA_READ_PREFIX_LAST);
   table->status=error ? STATUS_NOT_FOUND: 0;
   return error;

--- 1.49/storage/myisammrg/ha_myisammrg.h	2007-01-29 10:40:35 +01:00
+++ 1.50/storage/myisammrg/ha_myisammrg.h	2007-01-29 10:40:35 +01:00
@@ -56,11 +56,11 @@ class ha_myisammrg: public handler
   int write_row(byte * buf);
   int update_row(const byte * old_data, byte * new_data);
   int delete_row(const byte * buf);
-  int index_read(byte * buf, const byte * key,
-		 uint key_len, enum ha_rkey_function find_flag);
-  int index_read_idx(byte * buf, uint idx, const byte * key,
-		     uint key_len, enum ha_rkey_function find_flag);
-  int index_read_last(byte * buf, const byte * key, uint key_len);
+  int index_read(byte * buf, const byte * key, ulonglong keypart_map,
+                 enum ha_rkey_function find_flag);
+  int index_read_idx(byte * buf, uint index, const byte * key,
+                     ulonglong keypart_map, enum ha_rkey_function find_flag);
+  int index_read_last(byte * buf, const byte * key, ulonglong keypart_map);
   int index_next(byte * buf);
   int index_prev(byte * buf);
   int index_first(byte * buf);

--- 1.291/sql/handler.cc	2007-01-29 10:40:35 +01:00
+++ 1.292/sql/handler.cc	2007-01-29 10:40:35 +01:00
@@ -48,8 +48,6 @@ KEY_CREATE_INFO default_key_create_info=
 
 static handler *create_default(TABLE_SHARE *table, MEM_ROOT *mem_root);
 
-static SHOW_COMP_OPTION have_yes= SHOW_OPTION_YES;
-
 /* number of entries in handlertons[] */
 ulong total_ha= 0;
 /* number of storage engines (from handlertons[]) that support 2pc */
@@ -1854,7 +1852,7 @@ int handler::update_auto_increment()
       nr= compute_next_insert_id(nr-1, variables);
     }
     
-    if (table->s->next_number_key_offset == 0)
+    if (table->s->next_number_keypart == 0)
     {
       /* We must defer the appending until "nr" has been possibly truncated */
       append= TRUE;
@@ -1976,7 +1974,7 @@ void handler::get_auto_increment(ulonglo
                                         table->read_set);
   column_bitmaps_signal();
   index_init(table->s->next_number_index, 1);
-  if (!table->s->next_number_key_offset)
+  if (table->s->next_number_keypart == 0)
   {						// Autoincrement at key-start
     error=index_last(table->record[1]);
     /*
@@ -1992,7 +1990,8 @@ void handler::get_auto_increment(ulonglo
     key_copy(key, table->record[0],
              table->key_info + table->s->next_number_index,
              table->s->next_number_key_offset);
-    error= index_read(table->record[1], key, table->s->next_number_key_offset,
+    error= index_read(table->record[1], key,
+                      make_prev_keypart_map(table->s->next_number_keypart),
                       HA_READ_PREFIX_LAST);
     /*
       MySQL needs to call us for next row: assume we are inserting ("a",null)
@@ -3103,9 +3102,9 @@ int handler::read_multi_range_first(KEY_
        multi_range_curr < multi_range_end;
        multi_range_curr++)
   {
-    result= read_range_first(multi_range_curr->start_key.length ?
+    result= read_range_first(multi_range_curr->start_key.keypart_map ?
                              &multi_range_curr->start_key : 0,
-                             multi_range_curr->end_key.length ?
+                             multi_range_curr->end_key.keypart_map ?
                              &multi_range_curr->end_key : 0,
                              test(multi_range_curr->range_flag & EQ_RANGE),
                              multi_range_sorted);
@@ -3171,9 +3170,9 @@ int handler::read_multi_range_next(KEY_M
          multi_range_curr < multi_range_end;
          multi_range_curr++)
     {
-      result= read_range_first(multi_range_curr->start_key.length ?
+      result= read_range_first(multi_range_curr->start_key.keypart_map ?
                                &multi_range_curr->start_key : 0,
-                               multi_range_curr->end_key.length ?
+                               multi_range_curr->end_key.keypart_map ?
                                &multi_range_curr->end_key : 0,
                                test(multi_range_curr->range_flag & EQ_RANGE),
                                multi_range_sorted);
@@ -3233,7 +3232,7 @@ int handler::read_range_first(const key_
   else
     result= index_read(table->record[0],
 		       start_key->key,
-		       start_key->length,
+                       start_key->keypart_map,
 		       start_key->flag);
   if (result)
     DBUG_RETURN((result == HA_ERR_KEY_NOT_FOUND) 
@@ -3307,15 +3306,19 @@ int handler::compare_key(key_range *rang
   return cmp;
 }
 
+
 int handler::index_read_idx(byte * buf, uint index, const byte * key,
-			     uint key_len, enum ha_rkey_function find_flag)
+                             ulonglong keypart_map,
+                             enum ha_rkey_function find_flag)
 {
-  int error= ha_index_init(index, 0);
-  if (!error)
-    error= index_read(buf, key, key_len, find_flag);
+  int error, error1;
+  error= index_init(index, 0);
   if (!error)
-    error= ha_index_end();
-  return error;
+  {
+    error= index_read(buf, key, keypart_map, find_flag);
+    error1= index_end();
+  }
+  return error ?  error : error1;
 }
 
 
@@ -3365,7 +3368,6 @@ static my_bool exts_handlerton(THD *unus
 
 TYPELIB *ha_known_exts(void)
 {
-  MEM_ROOT *mem_root= current_thd->mem_root;
   if (!known_extensions.type_names || mysys_usage_id != known_extensions_id)
   {
     List<char> found_exts;

--- 1.252/sql/handler.h	2007-01-29 10:40:35 +01:00
+++ 1.253/sql/handler.h	2007-01-29 10:40:35 +01:00
@@ -867,6 +867,18 @@ public:
   {}
 };
 
+uint calculate_key_len(TABLE *, uint, const byte *, ulonglong);
+/*
+  bitmap with first N+1 bits set
+  (keypart_map for a key prefix of [0..N] keyparts)
+*/
+#define make_keypart_map(N) (((ulonglong)2 << (N)) - 1)
+/*
+  bitmap with first N bits set
+  (keypart_map for a key prefix of [0..N-1] keyparts)
+*/
+#define make_prev_keypart_map(N) (((ulonglong)1 << (N)) - 1)
+
 /*
   The handler class is the interface for dynamically loadable
   storage engines. Do not add ifdefs and take care when adding or
@@ -1202,11 +1214,20 @@ public:
     DBUG_ASSERT(FALSE);
     return HA_ERR_WRONG_COMMAND;
   }
-  virtual int index_read(byte * buf, const byte * key,
-			 uint key_len, enum ha_rkey_function find_flag)
+  private:
+  virtual int index_read(byte * buf, const byte * key, uint key_len,
+                         enum ha_rkey_function find_flag)
    { return  HA_ERR_WRONG_COMMAND; }
+  public:
+  virtual int index_read(byte * buf, const byte * key, ulonglong keypart_map,
+                         enum ha_rkey_function find_flag)
+   {
+     uint key_len= calculate_key_len(table, active_index, key, keypart_map);
+     return  index_read(buf, key, key_len, find_flag);
+   }
   virtual int index_read_idx(byte * buf, uint index, const byte * key,
-			     uint key_len, enum ha_rkey_function find_flag);
+                             ulonglong keypart_map,
+                             enum ha_rkey_function find_flag);
   virtual int index_next(byte * buf)
    { return  HA_ERR_WRONG_COMMAND; }
   virtual int index_prev(byte * buf)
@@ -1216,8 +1237,16 @@ public:
   virtual int index_last(byte * buf)
    { return  HA_ERR_WRONG_COMMAND; }
   virtual int index_next_same(byte *buf, const byte *key, uint keylen);
+  private:
   virtual int index_read_last(byte * buf, const byte * key, uint key_len)
    { return (my_errno=HA_ERR_WRONG_COMMAND); }
+  public:
+  virtual int index_read_last(byte * buf, const byte * key,
+                              ulonglong keypart_map)
+   {
+     uint key_len= calculate_key_len(table, active_index, key, keypart_map);
+     return  index_read_last(buf, key, key_len);
+   }
   virtual int read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
                                      KEY_MULTI_RANGE *ranges, uint range_count,
                                      bool sorted, HANDLER_BUFFER *buffer);
@@ -1243,8 +1272,7 @@ public:
     { return HA_ERR_WRONG_COMMAND; }
   virtual int rnd_same(byte *buf, uint inx)
     { return HA_ERR_WRONG_COMMAND; }
-  virtual ha_rows records_in_range(uint inx, key_range *min_key,
-                                   key_range *max_key)
+  virtual ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key)
     { return (ha_rows) 10; }
   virtual void position(const byte *record)=0;
   virtual int info(uint)=0; // see my_base.h for full description

--- 1.48/sql/key.cc	2007-01-29 10:40:35 +01:00
+++ 1.49/sql/key.cc	2007-01-29 10:40:35 +01:00
@@ -29,6 +29,7 @@
     field		Field to search after
     key_length		On partial match, contains length of fields before
 			field
+    keypart             key part # of a field
 
   NOTES
    Used when calculating key for NEXT_NUMBER
@@ -45,7 +46,7 @@
 */
 
 int find_ref_key(KEY *key, uint key_count, byte *record, Field *field,
-                 uint *key_length)
+                 uint *key_length, uint *keypart)
 {
   reg2 int i;
   reg3 KEY *key_info;
@@ -60,8 +61,8 @@ int find_ref_key(KEY *key, uint key_coun
   {
     if (key_info->key_part[0].offset == fieldpos)
     {                                  		/* Found key. Calc keylength */
-      *key_length=0;
-      return(i);                                /* Use this key */
+      *key_length= *keypart= 0;
+      return i;                                 /* Use this key */
     }
   }
 
@@ -78,8 +79,11 @@ int find_ref_key(KEY *key, uint key_coun
 	 j++, key_part++)
     {
       if (key_part->offset == fieldpos)
-	return(i);                              /* Use this key */
-      *key_length+=key_part->store_length;
+      {
+        *keypart= j;
+        return i;                               /* Use this key */
+      }
+      *key_length+= key_part->store_length;
     }
   }
   return(-1);					/* No key is ok */

--- 1.253/sql/log.cc	2007-01-29 10:40:35 +01:00
+++ 1.254/sql/log.cc	2007-01-29 10:40:35 +01:00
@@ -3787,7 +3787,7 @@ bool MYSQL_BIN_LOG::write(Log_event *eve
                              nb_elements()));
           /*
             If the auto_increment was second in a table's index (possible with
-            MyISAM or BDB) (table->next_number_key_offset != 0), such event is
+            MyISAM or BDB) (table->next_number_keypart != 0), such event is
             in fact not necessary. We could avoid logging it.
           */
           Intvar_log_event e(thd, (uchar) INSERT_ID_EVENT,

--- 1.263/sql/log_event.cc	2007-01-29 10:40:35 +01:00
+++ 1.264/sql/log_event.cc	2007-01-29 10:40:35 +01:00
@@ -6720,9 +6720,8 @@ replace_record(THD *thd, TABLE *table,
       }
 
       key_copy((byte*)key.get(), table->record[0], table->key_info + keynum, 0);
-      error= table->file->index_read_idx(table->record[1], keynum, 
-                                         (const byte*)key.get(),
-                                         table->key_info[keynum].key_length,
+      error= table->file->index_read_idx(table->record[1], keynum,
+                                         (const byte*)key.get(), ~ULL(0),
                                          HA_READ_KEY_EXACT);
       if (error)
         DBUG_RETURN(error);
@@ -6907,8 +6906,7 @@ static int find_and_fetch_row(TABLE *tab
       table->s->null_bytes > 0 ? table->s->null_bytes - 1 : 0;
     table->record[1][pos]= 0xFF;
     if ((error= table->file->index_read(table->record[1], key,
-                                        table->key_info->key_length,
-                                        HA_READ_KEY_EXACT)))
+                                        ~(ulonglong)0, HA_READ_KEY_EXACT)))
     {
       table->file->print_error(error, MYF(0));
       table->file->ha_index_end();

--- 1.473/sql/mysql_priv.h	2007-01-29 10:40:35 +01:00
+++ 1.474/sql/mysql_priv.h	2007-01-29 10:40:35 +01:00
@@ -1445,7 +1445,7 @@ void print_plan(JOIN* join,uint idx, dou
 void mysql_print_status();
 /* key.cc */
 int find_ref_key(KEY *key, uint key_count, byte *record, Field *field,
-                 uint *key_length);
+                 uint *key_length, uint *keypart);
 void key_copy(byte *to_key, byte *from_record, KEY *key_info, uint key_length);
 void key_restore(byte *to_record, byte *from_key, KEY *key_info,
                  uint key_length);

--- 1.258/sql/opt_range.cc	2007-01-29 10:40:35 +01:00
+++ 1.259/sql/opt_range.cc	2007-01-29 10:40:35 +01:00
@@ -310,7 +310,7 @@ public:
     min_value=arg->max_value;
     min_flag=arg->max_flag & NEAR_MAX ? 0 : NEAR_MIN;
   }
-  void store_min(uint length,char **min_key,uint min_key_flag)
+  int store_min(uint length,char **min_key,uint min_key_flag)
   {
     if ((min_flag & GEOM_FLAG) ||
         (!(min_flag & NO_MIN_RANGE) &&
@@ -324,12 +324,12 @@ public:
       else
 	memcpy(*min_key,min_value,length);
       (*min_key)+= length;
+      return 1;
     }
+    return 0;
   }
-  void store(uint length,char **min_key,uint min_key_flag,
-	     char **max_key, uint max_key_flag)
+  int store_max(uint length,char **max_key, uint max_key_flag)
   {
-    store_min(length, min_key, min_key_flag);
     if (!(max_flag & NO_MAX_RANGE) &&
 	!(max_key_flag & (NO_MAX_RANGE | NEAR_MAX)))
     {
@@ -341,33 +341,45 @@ public:
       else
 	memcpy(*max_key,max_value,length);
       (*max_key)+= length;
+      return 1;
     }
+    return 0;
   }
+  /*void store(uint length,char **min_key,uint min_key_flag,
+	     char **max_key, uint max_key_flag)
+  {
+    store_min(length, min_key, min_key_flag);
+    store_max(length, max_key, max_key_flag);
+  }*/
 
-  void store_min_key(KEY_PART *key,char **range_key, uint *range_key_flag)
+  int store_min_key(KEY_PART *key,char **range_key, uint *range_key_flag)
   {
     SEL_ARG *key_tree= first();
-    key_tree->store(key[key_tree->part].store_length,
-		    range_key,*range_key_flag,range_key,NO_MAX_RANGE);
+    uint res= key_tree->store_min(key[key_tree->part].store_length,
+                                  range_key, *range_key_flag);
     *range_key_flag|= key_tree->min_flag;
     if (key_tree->next_key_part &&
 	key_tree->next_key_part->part == key_tree->part+1 &&
 	!(*range_key_flag & (NO_MIN_RANGE | NEAR_MIN)) &&
 	key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
-      key_tree->next_key_part->store_min_key(key,range_key, range_key_flag);
+      res+= key_tree->next_key_part->store_min_key(key, range_key,
+                                                   range_key_flag);
+    return res;
   }
 
-  void store_max_key(KEY_PART *key,char **range_key, uint *range_key_flag)
+  int store_max_key(KEY_PART *key,char **range_key, uint *range_key_flag)
   {
     SEL_ARG *key_tree= last();
-    key_tree->store(key[key_tree->part].store_length,
-		    range_key, NO_MIN_RANGE, range_key,*range_key_flag);
+    uint res=key_tree->store_max(key[key_tree->part].store_length,
+                                 range_key, *range_key_flag);
     (*range_key_flag)|= key_tree->max_flag;
     if (key_tree->next_key_part &&
 	key_tree->next_key_part->part == key_tree->part+1 &&
 	!(*range_key_flag & (NO_MAX_RANGE | NEAR_MAX)) &&
 	key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
-      key_tree->next_key_part->store_max_key(key,range_key, range_key_flag);
+      res+= key_tree->next_key_part->store_max_key(key, range_key,
+                                                   range_key_flag);
+    return res;
   }
 
   SEL_ARG *insert(SEL_ARG *key);
@@ -583,8 +595,8 @@ static bool is_key_scan_ror(PARAM *param
 static ha_rows check_quick_select(PARAM *param,uint index,SEL_ARG *key_tree, 
                                   bool update_tbl_stats);
 static ha_rows check_quick_keys(PARAM *param,uint index,SEL_ARG *key_tree,
-				char *min_key,uint min_key_flag,
-				char *max_key, uint max_key_flag);
+                                char *min_key, uint min_key_flag, int,
+                                char *max_key, uint max_key_flag, int);
 
 QUICK_RANGE_SELECT *get_quick_select(PARAM *param,uint index,
                                      SEL_ARG *key_tree,
@@ -606,9 +618,6 @@ TABLE_READ_PLAN *get_best_disjunct_quick
                                          double read_time);
 static
 TRP_GROUP_MIN_MAX *get_best_group_min_max(PARAM *param, SEL_TREE *tree);
-static int get_index_merge_params(PARAM *param, key_map& needed_reg,
-                           SEL_IMERGE *imerge, double *read_time,
-                           ha_rows* imerge_rows);
 static double get_index_only_read_time(const PARAM* param, ha_rows records,
                                        int keynr);
 
@@ -1455,6 +1464,7 @@ QUICK_ROR_UNION_SELECT::~QUICK_ROR_UNION
 
 QUICK_RANGE::QUICK_RANGE()
   :min_key(0),max_key(0),min_length(0),max_length(0),
+  min_keypart_map(0), max_keypart_map(0),
    flag(NO_MIN_RANGE | NO_MAX_RANGE)
 {}
 
@@ -2425,8 +2435,6 @@ static int find_used_partitions_imerge(P
 static int find_used_partitions_imerge_list(PART_PRUNE_PARAM *ppar,
                                             List<SEL_IMERGE> &merges);
 static void mark_all_partitions_as_used(partition_info *part_info);
-static uint32 part_num_to_part_id_range(PART_PRUNE_PARAM* prune_par, 
-                                        uint32 num);
 
 #ifndef DBUG_OFF
 static void print_partitioning_index(KEY_PART *parts, KEY_PART *parts_end);
@@ -4035,9 +4043,9 @@ void ror_intersect_cpy(ROR_INTERSECT_INF
     The calculation is conducted as follows:
     Lets denote #records(keypart1, ... keypartK) as n_k. We need to calculate
 
-     n_{k1}      n_{k_2}
+     n_{k1}      n_{k2}
     --------- * ---------  * .... (3)
-     n_{k1-1}    n_{k2_1}
+     n_{k1-1}    n_{k2-1}
 
     where k1,k2,... are key parts which fields were not yet marked as fixed
     ( this is result of application of option b) of the recursion step for
@@ -4045,9 +4053,9 @@ void ror_intersect_cpy(ROR_INTERSECT_INF
     Since it is reasonable to expect that most of the fields are not marked
     as fixed, we calculate (3) as
 
-                                  n_{i1}      n_{i_2}
+                                  n_{i1}      n_{i2}
     (3) = n_{max_key_part}  / (   --------- * ---------  * ....  )
-                                  n_{i1-1}    n_{i2_1}
+                                  n_{i1-1}    n_{i2-1}
 
     where i1,i2, .. are key parts that were already marked as fixed.
 
@@ -4056,7 +4064,6 @@ void ror_intersect_cpy(ROR_INTERSECT_INF
 
   RETURN
     Selectivity of given ROR scan.
-    
 */
 
 static double ror_scan_selectivity(const ROR_INTERSECT_INFO *info, 
@@ -4067,6 +4074,7 @@ static double ror_scan_selectivity(const
   byte key_val[MAX_KEY_LENGTH+MAX_FIELD_WIDTH]; /* key values tuple */
   char *key_ptr= (char*) key_val;
   SEL_ARG *sel_arg, *tuple_arg= NULL;
+  ulonglong keypart_map= 0;
   bool cur_covered;
   bool prev_covered= test(bitmap_is_set(&info->covered_fields,
                                         key_part->fieldnr-1));
@@ -4077,7 +4085,7 @@ static double ror_scan_selectivity(const
   max_range.key= (byte*) key_val;
   max_range.flag= HA_READ_AFTER_KEY;
   ha_rows prev_records= info->param->table->file->stats.records;
-  DBUG_ENTER("ror_intersect_selectivity");
+  DBUG_ENTER("ror_scan_selectivity");
 
   for (sel_arg= scan->sel_arg; sel_arg;
        sel_arg= sel_arg->next_key_part)
@@ -4094,13 +4102,17 @@ static double ror_scan_selectivity(const
         tuple_arg= scan->sel_arg;
         /* Here we use the length of the first key part */
         tuple_arg->store_min(key_part->store_length, &key_ptr, 0);
+        keypart_map= 1;
       }
       while (tuple_arg->next_key_part != sel_arg)
       {
         tuple_arg= tuple_arg->next_key_part;
-        tuple_arg->store_min(key_part[tuple_arg->part].store_length, &key_ptr,
0);
+        tuple_arg->store_min(key_part[tuple_arg->part].store_length,
+                             &key_ptr, 0);
+        keypart_map= (keypart_map << 1) | 1;
       }
       min_range.length= max_range.length= ((char*) key_ptr - (char*) key_val);
+      min_range.keypart_map= max_range.keypart_map= keypart_map;
       records= (info->param->table->file->
                 records_in_range(scan->keynr, &min_range, &max_range));
       if (cur_covered)
@@ -5310,12 +5322,11 @@ static SEL_TREE *get_mm_tree(RANGE_OPT_P
     */
     for (uint i= 1 ; i < cond_func->arg_count ; i++)
     {
-     
       if (cond_func->arguments()[i]->real_item()->type() == Item::FIELD_ITEM)
       {
         field_item= (Item_field*) (cond_func->arguments()[i]->real_item());
         SEL_TREE *tmp= get_full_func_mm_tree(param, cond_func, 
-                                    field_item, (Item*) i, inv);
+                                    field_item, (Item*)(intptr)i, inv);
         if (inv)
           tree= !tree ? tmp : tree_or(param, tree, tmp);
         else 
@@ -7046,7 +7057,9 @@ check_quick_select(PARAM *param,uint idx
   }
   param->n_ranges= 0;
 
-  records=check_quick_keys(param,idx,tree,param->min_key,0,param->max_key,0);
+  records= check_quick_keys(param, idx, tree,
+                            param->min_key, 0, -1,
+                            param->max_key, 0, -1);
   if (records != HA_POS_ERROR)
   {
     if (update_tbl_stats)
@@ -7109,12 +7122,13 @@ check_quick_select(PARAM *param,uint idx
 */
 
 static ha_rows
-check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree,
-		 char *min_key,uint min_key_flag, char *max_key,
-		 uint max_key_flag)
+check_quick_keys(PARAM *param, uint idx, SEL_ARG *key_tree,
+		 char *min_key, uint min_key_flag, int min_keypart,
+                 char *max_key, uint max_key_flag, int max_keypart)
 {
   ha_rows records=0, tmp;
   uint tmp_min_flag, tmp_max_flag, keynr, min_key_length, max_key_length;
+  uint tmp_min_keypart= min_keypart, tmp_max_keypart= max_keypart;
   char *tmp_min_key, *tmp_max_key;
 
   param->max_key_part=max(param->max_key_part,key_tree->part);
@@ -7127,18 +7141,21 @@ check_quick_keys(PARAM *param,uint idx,S
       This is not a ROR scan if the key is not Clustered Primary Key.
     */
     param->is_ror_scan= FALSE;
-    records=check_quick_keys(param,idx,key_tree->left,min_key,min_key_flag,
-			     max_key,max_key_flag);
+    records=check_quick_keys(param, idx, key_tree->left,
+                             min_key, min_key_flag, min_keypart,
+			     max_key, max_key_flag, max_keypart);
     if (records == HA_POS_ERROR)			// Impossible
       return records;
   }
 
   tmp_min_key= min_key;
   tmp_max_key= max_key;
-  key_tree->store(param->key[idx][key_tree->part].store_length,
-		  &tmp_min_key,min_key_flag,&tmp_max_key,max_key_flag);
-  min_key_length= (uint) (tmp_min_key- param->min_key);
-  max_key_length= (uint) (tmp_max_key- param->max_key);
+  tmp_min_keypart+=
key_tree->store_min(param->key[idx][key_tree->part].store_length,
+                                        &tmp_min_key, min_key_flag);
+  tmp_max_keypart+=
key_tree->store_max(param->key[idx][key_tree->part].store_length,
+                                        &tmp_max_key, max_key_flag);
+  min_key_length= (uint) (tmp_min_key - param->min_key);
+  max_key_length= (uint) (tmp_max_key - param->max_key);
 
   if (param->is_ror_scan)
   {
@@ -7158,12 +7175,13 @@ check_quick_keys(PARAM *param,uint idx,S
       key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
   {						// const key as prefix
     if (min_key_length == max_key_length &&
-	!memcmp(min_key,max_key, (uint) (tmp_max_key - max_key)) &&
+	!memcmp(min_key, max_key, (uint) (tmp_max_key - max_key)) &&
 	!key_tree->min_flag && !key_tree->max_flag)
     {
-      tmp=check_quick_keys(param,idx,key_tree->next_key_part,
-			   tmp_min_key, min_key_flag | key_tree->min_flag,
-			   tmp_max_key, max_key_flag | key_tree->max_flag);
+      tmp=check_quick_keys(param,idx,key_tree->next_key_part, tmp_min_key,
+                           min_key_flag | key_tree->min_flag, tmp_min_keypart,
+                           tmp_max_key, max_key_flag | key_tree->max_flag,
+                           tmp_max_keypart);
       goto end;					// Ugly, but efficient
     }
     else
@@ -7175,18 +7193,20 @@ check_quick_keys(PARAM *param,uint idx,S
     tmp_min_flag=key_tree->min_flag;
     tmp_max_flag=key_tree->max_flag;
     if (!tmp_min_flag)
+      tmp_min_keypart+=
       key_tree->next_key_part->store_min_key(param->key[idx], &tmp_min_key,
 					     &tmp_min_flag);
     if (!tmp_max_flag)
+      tmp_max_keypart+=
       key_tree->next_key_part->store_max_key(param->key[idx], &tmp_max_key,
 					     &tmp_max_flag);
-    min_key_length= (uint) (tmp_min_key- param->min_key);
-    max_key_length= (uint) (tmp_max_key- param->max_key);
+    min_key_length= (uint) (tmp_min_key - param->min_key);
+    max_key_length= (uint) (tmp_max_key - param->max_key);
   }
   else
   {
-    tmp_min_flag=min_key_flag | key_tree->min_flag;
-    tmp_max_flag=max_key_flag | key_tree->max_flag;
+    tmp_min_flag= min_key_flag | key_tree->min_flag;
+    tmp_max_flag= max_key_flag | key_tree->max_flag;
   }
 
   keynr=param->real_keynr[idx];
@@ -7194,9 +7214,8 @@ check_quick_keys(PARAM *param,uint idx,S
   if (!tmp_min_flag && ! tmp_max_flag &&
       (uint) key_tree->part+1 == param->table->key_info[keynr].key_parts
&&
       (param->table->key_info[keynr].flags & (HA_NOSAME | HA_END_SPACE_KEY)) ==
-      HA_NOSAME &&
-      min_key_length == max_key_length &&
-      !memcmp(param->min_key,param->max_key,min_key_length))
+      HA_NOSAME && min_key_length == max_key_length &&
+      !memcmp(param->min_key, param->max_key, min_key_length))
   {
     tmp=1;					// Max one record
     param->n_ranges++;
@@ -7215,7 +7234,7 @@ check_quick_keys(PARAM *param,uint idx,S
           first members of clustered primary key.
       */
       if (!(min_key_length == max_key_length &&
-            !memcmp(min_key,max_key, (uint) (tmp_max_key - max_key)) &&
+            !memcmp(min_key, max_key, (uint) (tmp_max_key - max_key)) &&
             !key_tree->min_flag && !key_tree->max_flag &&
             is_key_scan_ror(param, keynr, key_tree->part + 1)))
         param->is_ror_scan= FALSE;
@@ -7227,11 +7246,12 @@ check_quick_keys(PARAM *param,uint idx,S
       key_range min_range;
       min_range.key=    (byte*) param->min_key;
       min_range.length= min_key_length;
+      min_range.keypart_map= make_keypart_map(tmp_min_keypart);
       /* In this case tmp_min_flag contains the handler-read-function */
       min_range.flag=   (ha_rkey_function) (tmp_min_flag ^ GEOM_FLAG);
 
-      tmp= param->table->file->records_in_range(keynr, &min_range,
-                                                (key_range*) 0);
+      tmp= param->table->file->records_in_range(keynr,
+                                                &min_range, (key_range*) 0);
     }
     else
     {
@@ -7241,10 +7261,12 @@ check_quick_keys(PARAM *param,uint idx,S
       min_range.length= min_key_length;
       min_range.flag=   (tmp_min_flag & NEAR_MIN ? HA_READ_AFTER_KEY :
                          HA_READ_KEY_EXACT);
+      min_range.keypart_map= make_keypart_map(tmp_min_keypart);
       max_range.key=    (byte*) param->max_key;
       max_range.length= max_key_length;
       max_range.flag=   (tmp_max_flag & NEAR_MAX ?
                          HA_READ_BEFORE_KEY : HA_READ_AFTER_KEY);
+      max_range.keypart_map= make_keypart_map(tmp_max_keypart);
       tmp=param->table->file->records_in_range(keynr,
                                                (min_key_length ? &min_range :
                                                 (key_range*) 0),
@@ -7265,8 +7287,9 @@ check_quick_keys(PARAM *param,uint idx,S
       This is not a ROR scan if the key is not Clustered Primary Key.
     */
     param->is_ror_scan= FALSE;
-    tmp=check_quick_keys(param,idx,key_tree->right,min_key,min_key_flag,
-			 max_key,max_key_flag);
+    tmp=check_quick_keys(param, idx, key_tree->right,
+                         min_key, min_key_flag, min_keypart,
+                         max_key, max_key_flag, max_keypart);
     if (tmp == HA_POS_ERROR)
       return tmp;
     records+=tmp;
@@ -7412,6 +7435,7 @@ get_quick_keys(PARAM *param,QUICK_RANGE_
 {
   QUICK_RANGE *range;
   uint flag;
+  int min_part= key_tree->part-1, max_part=key_tree->part-1;
 
   if (key_tree->left != &null_element)
   {
@@ -7420,16 +7444,18 @@ get_quick_keys(PARAM *param,QUICK_RANGE_
       return 1;
   }
   char *tmp_min_key=min_key,*tmp_max_key=max_key;
-  key_tree->store(key[key_tree->part].store_length,
-		  &tmp_min_key,min_key_flag,&tmp_max_key,max_key_flag);
+  min_part+= key_tree->store_min(key[key_tree->part].store_length,
+                                 &tmp_min_key,min_key_flag);
+  max_part+= key_tree->store_max(key[key_tree->part].store_length,
+                                 &tmp_max_key,max_key_flag);
 
   if (key_tree->next_key_part &&
       key_tree->next_key_part->part == key_tree->part+1 &&
       key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
   {						  // const key as prefix
-    if (!((tmp_min_key - min_key) != (tmp_max_key - max_key) ||
-	  memcmp(min_key,max_key, (uint) (tmp_max_key - max_key)) ||
-	  key_tree->min_flag || key_tree->max_flag))
+    if ((tmp_min_key - min_key) == (tmp_max_key - max_key) &&
+         memcmp(min_key, max_key, (uint)(tmp_max_key - max_key))==0 &&
+	 key_tree->min_flag==0 && key_tree->max_flag==0)
     {
       if (get_quick_keys(param,quick,key,key_tree->next_key_part,
 			 tmp_min_key, min_key_flag | key_tree->min_flag,
@@ -7440,11 +7466,15 @@ get_quick_keys(PARAM *param,QUICK_RANGE_
     {
       uint tmp_min_flag=key_tree->min_flag,tmp_max_flag=key_tree->max_flag;
       if (!tmp_min_flag)
-	key_tree->next_key_part->store_min_key(key, &tmp_min_key,
+      {
+        min_part+= key_tree->next_key_part->store_min_key(key, &tmp_min_key,
 					       &tmp_min_flag);
+      }
       if (!tmp_max_flag)
-	key_tree->next_key_part->store_max_key(key, &tmp_max_key,
+      {
+        max_part+= key_tree->next_key_part->store_max_key(key, &tmp_max_key,
 					       &tmp_max_flag);
+      }
       flag=tmp_min_flag | tmp_max_flag;
     }
   }
@@ -7494,13 +7524,15 @@ get_quick_keys(PARAM *param,QUICK_RANGE_
   /* Get range for retrieving rows in QUICK_SELECT::get_next */
   if (!(range= new QUICK_RANGE((const char *) param->min_key,
 			       (uint) (tmp_min_key - param->min_key),
+                               min_part >=0 ? make_keypart_map(min_part) : 0,
 			       (const char *) param->max_key,
 			       (uint) (tmp_max_key - param->max_key),
+                               max_part >=0 ? make_keypart_map(max_part) : 0,
 			       flag)))
     return 1;			// out of memory
 
-  set_if_bigger(quick->max_used_key_length,range->min_length);
-  set_if_bigger(quick->max_used_key_length,range->max_length);
+  set_if_bigger(quick->max_used_key_length, range->min_length);
+  set_if_bigger(quick->max_used_key_length, range->max_length);
   set_if_bigger(quick->used_key_parts, (uint) key_tree->part+1);
   if (insert_dynamic(&quick->ranges, (gptr)&range))
     return 1;
@@ -7642,6 +7674,7 @@ QUICK_RANGE_SELECT *get_quick_select_for
 
   range->min_key=range->max_key=(char*) ref->key_buff;
   range->min_length=range->max_length=ref->key_length;
+  range->min_keypart_map= range->max_keypart_map= (1 << ref->key_parts) -
1;
   range->flag= ((ref->key_length == key_info->key_length &&
 		 (key_info->flags & (HA_NOSAME | HA_END_SPACE_KEY)) ==
 		 HA_NOSAME) ? EQ_RANGE : 0);
@@ -7675,8 +7708,10 @@ QUICK_RANGE_SELECT *get_quick_select_for
     *ref->null_ref_key= 1;		// Set null byte then create a range
     if (!(null_range= new (alloc) QUICK_RANGE((char*)ref->key_buff,
                                               ref->key_length,
+                                              (1 << ref->key_parts) - 1,
                                               (char*)ref->key_buff,
                                               ref->key_length,
+                                              (1 << ref->key_parts) - 1,
                                               EQ_RANGE)))
       goto err;
     *ref->null_ref_key= 0;		// Clear null byte
@@ -8129,6 +8164,7 @@ int QUICK_RANGE_SELECT::get_next()
       start_key->flag=   ((range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
                           (range->flag & EQ_RANGE) ?
                           HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
+      start_key->keypart_map= range->min_keypart_map;
       end_key->key=      (const byte*) range->max_key;
       end_key->length=   range->max_length;
       /*
@@ -8137,6 +8173,7 @@ int QUICK_RANGE_SELECT::get_next()
       */
       end_key->flag=     (range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
                           HA_READ_AFTER_KEY);
+      end_key->keypart_map= range->max_keypart_map;
 
       mrange_slot->range_flag= range->flag;
     }
@@ -8186,7 +8223,9 @@ end:
     other              if some error occurred
 */
 
-int QUICK_RANGE_SELECT::get_next_prefix(uint prefix_length, byte *cur_prefix)
+int QUICK_RANGE_SELECT::get_next_prefix(uint prefix_length,
+                                        ulonglong keypart_map,
+                                        byte *cur_prefix)
 {
   DBUG_ENTER("QUICK_RANGE_SELECT::get_next_prefix");
 
@@ -8198,8 +8237,7 @@ int QUICK_RANGE_SELECT::get_next_prefix(
     {
       /* Read the next record in the same range with prefix after cur_prefix. */
       DBUG_ASSERT(cur_prefix != 0);
-      result= file->index_read(record, cur_prefix, prefix_length,
-                               HA_READ_AFTER_KEY);
+      result= file->index_read(record, cur_prefix, keypart_map, HA_READ_AFTER_KEY);
       if (result || (file->compare_key(file->end_range) <= 0))
         DBUG_RETURN(result);
     }
@@ -8215,11 +8253,13 @@ int QUICK_RANGE_SELECT::get_next_prefix(
 
     start_key.key=    (const byte*) range->min_key;
     start_key.length= min(range->min_length, prefix_length);
+    start_key.keypart_map= range->min_keypart_map & keypart_map;
     start_key.flag=   ((range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
 		       (range->flag & EQ_RANGE) ?
 		       HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
     end_key.key=      (const byte*) range->max_key;
     end_key.length=   min(range->max_length, prefix_length);
+    end_key.keypart_map= range->max_keypart_map & keypart_map;
     /*
       We use READ_AFTER_KEY here because if we are reading on a key
       prefix we want to find all keys with this prefix
@@ -8227,8 +8267,8 @@ int QUICK_RANGE_SELECT::get_next_prefix(
     end_key.flag=     (range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
 		       HA_READ_AFTER_KEY);
 
-    result= file->read_range_first(range->min_length ? &start_key : 0,
-				   range->max_length ? &end_key : 0,
+    result= file->read_range_first(range->min_keypart_map ? &start_key : 0,
+				   range->max_keypart_map ? &end_key : 0,
                                    test(range->flag & EQ_RANGE),
 				   sorted);
     if (range->flag == (UNIQUE_RANGE | EQ_RANGE))
@@ -8268,9 +8308,8 @@ int QUICK_RANGE_SELECT_GEOM::get_next()
     }
     range= *(cur_range++);
 
-    result= file->index_read(record,
-			     (byte*) range->min_key,
-			     range->min_length,
+    result= file->index_read(record, (byte*) range->min_key,
+			     range->min_keypart_map,
 			     (ha_rkey_function)(range->flag ^ GEOM_FLAG));
     if (result != HA_ERR_KEY_NOT_FOUND && result != HA_ERR_END_OF_FILE)
       DBUG_RETURN(result);
@@ -8403,13 +8442,13 @@ int QUICK_SELECT_DESC::get_next()
     if (range->flag & EQ_RANGE)
     {
       result = file->index_read(record, (byte*) range->max_key,
-				range->max_length, HA_READ_KEY_EXACT);
+				range->max_keypart_map, HA_READ_KEY_EXACT);
     }
     else
     {
       DBUG_ASSERT(range->flag & NEAR_MAX || range_reads_after_key(range));
       result=file->index_read(record, (byte*) range->max_key,
-			      range->max_length,
+			      range->max_keypart_map,
 			      ((range->flag & NEAR_MAX) ?
 			       HA_READ_BEFORE_KEY : HA_READ_PREFIX_LAST_OR_PREV));
     }
@@ -8728,8 +8767,7 @@ void QUICK_ROR_UNION_SELECT::add_keys_an
 static inline uint get_field_keypart(KEY *index, Field *field);
 static inline SEL_ARG * get_index_range_tree(uint index, SEL_TREE* range_tree,
                                              PARAM *param, uint *param_idx);
-static bool
-get_constant_key_infix(KEY *index_info, SEL_ARG *index_range_tree,
+static bool get_constant_key_infix(KEY *index_info, SEL_ARG *index_range_tree,
                        KEY_PART_INFO *first_non_group_part,
                        KEY_PART_INFO *min_max_arg_part,
                        KEY_PART_INFO *last_part, THD *thd,
@@ -9127,7 +9165,7 @@ get_best_group_min_max(PARAM *param, SEL
                           NULL;
     first_non_infix_part= min_max_arg_part ?
                           (min_max_arg_part < last_part) ?
-                             min_max_arg_part + 1 :
+                             min_max_arg_part :
                              NULL :
                            NULL;
     if (first_non_group_part &&
@@ -9184,7 +9222,9 @@ get_best_group_min_max(PARAM *param, SEL
     */
     if (first_non_infix_part)
     {
-      for (cur_part= first_non_infix_part; cur_part != last_part; cur_part++)
+      cur_part= first_non_infix_part +
+                (min_max_arg_part && (min_max_arg_part < last_part));
+      for (; cur_part != last_part; cur_part++)
       {
         if (bitmap_is_set(table->read_set, cur_part->field->field_index))
           goto next_index;
@@ -9730,7 +9770,7 @@ void cost_group_min_max(TABLE* table, KE
 
   RETURN
     New QUICK_GROUP_MIN_MAX_SELECT object if successfully created,
-    NULL o/w.
+    NULL otherwise.
 */
 
 QUICK_SELECT_I *
@@ -9743,10 +9783,10 @@ TRP_GROUP_MIN_MAX::make_quick(PARAM *par
   quick= new QUICK_GROUP_MIN_MAX_SELECT(param->table,
                                        
param->thd->lex->current_select->join,
                                         have_min, have_max, min_max_arg_part,
-                                        group_prefix_len, used_key_parts,
-                                        index_info, index, read_cost, records,
-                                        key_infix_len, key_infix,
-                                        parent_alloc);
+                                        group_prefix_len, group_key_parts,
+                                        used_key_parts, index_info, index,
+                                        read_cost, records, key_infix_len,
+                                        key_infix, parent_alloc);
   if (!quick)
     DBUG_RETURN(NULL);
 
@@ -9835,7 +9875,7 @@ QUICK_GROUP_MIN_MAX_SELECT::
 QUICK_GROUP_MIN_MAX_SELECT(TABLE *table, JOIN *join_arg, bool have_min_arg,
                            bool have_max_arg,
                            KEY_PART_INFO *min_max_arg_part_arg,
-                           uint group_prefix_len_arg,
+                           uint group_prefix_len_arg, uint group_key_parts_arg,
                            uint used_key_parts_arg, KEY *index_info_arg,
                            uint use_index, double read_cost_arg,
                            ha_rows records_arg, uint key_infix_len_arg,
@@ -9845,7 +9885,7 @@ QUICK_GROUP_MIN_MAX_SELECT(TABLE *table,
    have_max(have_max_arg), seen_first_key(FALSE),
    min_max_arg_part(min_max_arg_part_arg), key_infix(key_infix_arg),
    key_infix_len(key_infix_len_arg), min_functions_it(NULL),
-   max_functions_it(NULL)
+   max_functions_it(NULL), group_key_parts(group_key_parts_arg)
 {
   head=       table;
   file=       head->file;
@@ -9855,6 +9895,7 @@ QUICK_GROUP_MIN_MAX_SELECT(TABLE *table,
   read_time= read_cost_arg;
   records= records_arg;
   used_key_parts= used_key_parts_arg;
+  real_key_parts= used_key_parts_arg;
   real_prefix_len= group_prefix_len + key_infix_len;
   group_prefix= NULL;
   min_max_arg_len= min_max_arg_part ? min_max_arg_part->store_length : 0;
@@ -10021,7 +10062,9 @@ bool QUICK_GROUP_MIN_MAX_SELECT::add_ran
       range_flag|= EQ_RANGE;  /* equality condition */
   }
   range= new QUICK_RANGE(sel_range->min_value, min_max_arg_len,
+                         make_keypart_map(sel_range->part),
                          sel_range->max_value, min_max_arg_len,
+                         make_keypart_map(sel_range->part),
                          range_flag);
   if (!range)
     return TRUE;
@@ -10256,7 +10299,8 @@ int QUICK_GROUP_MIN_MAX_SELECT::get_next
       first sub-group with the extended prefix.
     */
     if (!have_min && !have_max && key_infix_len > 0)
-      result= file->index_read(record, group_prefix, real_prefix_len,
+      result= file->index_read(record, group_prefix,
+                               make_prev_keypart_map(real_key_parts),
                                HA_READ_KEY_EXACT);
 
     result= have_min ? min_res : have_max ? max_res : result;
@@ -10319,7 +10363,8 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_min
     /* Apply the constant equality conditions to the non-group select fields */
     if (key_infix_len > 0)
     {
-      if ((result= file->index_read(record, group_prefix, real_prefix_len,
+      if ((result= file->index_read(record, group_prefix,
+                                    make_prev_keypart_map(real_key_parts),
                                     HA_READ_KEY_EXACT)))
         DBUG_RETURN(result);
     }
@@ -10336,7 +10381,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_min
       /* Find the first subsequent record without NULL in the MIN/MAX field. */
       key_copy(tmp_record, record, index_info, 0);
       result= file->index_read(record, tmp_record,
-                               real_prefix_len + min_max_arg_len,
+                               make_keypart_map(real_key_parts),
                                HA_READ_AFTER_KEY);
       /*
         Check if the new record belongs to the current group by comparing its
@@ -10392,7 +10437,8 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_max
   if (min_max_ranges.elements > 0)
     result= next_max_in_range();
   else
-    result= file->index_read(record, group_prefix, real_prefix_len,
+    result= file->index_read(record, group_prefix,
+                             make_prev_keypart_map(real_key_parts),
                              HA_READ_PREFIX_LAST);
   DBUG_RETURN(result);
 }
@@ -10428,7 +10474,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_pre
   {
     byte *cur_prefix= seen_first_key ? group_prefix : NULL;
     if ((result= quick_prefix_select->get_next_prefix(group_prefix_len,
-                                                      cur_prefix)))
+                         (ULL(1) << group_key_parts) - 1, cur_prefix)))
       DBUG_RETURN(result);
     seen_first_key= TRUE;
   }
@@ -10444,7 +10490,8 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_pre
     else
     {
       /* Load the first key in this group into record. */
-      result= file->index_read(record, group_prefix, group_prefix_len,
+      result= file->index_read(record, group_prefix,
+                               make_prev_keypart_map(group_key_parts),
                                HA_READ_AFTER_KEY);
       if (result)
         DBUG_RETURN(result);
@@ -10487,6 +10534,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_min
 {
   ha_rkey_function find_flag;
   uint search_prefix_len;
+  ulonglong keypart_map;
   QUICK_RANGE *cur_range;
   bool found_null= FALSE;
   int result= HA_ERR_KEY_NOT_FOUND;
@@ -10508,8 +10556,9 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_min
 
     if (cur_range->flag & NO_MIN_RANGE)
     {
-      find_flag= HA_READ_KEY_EXACT;
       search_prefix_len= real_prefix_len;
+      keypart_map= (ULL(1) << real_key_parts) - 1;
+      find_flag= HA_READ_KEY_EXACT;
     }
     else
     {
@@ -10517,13 +10566,13 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_min
       memcpy(group_prefix + real_prefix_len, cur_range->min_key,
              cur_range->min_length);
       search_prefix_len= real_prefix_len + min_max_arg_len;
+      keypart_map= (ULL(2) << real_key_parts) - 1;
       find_flag= (cur_range->flag & (EQ_RANGE | NULL_RANGE)) ?
                  HA_READ_KEY_EXACT : (cur_range->flag & NEAR_MIN) ?
                  HA_READ_AFTER_KEY : HA_READ_KEY_OR_NEXT;
     }
 
-    result= file->index_read(record, group_prefix, search_prefix_len,
-                             find_flag);
+    result= file->index_read(record, group_prefix, keypart_map, find_flag);
     if (result)
     {
       if ((result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE) &&
@@ -10621,6 +10670,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_max
 {
   ha_rkey_function find_flag;
   uint search_prefix_len;
+  ulonglong keypart_map;
   QUICK_RANGE *cur_range;
   int result;
 
@@ -10642,8 +10692,9 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_max
 
     if (cur_range->flag & NO_MAX_RANGE)
     {
-      find_flag= HA_READ_PREFIX_LAST;
       search_prefix_len= real_prefix_len;
+      keypart_map= (ULL(1) << real_key_parts) - 1;
+      find_flag= HA_READ_PREFIX_LAST;
     }
     else
     {
@@ -10651,13 +10702,13 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_max
       memcpy(group_prefix + real_prefix_len, cur_range->max_key,
              cur_range->max_length);
       search_prefix_len= real_prefix_len + min_max_arg_len;
+      keypart_map= (ULL(2) << real_key_parts) - 1;
       find_flag= (cur_range->flag & EQ_RANGE) ?
                  HA_READ_KEY_EXACT : (cur_range->flag & NEAR_MAX) ?
                  HA_READ_BEFORE_KEY : HA_READ_PREFIX_LAST_OR_PREV;
     }
 
-    result= file->index_read(record, group_prefix, search_prefix_len,
-                             find_flag);
+    result= file->index_read(record, group_prefix, keypart_map, find_flag);
 
     if (result)
     {

--- 1.74/sql/opt_range.h	2007-01-29 10:40:35 +01:00
+++ 1.75/sql/opt_range.h	2007-01-29 10:40:35 +01:00
@@ -37,17 +37,22 @@ class QUICK_RANGE :public Sql_alloc {
  public:
   char *min_key,*max_key;
   uint16 min_length,max_length,flag;
+  ulonglong min_keypart_map, max_keypart_map;
 #ifdef HAVE_purify
   uint16 dummy;					/* Avoid warnings on 'flag' */
 #endif
   QUICK_RANGE();				/* Full range */
-  QUICK_RANGE(const char *min_key_arg,uint min_length_arg,
-	      const char *max_key_arg,uint max_length_arg,
+  QUICK_RANGE(const char *min_key_arg, uint min_length_arg,
+              ulonglong min_keypart_map_arg,
+	      const char *max_key_arg, uint max_length_arg,
+              ulonglong max_keypart_map_arg,
 	      uint flag_arg)
     : min_key((char*) sql_memdup(min_key_arg,min_length_arg+1)),
       max_key((char*) sql_memdup(max_key_arg,max_length_arg+1)),
       min_length((uint16) min_length_arg),
       max_length((uint16) max_length_arg),
+      min_keypart_map(min_keypart_map_arg),
+      max_keypart_map(max_keypart_map_arg),
       flag((uint16) flag_arg)
     {
 #ifdef HAVE_purify
@@ -318,7 +323,8 @@ public:
   int reset(void);
   int get_next();
   void range_end();
-  int get_next_prefix(uint prefix_length, byte *cur_prefix);
+  int get_next_prefix(uint prefix_length, ulonglong keypart_map,
+                      byte *cur_prefix);
   bool reverse_sorted() { return 0; }
   bool unique_key_range();
   int init_ror_merged_scan(bool reuse_handler);
@@ -605,6 +611,7 @@ private:
   byte *tmp_record;      /* Temporary storage for next_min(), next_max(). */
   byte *group_prefix;    /* Key prefix consisting of the GROUP fields. */
   uint group_prefix_len; /* Length of the group prefix. */
+  uint group_key_parts;
   byte *last_prefix;     /* Prefix of the last group for detecting EOF. */
   bool have_min;         /* Specify whether we are computing */
   bool have_max;         /*   a MIN, a MAX, or both.         */
@@ -616,6 +623,7 @@ private:
   uint key_infix_len;
   DYNAMIC_ARRAY min_max_ranges; /* Array of range ptrs for the MIN/MAX field. */
   uint real_prefix_len; /* Length of key prefix extended with key_infix. */
+  uint real_key_parts;
   List<Item_sum> *min_functions;
   List<Item_sum> *max_functions;
   List_iterator<Item_sum> *min_functions_it;
@@ -638,10 +646,11 @@ private:
 public:
   QUICK_GROUP_MIN_MAX_SELECT(TABLE *table, JOIN *join, bool have_min,
                              bool have_max, KEY_PART_INFO *min_max_arg_part,
-                             uint group_prefix_len, uint used_key_parts,
-                             KEY *index_info, uint use_index, double read_cost,
-                             ha_rows records, uint key_infix_len,
-                             byte *key_infix, MEM_ROOT *parent_alloc);
+                             uint group_prefix_len, uint group_key_parts,
+                             uint used_key_parts, KEY *index_info, uint
+                             use_index, double read_cost, ha_rows records, uint
+                             key_infix_len, byte *key_infix, MEM_ROOT
+                             *parent_alloc);
   ~QUICK_GROUP_MIN_MAX_SELECT();
   bool add_range(SEL_ARG *sel_range);
   void update_key_stat();

--- 1.59/sql/opt_sum.cc	2007-01-29 10:40:35 +01:00
+++ 1.60/sql/opt_sum.cc	2007-01-29 10:40:35 +01:00
@@ -251,7 +251,7 @@ int opt_sum_query(TABLE_LIST *tables, Li
             error= table->file->index_first(table->record[0]);
           else
 	    error= table->file->index_read(table->record[0],key_buff,
-					   ref.key_length,
+                                           make_prev_keypart_map(ref.key_parts),
 					   range_fl & NEAR_MIN ?
 					   HA_READ_AFTER_KEY :
 					   HA_READ_KEY_OR_NEXT);
@@ -338,11 +338,11 @@ int opt_sum_query(TABLE_LIST *tables, Li
             error= table->file->index_last(table->record[0]);
           else
 	    error= table->file->index_read(table->record[0], key_buff,
-					   ref.key_length,
+                                           make_prev_keypart_map(ref.key_parts),
 					   range_fl & NEAR_MAX ?
 					   HA_READ_BEFORE_KEY :
 					   HA_READ_PREFIX_LAST_OR_PREV);
-	  if (!error && reckey_in_range(1, &ref, item_field->field, 
+	  if (!error && reckey_in_range(1, &ref, item_field->field,
 			                conds, range_fl, prefix_len))
 	    error= HA_ERR_KEY_NOT_FOUND;
           if (table->key_read)
@@ -605,15 +605,13 @@ static bool matching_cond(bool max_fl, T
   /* Check if field is part of the tested partial key */
   byte *key_ptr= ref->key_buff;
   KEY_PART_INFO *part;
-  for (part= keyinfo->key_part;
-       ;
-       key_ptr+= part++->store_length)
+  for (part= keyinfo->key_part; ; key_ptr+= part++->store_length)
 
   {
     if (part > field_part)
       return 0;                     // Field is beyond the tested parts
     if (part->field->eq(((Item_field*) args[0])->field))
-      break;                        // Found a part od the key for the field
+      break;                        // Found a part of the key for the field
   }
 
   bool is_field_part= part == field_part;
@@ -625,8 +623,11 @@ static bool matching_cond(bool max_fl, T
   {
     uint length= (key_ptr-ref->key_buff)+part->store_length;
     if (ref->key_length < length)
+    {
     /* Ultimately ref->key_length will contain the length of the search key */
       ref->key_length= length;      
+      ref->key_parts= (part - keyinfo->key_part) + 1;
+    }
     if (!*prefix_len && part+1 == field_part)       
       *prefix_len= length;
     if (is_field_part && eq_type)
@@ -773,6 +774,7 @@ static bool find_key_for_maxmin(bool max
       {
         ref->key= idx;
         ref->key_length= 0;
+        ref->key_parts= 0;
         key_part_map key_part_used= 0;
         *range_fl= NO_MIN_RANGE | NO_MAX_RANGE;
         if (matching_cond(max_fl, ref, keyinfo, part, cond,
@@ -788,6 +790,8 @@ static bool find_key_for_maxmin(bool max
             */
             ref->key_buff[ref->key_length]= 1;
             ref->key_length+= part->store_length;
+            ref->key_parts++;
+            DBUG_ASSERT(ref->key_parts == jdx+1);
             *range_fl&= ~NO_MIN_RANGE;
             *range_fl|= NEAR_MIN;                // > NULL
           }

--- 1.302/sql/slave.cc	2007-01-29 10:40:35 +01:00
+++ 1.303/sql/slave.cc	2007-01-29 10:40:35 +01:00
@@ -31,6 +31,8 @@
 #include "rpl_tblmap.h"
 
 int queue_event(MASTER_INFO* mi,const char* buf,ulong event_len);
+static Log_event* next_event(RELAY_LOG_INFO* rli);
+
 
 #define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
 

--- 1.228/sql/sql_acl.cc	2007-01-29 10:40:35 +01:00
+++ 1.229/sql/sql_acl.cc	2007-01-29 10:40:35 +01:00
@@ -1813,8 +1813,7 @@ static bool update_user_table(THD *thd, 
            table->key_info->key_length);
 
   if (table->file->index_read_idx(table->record[0], 0,
-				  (byte *) user_key,
-                                  table->key_info->key_length,
+				  (byte *) user_key, ~ULL(0),
 				  HA_READ_KEY_EXACT))
   {
     my_message(ER_PASSWORD_NO_MATCH, ER(ER_PASSWORD_NO_MATCH),
@@ -1905,8 +1904,7 @@ static int replace_user_table(THD *thd, 
   key_copy(user_key, table->record[0], table->key_info,
            table->key_info->key_length);
 
-  if (table->file->index_read_idx(table->record[0], 0,
-                                  user_key, table->key_info->key_length,
+  if (table->file->index_read_idx(table->record[0], 0, user_key, ~ULL(0),
                                   HA_READ_KEY_EXACT))
   {
     /* what == 'N' means revoke */
@@ -2123,8 +2121,7 @@ static int replace_db_table(TABLE *table
   key_copy(user_key, table->record[0], table->key_info,
            table->key_info->key_length);
 
-  if (table->file->index_read_idx(table->record[0],0,
-                                  user_key, table->key_info->key_length,
+  if (table->file->index_read_idx(table->record[0],0, user_key, ~ULL(0),
                                   HA_READ_KEY_EXACT))
   {
     if (what == 'N')
@@ -2341,9 +2338,8 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TA
     col_privs->field[4]->store("",0, &my_charset_latin1);
 
     col_privs->file->ha_index_init(0, 1);
-    if (col_privs->file->index_read(col_privs->record[0],
-                                    (byte*) key,
-                                    key_prefix_len, HA_READ_KEY_EXACT))
+    if (col_privs->file->index_read(col_privs->record[0], (byte*) key,
+                                    (ulonglong)15, HA_READ_KEY_EXACT))
     {
       cols = 0; /* purecov: deadcode */
       col_privs->file->ha_index_end();
@@ -2479,7 +2475,7 @@ static int replace_column_table(GRANT_TA
   table->field[3]->store(table_name,(uint) strlen(table_name),
                          system_charset_info);
 
-  /* Get length of 3 first key parts */
+  /* Get length of 4 first key parts */
   key_prefix_length= (key_part[0].store_length + key_part[1].store_length +
                       key_part[2].store_length + key_part[3].store_length);
   key_copy(key, table->record[0], table->key_info, key_prefix_length);
@@ -2505,8 +2501,7 @@ static int replace_column_table(GRANT_TA
     key_copy(user_key, table->record[0], table->key_info,
              table->key_info->key_length);
 
-    if (table->file->index_read(table->record[0], user_key,
-				table->key_info->key_length,
+    if (table->file->index_read(table->record[0], user_key, ~(ulonglong)0,
                                 HA_READ_KEY_EXACT))
     {
       if (revoke_grant)
@@ -2582,8 +2577,7 @@ static int replace_column_table(GRANT_TA
     key_copy(user_key, table->record[0], table->key_info,
              key_prefix_length);
 
-    if (table->file->index_read(table->record[0], user_key,
-				key_prefix_length,
+    if (table->file->index_read(table->record[0], user_key, (ulonglong)15,
                                 HA_READ_KEY_EXACT))
       goto end;
 
@@ -2684,8 +2678,7 @@ static int replace_table_table(THD *thd,
   key_copy(user_key, table->record[0], table->key_info,
            table->key_info->key_length);
 
-  if (table->file->index_read_idx(table->record[0], 0,
-                                  user_key, table->key_info->key_length,
+  if (table->file->index_read_idx(table->record[0], 0, user_key, ~ULL(0),
 				  HA_READ_KEY_EXACT))
   {
     /*
@@ -2808,8 +2801,8 @@ static int replace_routine_table(THD *th
                          TRUE);
   store_record(table,record[1]);			// store at pos 1
 
-  if (table->file->index_read_idx(table->record[0],0,
-				  (byte*) table->field[0]->ptr,0,
+  if (table->file->index_read_idx(table->record[0], 0,
+				  (byte*) table->field[0]->ptr, ~ULL(0),
 				  HA_READ_KEY_EXACT))
   {
     /*
@@ -4987,7 +4980,7 @@ static int handle_grant_table(TABLE_LIST
     key_copy(user_key, table->record[0], table->key_info, key_prefix_length);
 
     if ((error= table->file->index_read_idx(table->record[0], 0,
-                                            user_key, key_prefix_length,
+                                            user_key, ULL(3),
                                             HA_READ_KEY_EXACT)))
     {
       if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)

--- 1.243/sql/sql_insert.cc	2007-01-29 10:40:35 +01:00
+++ 1.244/sql/sql_insert.cc	2007-01-29 10:40:35 +01:00
@@ -1165,9 +1165,7 @@ int write_record(THD *thd, TABLE *table,
 	}
 	key_copy((byte*) key,table->record[0],table->key_info+key_nr,0);
 	if ((error=(table->file->index_read_idx(table->record[1],key_nr,
-						(byte*) key,
-						table->key_info[key_nr].
-						key_length,
+						(byte*) key, ~ULL(0),
 						HA_READ_KEY_EXACT))))
 	  goto err;
       }

--- 1.485/sql/sql_select.cc	2007-01-29 10:40:35 +01:00
+++ 1.486/sql/sql_select.cc	2007-01-29 10:40:35 +01:00
@@ -10854,7 +10854,8 @@ int safe_index_read(JOIN_TAB *tab)
   TABLE *table= tab->table;
   if ((error=table->file->index_read(table->record[0],
 				     tab->ref.key_buff,
-				     tab->ref.key_length, HA_READ_KEY_EXACT)))
+                                     tab_to_keypart_map(tab),
+                                     HA_READ_KEY_EXACT)))
     return report_error(table, error);
   return 0;
 }
@@ -10992,7 +10993,8 @@ join_read_const(JOIN_TAB *tab)
     {
       error=table->file->index_read_idx(table->record[0],tab->ref.key,
 					(byte*) tab->ref.key_buff,
-					tab->ref.key_length,HA_READ_KEY_EXACT);
+					tab_to_keypart_map(tab),
+                                        HA_READ_KEY_EXACT);
     }
     if (error)
     {
@@ -11035,7 +11037,8 @@ join_read_key(JOIN_TAB *tab)
     }
     error=table->file->index_read(table->record[0],
 				  tab->ref.key_buff,
-				  tab->ref.key_length,HA_READ_KEY_EXACT);
+                                  tab_to_keypart_map(tab),
+                                  HA_READ_KEY_EXACT);
     if (error && error != HA_ERR_KEY_NOT_FOUND && error !=
HA_ERR_END_OF_FILE)
       return report_error(table, error);
   }
@@ -11063,7 +11066,8 @@ join_read_always_key(JOIN_TAB *tab)
     return -1;
   if ((error=table->file->index_read(table->record[0],
 				     tab->ref.key_buff,
-				     tab->ref.key_length,HA_READ_KEY_EXACT)))
+				     tab_to_keypart_map(tab),
+                                     HA_READ_KEY_EXACT)))
   {
     if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
       return report_error(table, error);
@@ -11090,7 +11094,7 @@ join_read_last_key(JOIN_TAB *tab)
     return -1;
   if ((error=table->file->index_read_last(table->record[0],
 					  tab->ref.key_buff,
-					  tab->ref.key_length)))
+					  tab_to_keypart_map(tab))))
   {
     if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
       return report_error(table, error);
@@ -11631,7 +11635,7 @@ end_update(JOIN *join, JOIN_TAB *join_ta
       group->buff[-1]= (char) group->field->is_null();
   }
   if (!table->file->index_read(table->record[1],
-			       join->tmp_table_param.group_buff,0,
+			       join->tmp_table_param.group_buff, ~(ulonglong)0,
 			       HA_READ_KEY_EXACT))
   {						/* Update old record */
     restore_record(table,record[1]);

--- 1.117/sql/sql_select.h	2007-01-29 10:40:35 +01:00
+++ 1.118/sql/sql_select.h	2007-01-29 10:40:35 +01:00
@@ -202,6 +202,11 @@ typedef struct st_join_table {
   }
 } JOIN_TAB;
 
+static inline ulonglong tab_to_keypart_map(JOIN_TAB *tab)
+{
+  return (ULL(1) << tab->ref.key_parts) - 1;
+}
+
 enum_nested_loop_state sub_select_cache(JOIN *join, JOIN_TAB *join_tab, bool
                                         end_of_records);
 enum_nested_loop_state sub_select(JOIN *join,JOIN_TAB *join_tab, bool

--- 1.70/sql/sql_udf.cc	2007-01-29 10:40:35 +01:00
+++ 1.71/sql/sql_udf.cc	2007-01-29 10:40:35 +01:00
@@ -514,8 +514,7 @@ int mysql_drop_function(THD *thd,const L
   table->use_all_columns();
   table->field[0]->store(exact_name_str, exact_name_len, &my_charset_bin);
   if (!table->file->index_read_idx(table->record[0], 0,
-				   (byte*) table->field[0]->ptr,
-				   table->key_info[0].key_length,
+				   (byte*) table->field[0]->ptr, ~ULL(0),
 				   HA_READ_KEY_EXACT))
   {
     int error;

--- 1.270/sql/table.cc	2007-01-29 10:40:35 +01:00
+++ 1.271/sql/table.cc	2007-01-29 10:40:35 +01:00
@@ -1223,12 +1223,12 @@ static int open_binary_frm(THD *thd, TAB
     if ((int) (share->next_number_index= (uint)
 	       find_ref_key(share->key_info, share->keys,
                             share->default_values, reg_field,
-			    &share->next_number_key_offset)) < 0)
+			    &share->next_number_key_offset,
+                            &share->next_number_keypart)) < 0)
     {
       /* Wrong field definition */
-      DBUG_ASSERT(0);
-      reg_field->unireg_check= Field::NONE;	/* purecov: inspected */
-      share->found_next_number_field= 0;
+      error= 4;
+      goto err;
     }
     else
       reg_field->flags |= AUTO_INCREMENT_FLAG;
@@ -2245,6 +2245,30 @@ char *get_field(MEM_ROOT *mem, Field *fi
   return to;
 }
 
+/*
+  DESCRIPTION
+    given a buffer with a key value, and a map of keyparts
+    that are present in this value, returns the length of the value
+*/
+uint calculate_key_len(TABLE *table, uint key, const byte *buf,
+                       ulonglong keypart_map)
+{
+  /* works only with key prefixes */
+  DBUG_ASSERT(((keypart_map + 1) & keypart_map) == 0);
+
+  KEY *key_info= table->s->key_info+key;
+  KEY_PART_INFO *key_part= key_info->key_part;
+  KEY_PART_INFO *end_key_part= key_part + key_info->key_parts;
+  uint length= 0;
+
+  while (key_part < end_key_part && keypart_map)
+  {
+    length+= key_part->store_length;
+    keypart_map >>= 1;
+    key_part++;
+  }
+  return length;
+}
 
 /*
   Check if database name is valid
@@ -3936,7 +3960,7 @@ void st_table::mark_auto_increment_colum
   */
   bitmap_set_bit(read_set, found_next_number_field->field_index);
   bitmap_set_bit(write_set, found_next_number_field->field_index);
-  if (s->next_number_key_offset)
+  if (s->next_number_keypart)
     mark_columns_used_by_index_no_reset(s->next_number_index, read_set);
   file->column_bitmaps_signal();
 }

--- 1.158/sql/table.h	2007-01-29 10:40:35 +01:00
+++ 1.159/sql/table.h	2007-01-29 10:40:35 +01:00
@@ -194,6 +194,7 @@ typedef struct st_table_share
   uint primary_key;
   uint next_number_index;
   uint next_number_key_offset;
+  uint next_number_keypart;
   uint error, open_errno, errarg;       /* error from open_table_def() */
   uint column_bitmap_size;
   uchar frm_version;

--- 1.20/sql/event_db_repository.cc	2007-01-29 10:40:35 +01:00
+++ 1.21/sql/event_db_repository.cc	2007-01-29 10:40:35 +01:00
@@ -288,7 +288,7 @@ Event_db_repository::index_read_for_db_f
   {
     key_copy(key_buf, event_table->record[0], key_info, key_len);
     if (!(ret= event_table->file->index_read(event_table->record[0], key_buf,
-                                             key_len, HA_READ_PREFIX)))
+                                             (ulonglong)1, HA_READ_PREFIX)))
     {
       DBUG_PRINT("info",("Found rows. Let's retrieve them. ret=%d", ret));
       do
@@ -518,7 +518,6 @@ Event_db_repository::create_event(THD *t
                                   my_bool create_if_not)
 {
   int ret= 0;
-  CHARSET_INFO *scs= system_charset_info;
   TABLE *table= NULL;
   char old_db_buf[NAME_LEN+1];
   LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) };
@@ -844,8 +843,7 @@ Event_db_repository::find_named_event(TH
 
   key_copy(key, table->record[0], table->key_info,
table->key_info->key_length);
 
-  if (table->file->index_read_idx(table->record[0], 0, key,
-                                  table->key_info->key_length,
+  if (table->file->index_read_idx(table->record[0], 0, key, ~ULL(0),
                                   HA_READ_KEY_EXACT))
   {
     DBUG_PRINT("info", ("Row not found"));

--- 1.16/storage/myisam/rt_test.c	2007-01-29 10:40:35 +01:00
+++ 1.17/storage/myisam/rt_test.c	2007-01-29 10:40:35 +01:00
@@ -323,7 +323,7 @@ static int run_test(const char *filename
   range.key= record+1;
   range.length= 1000;                           /* Big enough */
   range.flag= HA_READ_MBR_INTERSECT;
-  hrows= mi_records_in_range(file,0, &range, (key_range*) 0);
+  hrows= mi_records_in_range(file, 0, &range, (key_range*) 0);
   printf("     %ld rows\n", (long) hrows);
 
   if (mi_close(file)) goto err;

--- 1.14/storage/myisam/sp_test.c	2007-01-29 10:40:35 +01:00
+++ 1.15/storage/myisam/sp_test.c	2007-01-29 10:40:35 +01:00
@@ -255,7 +255,7 @@ int run_test(const char *filename)
   max_range.key= record+1;
   max_range.length= 1000;                       /* Big enough */
   max_range.flag= HA_READ_KEY_EXACT;
-  hrows= mi_records_in_range(file,0, &min_range, &max_range);
+  hrows= mi_records_in_range(file, 0, &min_range, &max_range);
   printf("     %ld rows\n", (long) hrows);
 
   if (mi_close(file)) goto err;

--- 1.142/sql/item_subselect.cc	2007-01-29 10:40:35 +01:00
+++ 1.143/sql/item_subselect.cc	2007-01-29 10:40:35 +01:00
@@ -2013,7 +2013,8 @@ int subselect_uniquesubquery_engine::exe
     table->file->ha_index_init(tab->ref.key, 0);
   error= table->file->index_read(table->record[0],
                                  tab->ref.key_buff,
-                                 tab->ref.key_length,HA_READ_KEY_EXACT);
+                                 tab_to_keypart_map(tab),
+                                 HA_READ_KEY_EXACT);
   if (error &&
       error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
     error= report_error(table, error);
@@ -2122,7 +2123,8 @@ int subselect_indexsubquery_engine::exec
     table->file->ha_index_init(tab->ref.key, 1);
   error= table->file->index_read(table->record[0],
                                  tab->ref.key_buff,
-                                 tab->ref.key_length,HA_READ_KEY_EXACT);
+                                 tab_to_keypart_map(tab),
+                                 HA_READ_KEY_EXACT);
   if (error &&
       error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
     error= report_error(table, error);

--- 1.51/storage/example/ha_example.cc	2007-01-29 10:40:35 +01:00
+++ 1.52/storage/example/ha_example.cc	2007-01-29 10:40:35 +01:00
@@ -90,14 +90,13 @@
 static handler *example_create_handler(handlerton *hton,
                                        TABLE_SHARE *table, 
                                        MEM_ROOT *mem_root);
-static int example_init_func();
+static int example_init_func(void *);
 
 handlerton *example_hton;
 
 /* Variables for example share methods */
 static HASH example_open_tables; ///< Hash used to track the number of open tables;
variable for example share methods
 pthread_mutex_t example_mutex;   ///< This is the mutex used to init the hash;
variable for example share methods
-static int example_init= 0;      ///< This variable is used to check the init state of
hash; variable for example share methods
 
 /** @brief
   Function we use in the creation of our hash to get key.
@@ -372,7 +371,7 @@ int ha_example::delete_row(const byte * 
   index.
 */
 int ha_example::index_read(byte * buf, const byte * key,
-                           uint key_len __attribute__((unused)),
+                           ulonglong keypart_map __attribute__((unused)),
                            enum ha_rkey_function find_flag
                            __attribute__((unused)))
 {

--- 1.20/storage/example/ha_example.h	2007-01-29 10:40:35 +01:00
+++ 1.21/storage/example/ha_example.h	2007-01-29 10:40:35 +01:00
@@ -191,7 +191,7 @@ public:
     skip it and and MySQL will treat it as not implemented.
   */
   int index_read(byte * buf, const byte * key,
-                 uint key_len, enum ha_rkey_function find_flag);
+                 ulonglong keypart_map, enum ha_rkey_function find_flag);
 
   /** @brief
     We implement this in ha_example.cc. It's not an obligatory method;

--- 1.46/storage/blackhole/ha_blackhole.cc	2007-01-29 10:40:35 +01:00
+++ 1.47/storage/blackhole/ha_blackhole.cc	2007-01-29 10:40:35 +01:00
@@ -152,7 +152,8 @@ THR_LOCK_DATA **ha_blackhole::store_lock
 
 
 int ha_blackhole::index_read(byte * buf, const byte * key,
-                             uint key_len, enum ha_rkey_function find_flag)
+                             ulonglong keypart_map, uint key_len,
+                             enum ha_rkey_function find_flag)
 {
   DBUG_ENTER("ha_blackhole::index_read");
   DBUG_RETURN(0);
@@ -160,14 +161,16 @@ int ha_blackhole::index_read(byte * buf,
 
 
 int ha_blackhole::index_read_idx(byte * buf, uint idx, const byte * key,
-                                 uint key_len, enum ha_rkey_function find_flag)
+                                 ulonglong keypart_map, uint key_len,
+                                 enum ha_rkey_function find_flag)
 {
   DBUG_ENTER("ha_blackhole::index_read_idx");
   DBUG_RETURN(HA_ERR_END_OF_FILE);
 }
 
 
-int ha_blackhole::index_read_last(byte * buf, const byte * key, uint key_len)
+int ha_blackhole::index_read_last(byte * buf, const byte * key,
+                                  ulonglong keypart_map)
 {
   DBUG_ENTER("ha_blackhole::index_read_last");
   DBUG_RETURN(HA_ERR_END_OF_FILE);

--- 1.12/storage/blackhole/ha_blackhole.h	2007-01-29 10:40:35 +01:00
+++ 1.13/storage/blackhole/ha_blackhole.h	2007-01-29 10:40:35 +01:00
@@ -64,11 +64,12 @@ public:
   int rnd_init(bool scan);
   int rnd_next(byte *buf);
   int rnd_pos(byte * buf, byte *pos);
-  int index_read(byte * buf, const byte * key,
+  int index_read(byte * buf, const byte * key, ulonglong keypart_map,
                  uint key_len, enum ha_rkey_function find_flag);
   int index_read_idx(byte * buf, uint idx, const byte * key,
-                     uint key_len, enum ha_rkey_function find_flag);
-  int index_read_last(byte * buf, const byte * key, uint key_len);
+                   ulonglong keypart_map, uint key_len,
+                   enum ha_rkey_function find_flag);
+  int index_read_last(byte * buf, const byte * key, ulonglong keypart_map);
   int index_next(byte * buf);
   int index_prev(byte * buf);
   int index_first(byte * buf);

--- 1.46/sql/tztime.cc	2007-01-29 10:40:35 +01:00
+++ 1.47/sql/tztime.cc	2007-01-29 10:40:35 +01:00
@@ -1900,9 +1900,9 @@ tz_load_from_open_tables(const String *t
   (void)table->file->ha_index_init(0, 1);
 
   if (table->file->index_read(table->record[0],
(byte*)table->field[0]->ptr,
-                              0, HA_READ_KEY_EXACT))
+                              ~(ulonglong)0, HA_READ_KEY_EXACT))
   {
-#ifdef EXTRA_DEBUG    
+#ifdef EXTRA_DEBUG
     /*
       Most probably user has mistyped time zone name, so no need to bark here
       unless we need it for debugging.
@@ -1928,7 +1928,7 @@ tz_load_from_open_tables(const String *t
   (void)table->file->ha_index_init(0, 1);
 
   if (table->file->index_read(table->record[0],
(byte*)table->field[0]->ptr,
-                              0, HA_READ_KEY_EXACT))
+                              ~(ulonglong)0, HA_READ_KEY_EXACT))
   {
     sql_print_error("Can't find description of time zone '%u'", tzid);
     goto end;
@@ -1955,9 +1955,8 @@ tz_load_from_open_tables(const String *t
   table->field[0]->store((longlong) tzid, TRUE);
   (void)table->file->ha_index_init(0, 1);
 
-  // FIXME Is there any better approach than explicitly specifying 4 ???
   res= table->file->index_read(table->record[0],
(byte*)table->field[0]->ptr,
-                               4, HA_READ_KEY_EXACT);
+                               (ulonglong)1, HA_READ_KEY_EXACT);
   while (!res)
   {
     ttid= (uint)table->field[1]->val_int();
@@ -2028,9 +2027,8 @@ tz_load_from_open_tables(const String *t
   table->field[0]->store((longlong) tzid, TRUE);
   (void)table->file->ha_index_init(0, 1);
 
-  // FIXME Is there any better approach than explicitly specifying 4 ???
   res= table->file->index_read(table->record[0],
(byte*)table->field[0]->ptr,
-                               4, HA_READ_KEY_EXACT);
+                               (ulonglong)1, HA_READ_KEY_EXACT);
   while (!res)
   {
     ttime= (my_time_t)table->field[1]->val_int();

--- 1.397/sql/ha_ndbcluster.cc	2007-01-29 10:40:35 +01:00
+++ 1.398/sql/ha_ndbcluster.cc	2007-01-29 10:40:35 +01:00
@@ -956,7 +956,6 @@ int ha_ndbcluster::get_ndb_partition_id(
 
 bool ha_ndbcluster::uses_blob_value()
 {
-  uint blob_fields;
   MY_BITMAP *bitmap;
   uint *blob_index, *blob_index_end;
   if (table_share->blob_fields == 0)
@@ -1108,7 +1107,7 @@ int ha_ndbcluster::create_indexes(Ndb *n
   const char **key_name= tab->s->keynames.type_names;
   NDBDICT *dict= ndb->getDictionary();
   DBUG_ENTER("ha_ndbcluster::create_indexes");
-  
+
   for (i= 0; i < tab->s->keys; i++, key_info++, key_name++)
   {
     index_name= *key_name;
@@ -3375,19 +3374,6 @@ int ha_ndbcluster::index_read(byte *buf,
 }
 
 
-int ha_ndbcluster::index_read_idx(byte *buf, uint index_no, 
-                              const byte *key, uint key_len, 
-                              enum ha_rkey_function find_flag)
-{
-  statistic_increment(current_thd->status_var.ha_read_key_count, &LOCK_status);
-  DBUG_ENTER("ha_ndbcluster::index_read_idx");
-  DBUG_PRINT("enter", ("index_no: %u, key_len: %u", index_no, key_len));  
-  close_scan();
-  index_init(index_no, 0);  
-  DBUG_RETURN(index_read(buf, key, key_len, find_flag));
-}
-
-
 int ha_ndbcluster::index_next(byte *buf)
 {
   DBUG_ENTER("ha_ndbcluster::index_next");
@@ -3554,10 +3540,10 @@ int ha_ndbcluster::close_scan()
 
   m_multi_cursor= 0;
   if (!m_active_cursor && !m_multi_cursor)
-    DBUG_RETURN(1);
+    DBUG_RETURN(0);
 
   NdbScanOperation *cursor= m_active_cursor ? m_active_cursor : m_multi_cursor;
-  
+
   if (m_lock_tuple)
   {
     /*

--- 1.165/sql/ha_ndbcluster.h	2007-01-29 10:40:35 +01:00
+++ 1.166/sql/ha_ndbcluster.h	2007-01-29 10:40:35 +01:00
@@ -641,8 +641,6 @@ class ha_ndbcluster: public handler
   int index_end();
   int index_read(byte *buf, const byte *key, uint key_len, 
                  enum ha_rkey_function find_flag);
-  int index_read_idx(byte *buf, uint index, const byte *key, uint key_len, 
-                     enum ha_rkey_function find_flag);
   int index_next(byte *buf);
   int index_prev(byte *buf);
   int index_first(byte *buf);

--- 1.320/storage/innobase/handler/ha_innodb.cc	2007-01-29 10:40:35 +01:00
+++ 1.321/storage/innobase/handler/ha_innodb.cc	2007-01-29 10:40:35 +01:00
@@ -3920,14 +3920,14 @@ statement issued by the user. We also in
 
   2) If prebuilt->sql_stat_start == TRUE we 'pre-compile' the MySQL search
 instructions to prebuilt->template of the table handle instance in
-::index_read. The template is used to save CPU time in large joins.
+::index_read_old. The template is used to save CPU time in large joins.
 
   3) In row_search_for_mysql, if prebuilt->sql_stat_start is true, we
 allocate a new consistent read view for the trx if it does not yet have one,
 or in the case of a locking read, set an InnoDB 'intention' table level
 lock on the table.
 
-  4) We do the SELECT. MySQL may repeatedly call ::index_read for the
+  4) We do the SELECT. MySQL may repeatedly call ::index_read_old for the
 same table handle instance, if it is a join.
 
   5) When the SELECT ends, MySQL removes its intention table level locks
@@ -3941,7 +3941,7 @@ table handler in that case has to execut
   B) If the user has explicitly set MySQL table level locks, then MySQL
 does NOT call ::external_lock at the start of the statement. To determine
 when we are at the start of a new SQL statement we at the start of
-::index_read also compare the query id to the latest query id where the
+::index_read_old also compare the query id to the latest query id where the
 table handle instance was used. If it has changed, we know we are at the
 start of a new SQL statement. Since the query id can theoretically
 overwrap, we use this test only as a secondary way of determining the
@@ -3978,7 +3978,7 @@ ha_innobase::index_read(
 	int		error;
 	ulint		ret;
 
-	DBUG_ENTER("index_read");
+	DBUG_ENTER("index_read_old");
 
 	ut_a(prebuilt->trx ==
 		(trx_t*) current_thd->ha_data[ht->slot]);
@@ -4060,7 +4060,7 @@ ha_innobase::index_read(
 }
 
 /***********************************************************************
-The following functions works like index_read, but it find the last
+The following functions works like index_read_old, but it find the last
 row with the current key value or prefix. */
 
 int
@@ -4166,7 +4166,7 @@ ha_innobase::index_read_idx(
 
 /***************************************************************************
 Reads the next or previous row from a cursor, which must have previously been
-positioned using index_read. */
+positioned using index_read_old. */
 
 int
 ha_innobase::general_fetch(
@@ -4215,7 +4215,7 @@ ha_innobase::general_fetch(
 
 /***************************************************************************
 Reads the next row from a cursor, which must have previously been
-positioned using index_read. */
+positioned using index_read_old. */
 
 int
 ha_innobase::index_next(
@@ -4251,7 +4251,7 @@ ha_innobase::index_next_same(
 
 /***************************************************************************
 Reads the previous row from a cursor, which must have previously been
-positioned using index_read. */
+positioned using index_read_old. */
 
 int
 ha_innobase::index_prev(

--- 1.42/sql/sql_plugin.cc	2007-01-29 10:40:35 +01:00
+++ 1.43/sql/sql_plugin.cc	2007-01-29 10:40:35 +01:00
@@ -921,8 +921,7 @@ my_bool mysql_uninstall_plugin(THD *thd,
   table->use_all_columns();
   table->field[0]->store(name->str, name->length, system_charset_info);
   if (! table->file->index_read_idx(table->record[0], 0,
-                                    (byte *)table->field[0]->ptr,
-                                    table->key_info[0].key_length,
+                                    (byte *)table->field[0]->ptr, ~ULL(0),
                                     HA_READ_KEY_EXACT))
   {
     int error;

--- 1.82/sql/ha_partition.cc	2007-01-29 10:40:35 +01:00
+++ 1.83/sql/ha_partition.cc	2007-01-29 10:40:35 +01:00
@@ -584,7 +584,6 @@ int ha_partition::drop_partitions(const 
   List_iterator<partition_element> part_it(m_part_info->partitions);
   char part_name_buff[FN_REFLEN];
   uint no_parts= m_part_info->partitions.elements;
-  uint part_count= 0;
   uint no_subparts= m_part_info->no_subparts;
   uint i= 0;
   uint name_variant;
@@ -1075,7 +1074,6 @@ int ha_partition::handle_opt_partitions(
   uint no_parts= m_part_info->no_parts;
   uint no_subparts= m_part_info->no_subparts;
   uint i= 0;
-  LEX *lex= thd->lex;
   int error;
   DBUG_ENTER("ha_partition::handle_opt_partitions");
   DBUG_PRINT("enter", ("all_parts %u, flag= %u", all_parts, flag));
@@ -1136,7 +1134,6 @@ int ha_partition::prepare_new_partition(
 {
   int error;
   bool create_flag= FALSE;
-  bool open_flag= FALSE;
   DBUG_ENTER("prepare_new_partition");
 
   if ((error= set_up_table_before_create(table, part_name, create_info,
@@ -1245,7 +1242,6 @@ int ha_partition::change_partitions(HA_C
   handler **new_file_array;
   int error= 1;
   bool first;
-  bool copy_parts= FALSE;
   uint temp_partitions= m_part_info->temp_partitions.elements;
   THD *thd= current_thd;
   DBUG_ENTER("ha_partition::change_partitions");
@@ -2061,7 +2057,6 @@ bool ha_partition::new_handlers_from_par
   partition_element *part_elem;
   uint alloc_len= (m_tot_parts + 1) * sizeof(handler*);
   List_iterator_fast <partition_element> part_it(m_part_info->partitions);
-  THD *thd= current_thd;
   DBUG_ENTER("ha_partition::new_handlers_from_part_info");
 
   if (!(m_file= (handler **) alloc_root(mem_root, alloc_len)))
@@ -3327,13 +3322,14 @@ int ha_partition::index_end()
 */
 
 int ha_partition::index_read(byte * buf, const byte * key,
-			     uint key_len, enum ha_rkey_function find_flag)
+			     ulonglong keypart_map,
+                             enum ha_rkey_function find_flag)
 {
   DBUG_ENTER("ha_partition::index_read");
 
   end_range= 0;
   m_index_scan_type= partition_index_read;
-  DBUG_RETURN(common_index_read(buf, key, key_len, find_flag));
+  DBUG_RETURN(common_index_read(buf, key, keypart_map, find_flag));
 }
 
 
@@ -3346,14 +3342,17 @@ int ha_partition::index_read(byte * buf,
   see index_read for rest
 */
 
-int ha_partition::common_index_read(byte *buf, const byte *key, uint key_len,
+int ha_partition::common_index_read(byte *buf, const byte *key,
+                                    ulonglong keypart_map,
 				    enum ha_rkey_function find_flag)
 {
   int error;
   bool reverse_order= FALSE;
+  uint key_len= calculate_key_len(table, active_index, key, keypart_map);
   DBUG_ENTER("ha_partition::common_index_read");
 
   memcpy((void*)m_start_key.key, key, key_len);
+  m_start_key.keypart_map= keypart_map;
   m_start_key.length= key_len;
   m_start_key.flag= find_flag;
 
@@ -3482,33 +3481,6 @@ int ha_partition::common_first_last(byte
 
 
 /*
-  Perform index read using index where always only one row is returned
-
-  SYNOPSIS
-    index_read_idx()
-    see index_read for rest of parameters and return values
-
-  DESCRIPTION
-    Positions an index cursor to the index specified in key. Fetches the
-    row if any.  This is only used to read whole keys.
-    TODO: Optimise this code to avoid index_init and index_end
-*/
-
-int ha_partition::index_read_idx(byte * buf, uint index, const byte * key,
-				 uint key_len,
-                                 enum ha_rkey_function find_flag)
-{
-  int res;
-  DBUG_ENTER("ha_partition::index_read_idx");
-
-  index_init(index, 0);
-  res= index_read(buf, key, key_len, find_flag);
-  index_end();
-  DBUG_RETURN(res);
-}
-
-
-/*
   Read last using key
 
   SYNOPSIS
@@ -3526,14 +3498,15 @@ int ha_partition::index_read_idx(byte * 
     Can only be used on indexes supporting HA_READ_ORDER
 */
 
-int ha_partition::index_read_last(byte *buf, const byte *key, uint keylen)
+int ha_partition::index_read_last(byte *buf, const byte *key,
+                                      ulonglong keypart_map)
 {
   DBUG_ENTER("ha_partition::index_read_last");
 
   m_ordered= TRUE;				// Safety measure
   end_range= 0;
   m_index_scan_type= partition_index_read_last;
-  DBUG_RETURN(common_index_read(buf, key, keylen, HA_READ_PREFIX_LAST));
+  DBUG_RETURN(common_index_read(buf, key, keypart_map, HA_READ_PREFIX_LAST));
 }
 
 
@@ -3679,7 +3652,7 @@ int ha_partition::read_range_first(const
     m_index_scan_type= partition_index_read;
     error= common_index_read(m_rec0,
 			     start_key->key,
-			     start_key->length, start_key->flag);
+                             start_key->keypart_map, start_key->flag);
   }
   DBUG_RETURN(error);
 }
@@ -3878,7 +3851,7 @@ int ha_partition::handle_unordered_scan_
     case partition_index_read:
       DBUG_PRINT("info", ("index_read on partition %d", i));
       error= file->index_read(buf, m_start_key.key,
-                              m_start_key.length,
+                              m_start_key.keypart_map,
                               m_start_key.flag);
       break;
     case partition_index_first:
@@ -3970,7 +3943,7 @@ int ha_partition::handle_ordered_index_s
     case partition_index_read:
       error= file->index_read(rec_buf_ptr,
                               m_start_key.key,
-                              m_start_key.length,
+                              m_start_key.keypart_map,
                               m_start_key.flag);
       break;
     case partition_index_first:
@@ -3984,7 +3957,7 @@ int ha_partition::handle_ordered_index_s
     case partition_index_read_last:
       error= file->index_read_last(rec_buf_ptr,
                                    m_start_key.key,
-                                   m_start_key.length);
+                                   m_start_key.keypart_map);
       reverse_order= TRUE;
       break;
     default:

--- 1.32/sql/ha_partition.h	2007-01-29 10:40:35 +01:00
+++ 1.33/sql/ha_partition.h	2007-01-29 10:40:35 +01:00
@@ -378,9 +378,8 @@ public:
     any end processing needed.
   */
   virtual int index_read(byte * buf, const byte * key,
-			 uint key_len, enum ha_rkey_function find_flag);
-  virtual int index_read_idx(byte * buf, uint idx, const byte * key,
-			     uint key_len, enum ha_rkey_function find_flag);
+                             ulonglong keypart_map,
+                             enum ha_rkey_function find_flag);
   virtual int index_init(uint idx, bool sorted);
   virtual int index_end();
 
@@ -393,7 +392,8 @@ public:
   virtual int index_first(byte * buf);
   virtual int index_last(byte * buf);
   virtual int index_next_same(byte * buf, const byte * key, uint keylen);
-  virtual int index_read_last(byte * buf, const byte * key, uint keylen);
+  virtual int index_read_last(byte * buf, const byte * key,
+                                  ulonglong keypart_map);
 
   /*
     read_first_row is virtual method but is only implemented by
@@ -419,7 +419,7 @@ public:
 
 private:
   int common_index_read(byte * buf, const byte * key,
-			uint key_len, enum ha_rkey_function find_flag);
+                        ulonglong keypart_map, enum ha_rkey_function find_flag);
   int common_first_last(byte * buf);
   int partition_scan_set_up(byte * buf, bool idx_read_flag);
   int handle_unordered_next(byte * buf, bool next_same);

--- 1.96/storage/federated/ha_federated.cc	2007-01-29 10:40:35 +01:00
+++ 1.97/storage/federated/ha_federated.cc	2007-01-29 10:40:35 +01:00
@@ -362,7 +362,7 @@ static handler *federated_create_handler
                                          MEM_ROOT *mem_root);
 static int federated_commit(handlerton *hton, THD *thd, bool all);
 static int federated_rollback(handlerton *hton, THD *thd, bool all);
-static int federated_db_init(void);
+static int federated_db_init(void *);
 
 
 /* Federated storage engine handlerton */
@@ -573,9 +573,6 @@ int get_connection(FEDERATED_SHARE *shar
   int error_num= ER_FOREIGN_SERVER_DOESNT_EXIST;
   char error_buffer[FEDERATED_QUERY_BUFFER_SIZE];
   FOREIGN_SERVER *server;
-  MYSQL *mysql_conn= 0;
-  MYSQL_RES *result= 0;
-  MYSQL_ROW row= 0;
   DBUG_ENTER("ha_federated::get_connection");
 
   if (!(server=

--- 1.4/sql/sql_servers.cc	2007-01-29 10:40:35 +01:00
+++ 1.5/sql/sql_servers.cc	2007-01-29 10:40:35 +01:00
@@ -25,6 +25,7 @@
 #include "sp_head.h"
 #include "sp.h"
 
+static my_bool servers_load(THD *thd, TABLE_LIST *tables);
 HASH servers_cache;
 pthread_mutex_t servers_cache_mutex;                // To init the hash
 uint servers_cache_initialised=FALSE;
@@ -356,8 +357,7 @@ my_bool server_exists_in_table(THD *thd,
                          system_charset_info);
 
   if ((error= table->file->index_read_idx(table->record[0], 0,
-                                   (byte *)table->field[0]->ptr,
-                                   table->key_info[0].key_length,
+                                   (byte *)table->field[0]->ptr, ~(ulonglong)0,
                                    HA_READ_KEY_EXACT)))
   {
     if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
@@ -556,8 +556,7 @@ int insert_server_record(TABLE *table, F
 
   /* read index until record is that specified in server_name */
   if ((error= table->file->index_read_idx(table->record[0], 0,
-                                   (byte *)table->field[0]->ptr,
-                                   table->key_info[0].key_length,
+                                   (byte *)table->field[0]->ptr, ~(longlong)0,
                                    HA_READ_KEY_EXACT)))
   {
     /* if not found, err */
@@ -876,8 +875,7 @@ int update_server_record(TABLE *table, F
                          system_charset_info);
 
   if ((error= table->file->index_read_idx(table->record[0], 0,
-                                   (byte *)table->field[0]->ptr,
-                                   table->key_info[0].key_length,
+                                   (byte *)table->field[0]->ptr, ~(longlong)0,
                                    HA_READ_KEY_EXACT)))
   {
     if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
@@ -931,8 +929,7 @@ int delete_server_record(TABLE *table,
   table->field[0]->store(server_name, server_name_length, system_charset_info);
 
   if ((error= table->file->index_read_idx(table->record[0], 0,
-                                   (byte *)table->field[0]->ptr,
-                                   table->key_info[0].key_length,
+                                   (byte *)table->field[0]->ptr, ~(ulonglong)0,
                                    HA_READ_KEY_EXACT)))
   {
     if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)

--- 1.3/sql/sql_servers.h	2007-01-29 10:40:35 +01:00
+++ 1.4/sql/sql_servers.h	2007-01-29 10:40:35 +01:00
@@ -26,7 +26,6 @@ typedef struct st_federated_server
 
 /* cache handlers */
 my_bool servers_init(bool dont_read_server_table);
-static my_bool servers_load(THD *thd, TABLE_LIST *tables);
 my_bool servers_reload(THD *thd);
 my_bool get_server_from_table_to_cache(TABLE *table);
 void servers_free(bool end=0);

--- 1.136/sql/sp.cc	2007-01-29 10:40:35 +01:00
+++ 1.137/sql/sp.cc	2007-01-29 10:40:35 +01:00
@@ -218,8 +218,7 @@ db_find_routine_aux(THD *thd, int type, 
   key_copy(key, table->record[0], table->key_info,
            table->key_info->key_length);
 
-  if (table->file->index_read_idx(table->record[0], 0,
-				  key, table->key_info->key_length,
+  if (table->file->index_read_idx(table->record[0], 0, key, ~ULL(0),
 				  HA_READ_KEY_EXACT))
     DBUG_RETURN(SP_KEY_NOT_FOUND);
 
@@ -494,8 +493,6 @@ db_create_routine(THD *thd, int type, sp
   int ret;
   TABLE *table;
   char definer[USER_HOST_BUFF_SIZE];
-  char old_db_buf[NAME_LEN+1];
-  LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) };
   DBUG_ENTER("db_create_routine");
   DBUG_PRINT("enter", ("type: %d name: %.*s",type,sp->m_name.length,
                        sp->m_name.str));
@@ -906,7 +903,7 @@ sp_drop_db_routines(THD *thd, char *db)
   table->file->ha_index_init(0, 1);
   if (! table->file->index_read(table->record[0],
                                 (byte *)table->field[MYSQL_PROC_FIELD_DB]->ptr,
-				key_len, HA_READ_KEY_EXACT))
+                                (ulonglong)1, HA_READ_KEY_EXACT))
   {
     int nxtres;
     bool deleted= FALSE;

--- 1.103/sql/slave.h	2007-01-29 10:40:35 +01:00
+++ 1.104/sql/slave.h	2007-01-29 10:40:35 +01:00
@@ -111,8 +111,6 @@ extern ulonglong relay_log_space_limit;
 #define MYSQL_SLAVE_RUN_NOT_CONNECT 1
 #define MYSQL_SLAVE_RUN_CONNECT     2
 
-static Log_event* next_event(RELAY_LOG_INFO* rli);
-
 #define RPL_LOG_NAME (rli->group_master_log_name[0] ? rli->group_master_log_name :\
  "FIRST")
 #define IO_RPL_LOG_NAME (mi->master_log_name[0] ? mi->master_log_name :\

--- 1.22/storage/myisammrg/myrg_rkey.c	2007-01-29 10:40:35 +01:00
+++ 1.23/storage/myisammrg/myrg_rkey.c	2007-01-29 10:40:35 +01:00
@@ -36,7 +36,7 @@
 */
 
 int myrg_rkey(MYRG_INFO *info,byte *buf,int inx, const byte *key,
-            uint key_len, enum ha_rkey_function search_flag)
+            ulonglong keypart_map, enum ha_rkey_function search_flag)
 {
   byte *key_buff;
   uint pack_key_length;
@@ -56,7 +56,7 @@ int myrg_rkey(MYRG_INFO *info,byte *buf,
 
     if (table == info->open_tables)
     {
-      err=mi_rkey(mi,0,inx,key,key_len,search_flag);
+      err=mi_rkey(mi, 0, inx, key, keypart_map, search_flag);
       /* Get the saved packed key and packed key length. */
       key_buff=(byte*) mi->lastkey+mi->s->base.max_key_length;
       pack_key_length=mi->pack_key_length;
@@ -64,7 +64,7 @@ int myrg_rkey(MYRG_INFO *info,byte *buf,
     else
     {
       mi->once_flags|= USE_PACKED_KEYS;
-      err=mi_rkey(mi,0,inx,key_buff,pack_key_length,search_flag);
+      err=mi_rkey(mi, 0, inx, key_buff, pack_key_length, search_flag);
     }
     info->last_used_table=table+1;
 

--- 1.91/sql/sql_handler.cc	2007-01-29 10:40:35 +01:00
+++ 1.92/sql/sql_handler.cc	2007-01-29 10:40:35 +01:00
@@ -515,7 +515,8 @@ bool mysql_ha_read(THD *thd, TABLE_LIST 
       }
       List_iterator<Item> it_ke(*key_expr);
       Item *item;
-      for (key_len=0 ; (item=it_ke++) ; key_part++)
+      ulonglong keypart_map;
+      for (keypart_map= key_len=0 ; (item=it_ke++) ; key_part++)
       {
         my_bitmap_map *old_map;
 	// 'item' can be changed by fix_fields() call
@@ -532,6 +533,7 @@ bool mysql_ha_read(THD *thd, TABLE_LIST 
 	(void) item->save_in_field(key_part->field, 1);
         dbug_tmp_restore_column_map(table->write_set, old_map);
 	key_len+=key_part->store_length;
+        keypart_map= (keypart_map << 1) | 1;
       }
 
       if (!(key= (byte*) thd->calloc(ALIGN_SIZE(key_len))))
@@ -540,7 +542,7 @@ bool mysql_ha_read(THD *thd, TABLE_LIST 
       table->file->ha_index_init(keyno, 1);
       key_copy(key, table->record[0], table->key_info + keyno, key_len);
       error= table->file->index_read(table->record[0],
-                                     key,key_len,ha_rkey_mode);
+                                     key, keypart_map, ha_rkey_mode);
       mode=rkey_to_rnext[(int)ha_rkey_mode];
       break;
     }

--- 1.54/sql/sql_help.cc	2007-01-29 10:40:35 +01:00
+++ 1.55/sql/sql_help.cc	2007-01-29 10:40:35 +01:00
@@ -295,8 +295,7 @@ int get_topics_for_keyword(THD *thd, TAB
   rkey_id->store((longlong) key_id, TRUE);
   rkey_id->get_key_image(buff, rkey_id->pack_length(), Field::itRAW);
   int key_res= relations->file->index_read(relations->record[0],
-                                           (byte *) buff,
-                                           rkey_id->pack_length(),
+                                           (byte *) buff, (ulonglong)1,
                                            HA_READ_KEY_EXACT);
 
   for ( ;
@@ -310,7 +309,7 @@ int get_topics_for_keyword(THD *thd, TAB
     field->get_key_image(topic_id_buff, field->pack_length(), Field::itRAW);
 
     if (!topics->file->index_read(topics->record[0], (byte *)topic_id_buff,
-				  field->pack_length(), HA_READ_KEY_EXACT))
+				  (ulonglong)1, HA_READ_KEY_EXACT))
     {
       memorize_variant_topic(thd,topics,count,find_fields,
 			     names,name,description,example);
Thread
bk commit into 5.1 tree (serg:1.2415)Sergei Golubchik29 Jan