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