From: Sergey Glukhov Date: September 20 2012 11:33am Subject: bzr push into mysql-trunk branch (sergey.glukhov:4512 to 4513) WL#6266 List-Archive: http://lists.mysql.com/commits/144828 Message-Id: <201209201133.q8KBX1UQ022220@acsmt356.oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 4513 Sergey Glukhov 2012-09-20 WL#6266 Make use of hidden key parts(addon) added a check that extended key length does not exceed MAX_KEY_LENGTH. @ mysql-test/r/innodb_pk_extention.result test fix @ mysql-test/suite/opt_trace/r/range_no_prot.result test fix @ mysql-test/suite/opt_trace/r/range_ps_prot.result test fix @ mysql-test/t/innodb_pk_extention.test test fix @ sql/opt_sum.cc fixed coding style @ sql/table.cc added a check that extended key length does not exceed MAX_KEY_LENGTH. modified: mysql-test/r/innodb_pk_extention.result mysql-test/suite/opt_trace/r/range_no_prot.result mysql-test/suite/opt_trace/r/range_ps_prot.result mysql-test/t/innodb_pk_extention.test sql/opt_sum.cc sql/table.cc 4512 Sergey Glukhov 2012-09-20 WL#6266 Make use of hidden key parts @ mysql-test/r/innodb_pk_extention.result test result @ mysql-test/suite/innodb/r/innodb_mysql.result result fix @ mysql-test/suite/opt_trace/r/range_no_prot.result result fix @ mysql-test/suite/opt_trace/r/range_ps_prot.result result fix @ mysql-test/t/innodb_pk_extention.test test case @ sql/handler.cc handler::index_next_same(): replaced key_info->key_parts with key_info->actual_key_parts @ sql/opt_range.cc SQL_SELECT::test_quick_select(), get_quick_select(), get_best_group_min_max(), get_field_keypart(): replaced key_info->key_parts with key_info->actual_key_parts @ sql/opt_sum.cc find_key_for_maxmin(): replaced key_info->key_parts with key_info->actual_key_parts @ sql/sql_optimizer.cc make_join_statistics(), find_eq_ref_candidate(), add_key_part(), list_contains_unique_index(): replaced key_info->key_parts with key_info->actual_key_parts replaced key_info->flags with key_info->actual_flags @ sql/sql_planner.cc Optimize_table_order::best_access_path(): replaced key_info->key_parts with key_info->actual_key_parts replaced key_info->flags with key_info->actual_flags @ sql/sql_select.cc create_ref_for_key(): replaced key_info->key_parts with key_info->actual_key_parts replaced key_info->flags with key_info->actual_flags @ sql/sql_table.cc mysql_prepare_create_table(): added initialization of key_info->actual_key_parts, key_info->actual_flags @ sql/sql_tmp_table.cc create_tmp_table(), create_duplicate_weedout_tmp_table(): added initialization of key_info->actual_key_parts, key_info->actual_flags @ sql/structs.h added actual_flags, actual_key_parts, hidden_key_parts to KEY struct @ sql/table.cc open_binary_frm() function added code which extends secondary keys for InnoDB tables open_table_from_share() function added code which copies extended parts from TABLE_SHARE to TABLE struct calculate_key_len() replaced key_info->key_parts with key_info->actual_key_parts TABLE::add_tmp_key() added initialization of key_info->actual_key_parts, key_info->actual_flags @ sql/table.h added actual_key_parts field to the TABLE_SHARE struct @ storage/innobase/handler/ha_innodb.cc ha_innobase::records_in_range(), ha_innobase::info_low(): replaced key_info->key_parts with key_info->actual_key_parts added: mysql-test/r/innodb_pk_extention.result mysql-test/t/innodb_pk_extention.test modified: mysql-test/suite/innodb/r/innodb_mysql.result mysql-test/suite/opt_trace/r/range_no_prot.result mysql-test/suite/opt_trace/r/range_ps_prot.result sql/handler.cc sql/opt_range.cc sql/opt_sum.cc sql/sql_optimizer.cc sql/sql_planner.cc sql/sql_select.cc sql/sql_table.cc sql/sql_tmp_table.cc sql/structs.h sql/table.cc sql/table.h storage/innobase/handler/ha_innodb.cc === modified file 'mysql-test/r/innodb_pk_extention.result' --- a/mysql-test/r/innodb_pk_extention.result 2012-09-20 05:08:10 +0000 +++ b/mysql-test/r/innodb_pk_extention.result 2012-09-20 11:32:21 +0000 @@ -44,6 +44,7 @@ INSERT INTO t1 VALUES INSERT INTO t1 SELECT pk_1 + 60, pk_2, f1, f2 FROM t1; INSERT INTO t1 SELECT pk_1 + 120, pk_2, f1, f2 FROM t1; INSERT INTO t1 SELECT pk_1 + 240, pk_2, f1, f2 FROM t1; +INSERT INTO t1 SELECT pk_1 + 480, pk_2, f1, f2 FROM t1; REF access optimization @@ -141,7 +142,7 @@ id select_type table type possible_keys FLUSH STATUS; SELECT MAX(pk_1) FROM t1 WHERE f1 = '2000-01-03'; MAX(pk_1) -459 +939 SHOW STATUS LIKE 'handler_read%'; Variable_name Value Handler_read_first 0 @@ -216,13 +217,13 @@ FLUSH STATUS; SELECT count(*) FROM t1 AS t1 JOIN t1 AS t2 ON t2.pk_1 = t1.pk_1 WHERE t1.f1 = '2000-01-03' AND t2.f1 = '2000-01-03'; count(*) -216 +432 SHOW STATUS LIKE 'handler_read%'; Variable_name Value Handler_read_first 0 -Handler_read_key 217 +Handler_read_key 433 Handler_read_last 0 -Handler_read_next 432 +Handler_read_next 864 Handler_read_prev 0 Handler_read_rnd 0 Handler_read_rnd_next 0 === modified file 'mysql-test/suite/opt_trace/r/range_no_prot.result' --- a/mysql-test/suite/opt_trace/r/range_no_prot.result 2012-09-20 05:08:10 +0000 +++ b/mysql-test/suite/opt_trace/r/range_no_prot.result 2012-09-20 11:32:21 +0000 @@ -5221,7 +5221,7 @@ EXPLAIN SELECT v FROM t1 WHERE i1 = 1 AN "index": "v_idx", "rows": 1, "ranges": [ - "a <= v <= a AND 1 <= i1 <= 1" + "a <= v <= a AND 1 <= i1 <= 1 AND pk < 3" ] /* ranges */ } /* range_access_plan */, "rows_for_plan": 1, === modified file 'mysql-test/suite/opt_trace/r/range_ps_prot.result' --- a/mysql-test/suite/opt_trace/r/range_ps_prot.result 2012-09-20 05:08:10 +0000 +++ b/mysql-test/suite/opt_trace/r/range_ps_prot.result 2012-09-20 11:32:21 +0000 @@ -5221,7 +5221,7 @@ EXPLAIN SELECT v FROM t1 WHERE i1 = 1 AN "index": "v_idx", "rows": 1, "ranges": [ - "a <= v <= a AND 1 <= i1 <= 1" + "a <= v <= a AND 1 <= i1 <= 1 AND pk < 3" ] /* ranges */ } /* range_access_plan */, "rows_for_plan": 1, === modified file 'mysql-test/t/innodb_pk_extention.test' --- a/mysql-test/t/innodb_pk_extention.test 2012-09-20 05:08:10 +0000 +++ b/mysql-test/t/innodb_pk_extention.test 2012-09-20 11:32:21 +0000 @@ -52,6 +52,7 @@ INSERT INTO t1 VALUES INSERT INTO t1 SELECT pk_1 + 60, pk_2, f1, f2 FROM t1; INSERT INTO t1 SELECT pk_1 + 120, pk_2, f1, f2 FROM t1; INSERT INTO t1 SELECT pk_1 + 240, pk_2, f1, f2 FROM t1; +INSERT INTO t1 SELECT pk_1 + 480, pk_2, f1, f2 FROM t1; --echo --echo REF access optimization === modified file 'sql/opt_sum.cc' --- a/sql/opt_sum.cc 2012-09-20 05:08:10 +0000 +++ b/sql/opt_sum.cc 2012-09-20 11:32:21 +0000 @@ -909,7 +909,7 @@ static bool find_key_for_maxmin(bool max continue; uint jdx= 0; *prefix_len= 0; - for (part= keyinfo->key_part, part_end= part+keyinfo->actual_key_parts ; + for (part= keyinfo->key_part, part_end= part + keyinfo->actual_key_parts ; part != part_end ; part++, jdx++, key_part_to_use= (key_part_to_use << 1) | 1) { === modified file 'sql/table.cc' --- a/sql/table.cc 2012-09-20 05:08:10 +0000 +++ b/sql/table.cc 2012-09-20 11:32:21 +0000 @@ -1059,6 +1059,7 @@ static int open_binary_frm(THD *thd, TAB if (use_extended_sk && i && !(keyinfo->flags & HA_NOSAME)) { uint pk_part; + uint max_key_length= keyinfo->key_length; /* At this stage keyinfo->actual_flags is used as a sign that extended key can or can not be unique. If it's @@ -1069,6 +1070,8 @@ static int open_binary_frm(THD *thd, TAB keyinfo->actual_flags= HA_NOSAME; for (pk_part= 0; pk_part < share->key_info->key_parts; pk_part++) { + bool max_key_limit_exceeded= false; + KEY_PART_INFO *pk_key_part= &share->key_info->key_part[pk_part]; if (keyinfo->actual_key_parts >= MAX_REF_PARTS) { keyinfo->actual_flags= 0; /* Extended key is not unique */ @@ -1077,18 +1080,29 @@ static int open_binary_frm(THD *thd, TAB for (j= 0; j < keyinfo->key_parts; j++) { - if (keyinfo->key_part[j].fieldnr == - share->key_info->key_part[pk_part].fieldnr) + if (keyinfo->key_part[j].fieldnr == pk_key_part->fieldnr && + keyinfo->key_part[j].length >= pk_key_part->length) break; if (j == keyinfo->key_parts - 1) { - *key_part++= share->key_info->key_part[pk_part]; + /* MySQL does not supports keys longer than MAX_KEY_LENGTH */ + if (max_key_length + pk_key_part->length > MAX_KEY_LENGTH) + { + max_key_limit_exceeded= true; + keyinfo->actual_flags= 0; + break; + } + + *key_part++= *pk_key_part; *rec_per_key++= 0; keyinfo->actual_key_parts++; keyinfo->hidden_key_parts++; + max_key_length+= pk_key_part->length; } } + if (max_key_limit_exceeded) + break; } } share->actual_key_parts+= keyinfo->actual_key_parts; No bundle (reason: useless for push emails).