From b3fa1d867f29137240c46a6a0396bb9a1c7019fa Mon Sep 17 00:00:00 2001 From: unknown <heikki@hundin.mysql.fi> Date: Tue, 18 Feb 2003 19:43:41 +0200 Subject: [PATCH] page0cur.c: Prepare for 5.x where HA_READ_PREFIX_LAST may pass only a few first bytes of the last field in a key value ha_innodb.cc: In 4.0 always assume HA_READ_PREFIX_LAST passes a complete-field prefix of a key value; LIKE queries use a padding trick sql/ha_innodb.cc: In 4.0 always assume HA_READ_PREFIX_LAST passes a complete-field prefix of a key value; LIKE queries use a padding trick innobase/page/page0cur.c: Prepare for 5.x where HA_READ_PREFIX_LAST may pass only a few first bytes of the last field in a key value --- innobase/page/page0cur.c | 71 +++++++++++++++++++++++++++++----------- sql/ha_innodb.cc | 4 +-- 2 files changed, 53 insertions(+), 22 deletions(-) diff --git a/innobase/page/page0cur.c b/innobase/page/page0cur.c index 0e65dc8b1d..d3a40668c4 100644 --- a/innobase/page/page0cur.c +++ b/innobase/page/page0cur.c @@ -120,6 +120,53 @@ page_cur_try_search_shortcut( #endif +/******************************************************************** +Checks if the nth field in a record is a character type field which extends +the nth field in tuple, i.e., the field is longer or equal in length and has +common first characters. */ +static +ibool +page_cur_rec_field_extends( +/*=======================*/ + /* out: TRUE if rec field extends tuple + field */ + dtuple_t* tuple, /* in: data tuple */ + rec_t* rec, /* in: record */ + ulint n) /* in: compare nth field */ +{ + dtype_t* type; + dfield_t* dfield; + byte* rec_f; + ulint rec_f_len; + + dfield = dtuple_get_nth_field(tuple, n); + + type = dfield_get_type(dfield); + + rec_f = rec_get_nth_field(rec, n, &rec_f_len); + + if (type->mtype == DATA_VARCHAR + || type->mtype == DATA_CHAR + || type->mtype == DATA_FIXBINARY + || type->mtype == DATA_BINARY + || type->mtype == DATA_BLOB + || type->mtype == DATA_VARMYSQL + || type->mtype == DATA_MYSQL) { + + if (dfield_get_len(dfield) != UNIV_SQL_NULL + && rec_f_len != UNIV_SQL_NULL + && rec_f_len >= dfield_get_len(dfield) + && 0 == cmp_data_data_slow(type, dfield_get_data(dfield), + dfield_get_len(dfield), + rec_f, dfield_get_len(dfield))) { + + return(TRUE); + } + } + + return(FALSE); +} + /******************************************************************** Searches the right position for a page cursor. */ @@ -239,16 +286,8 @@ page_cur_search_with_match( } else if (cmp == -1) { if (mode == PAGE_CUR_LE_OR_EXTENDS - && dfield_get_len(dtuple_get_nth_field(tuple, - cur_matched_fields)) - == cur_matched_bytes - && rec_get_nth_field_len(mid_rec, - cur_matched_fields) - != UNIV_SQL_NULL) { - - /* This means current dfield is not SQL - NULL, and the current rec field extends it */ - + && page_cur_rec_field_extends(tuple, mid_rec, + cur_matched_fields)) { low = mid; low_matched_fields = cur_matched_fields; low_matched_bytes = cur_matched_bytes; @@ -296,16 +335,8 @@ page_cur_search_with_match( } else if (cmp == -1) { if (mode == PAGE_CUR_LE_OR_EXTENDS - && dfield_get_len(dtuple_get_nth_field(tuple, - cur_matched_fields)) - == cur_matched_bytes - && rec_get_nth_field_len(mid_rec, - cur_matched_fields) - != UNIV_SQL_NULL) { - - /* This means current dfield is not SQL - NULL, and the current rec field extends it */ - + && page_cur_rec_field_extends(tuple, mid_rec, + cur_matched_fields)) { low_rec = mid_rec; low_matched_fields = cur_matched_fields; low_matched_bytes = cur_matched_bytes; diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index fce9500a47..3ceb5cbeb3 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -2256,8 +2256,8 @@ convert_search_mode_to_innobase( case HA_READ_BEFORE_KEY: return(PAGE_CUR_L); case HA_READ_PREFIX: return(PAGE_CUR_GE); case HA_READ_PREFIX_LAST: return(PAGE_CUR_LE); - /* In MySQL HA_READ_PREFIX and HA_READ_PREFIX_LAST always - use a complete-field-prefix of a kay value as the search + /* In MySQL-4.0 HA_READ_PREFIX and HA_READ_PREFIX_LAST always + pass a complete-field-prefix of a key value as the search tuple. I.e., it is not allowed that the last field would just contain n first bytes of the full field value. MySQL uses a 'padding' trick to convert LIKE 'abc%' -- 2.30.9