List:Commits« Previous MessageNext Message »
From:Christopher Powers Date:January 22 2009 6:06pm
Subject:bzr commit into mysql-6.0-falcon-team branch (christopher.powers:2970)
Bug#39678
View as plain text  
#At file:///home/cpowers/work/dev/dev-03/mysql/

 2970 Christopher Powers	2009-01-22 [merge]
      Bug #39678 Assertion (bdb) fails in IndexRootPage::indexMerge during recovery
      
      Fixed bug in SRLUpdateIndex.
added:
  mysql-test/suite/falcon/r/falcon_bug_40607.result
  mysql-test/suite/falcon/r/falcon_bug_41582.result
  mysql-test/suite/falcon/r/falcon_bug_42196.result
  mysql-test/suite/falcon/t/falcon_bug_40607.test
  mysql-test/suite/falcon/t/falcon_bug_41582.test
  mysql-test/suite/falcon/t/falcon_bug_42196.test
modified:
  storage/falcon/SRLUpdateIndex.cpp
  storage/falcon/StorageDatabase.cpp
  storage/falcon/StorageTableShare.h
  storage/falcon/ha_falcon.cpp

per-file messages:
  storage/falcon/SRLUpdateIndex.cpp
    SRLUpdateIndex::append() - Use local indexId rather than class member.
=== added file 'mysql-test/suite/falcon/r/falcon_bug_40607.result'
--- a/mysql-test/suite/falcon/r/falcon_bug_40607.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/falcon/r/falcon_bug_40607.result	2009-01-20 08:09:02 +0000
@@ -0,0 +1,20 @@
+*** Bug #40607 ***
+SET @@storage_engine = 'Falcon';
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (id decimal unsigned, key (id));
+INSERT INTO t1 VALUES (5),(6),(7), (8), (9);
+SELECT * FROM t1 WHERE id < 7;
+id
+5
+6
+SELECT * FROM t1 WHERE id = 7;
+id
+7
+SELECT * FROM t1 WHERE id > 7;
+id
+8
+9
+SELECT count(*) FROM t1;
+count(*)
+5
+DROP TABLE t1;

=== added file 'mysql-test/suite/falcon/r/falcon_bug_41582.result'
--- a/mysql-test/suite/falcon/r/falcon_bug_41582.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/falcon/r/falcon_bug_41582.result	2009-01-20 08:09:02 +0000
@@ -0,0 +1,142 @@
+*** Bug #41582 ***
+SET @@storage_engine = 'Falcon';
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1(id decimal(11,0), key(id));
+INSERT INTO t1 VALUES (4299999998), (4299999999), (4300000000), (4300000001), (4300000002);
+SELECT count(*) FROM t1;
+count(*)
+5
+SELECT * FROM t1 WHERE id > 4300000000;
+id
+4300000001
+4300000002
+SELECT * FROM t1 WHERE id = 4300000000;
+id
+4300000000
+SELECT * FROM t1 WHERE id < 4300000000;
+id
+4299999998
+4299999999
+DROP TABLE t1;
+CREATE TABLE t1(id numeric(11), key(id));
+INSERT INTO t1 VALUES (4299999998), (4299999999), (4300000000), (4300000001), (4300000002);
+SELECT count(*) FROM t1;
+count(*)
+5
+SELECT * FROM t1 WHERE id > 4300000000;
+id
+4300000001
+4300000002
+SELECT * FROM t1 WHERE id = 4300000000;
+id
+4300000000
+SELECT * FROM t1 WHERE id < 4300000000;
+id
+4299999998
+4299999999
+DROP TABLE t1;
+CREATE TABLE t1(id decimal(11,0), key(id));
+INSERT INTO t1 VALUES (11), (12), (13), (14), (15);
+SELECT count(*) FROM t1;
+count(*)
+5
+SELECT * FROM t1 WHERE id > 13;
+id
+14
+15
+SELECT * FROM t1 WHERE id = 13;
+id
+13
+SELECT * FROM t1 WHERE id < 13;
+id
+11
+12
+DROP TABLE t1;
+CREATE TABLE t1(id numeric(11), key(id));
+INSERT INTO t1 VALUES (11), (12), (13), (14), (15);
+SELECT count(*) FROM t1;
+count(*)
+5
+SELECT * FROM t1 WHERE id > 13;
+id
+14
+15
+SELECT * FROM t1 WHERE id = 13;
+id
+13
+SELECT * FROM t1 WHERE id < 13;
+id
+11
+12
+DROP TABLE t1;
+CREATE TABLE t1(id decimal(13,3), key(id));
+INSERT INTO t1 VALUES (4299999998.123), (4299999998.125), (4300000000.123), (4300000000.125), (4300000002.123);
+SELECT count(*) FROM t1;
+count(*)
+5
+SELECT * FROM t1 WHERE id > 4300000000.123;
+id
+4300000000.125
+4300000002.123
+SELECT * FROM t1 WHERE id = 4300000000.123;
+id
+4300000000.123
+SELECT * FROM t1 WHERE id < 4300000000.123;
+id
+4299999998.123
+4299999998.125
+DROP TABLE t1;
+CREATE TABLE t1(id numeric(13,3), key(id));
+INSERT INTO t1 VALUES (4299999998.123), (4299999998.125), (4300000000.123), (4300000000.125), (4300000002.123);
+SELECT count(*) FROM t1;
+count(*)
+5
+SELECT * FROM t1 WHERE id > 4300000000.123;
+id
+4300000000.125
+4300000002.123
+SELECT * FROM t1 WHERE id = 4300000000.123;
+id
+4300000000.123
+SELECT * FROM t1 WHERE id < 4300000000.123;
+id
+4299999998.123
+4299999998.125
+DROP TABLE t1;
+CREATE TABLE t1(id decimal(7,2), key(id));
+INSERT INTO t1 VALUES (12.75), (13.10), (13.15), (13.27), (15.01);
+SELECT count(*) FROM t1;
+count(*)
+5
+SELECT * FROM t1 WHERE id > 13.15;
+id
+13.27
+15.01
+SELECT * FROM t1 WHERE id = 13.15;
+id
+13.15
+SELECT * FROM t1 WHERE id < 13.15;
+id
+12.75
+13.10
+DROP TABLE t1;
+CREATE TABLE t1(id numeric(7,2), key(id));
+INSERT INTO t1 VALUES (12.75), (13.10), (13.15), (13.27), (15.01);
+SELECT count(*) FROM t1;
+count(*)
+5
+SELECT * FROM t1 WHERE id > 13.15;
+id
+13.27
+15.01
+SELECT * FROM t1 WHERE id = 13.15;
+id
+13.15
+SELECT * FROM t1 WHERE id < 13.15;
+id
+12.75
+13.10
+SELECT count(*) FROM t1;
+count(*)
+5
+DROP TABLE t1;

=== added file 'mysql-test/suite/falcon/r/falcon_bug_42196.result'
--- a/mysql-test/suite/falcon/r/falcon_bug_42196.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/falcon/r/falcon_bug_42196.result	2009-01-21 16:48:25 +0000
@@ -0,0 +1,18 @@
+*** Bug #42196 ***
+SET @@storage_engine = 'Falcon';
+DROP TABLE IF EXISTS t1;
+DROP FUNCTION IF EXISTS f1;
+CREATE TABLE t1 (s1 bit(3), key(s1));
+CREATE FUNCTION f1() RETURNS int RETURN 1;
+INSERT INTO t1 VALUES (2*f1());
+SELECT s1+0 FROM t1 WHERE s1 = 2;
+s1+0
+2
+SELECT s1+0 from t1;
+s1+0
+2
+SELECT count(*) FROM t1;
+count(*)
+1
+DROP TABLE t1;
+DROP FUNCTION f1;

=== added file 'mysql-test/suite/falcon/t/falcon_bug_40607.test'
--- a/mysql-test/suite/falcon/t/falcon_bug_40607.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/falcon/t/falcon_bug_40607.test	2009-01-20 08:09:02 +0000
@@ -0,0 +1,35 @@
+--source include/have_falcon.inc
+
+#
+# Bug #40607: Falcon unsigned indexes broken
+#
+--echo *** Bug #40607 ***
+
+# ----------------------------------------------------- #
+# --- Initialisation                                --- #
+# ----------------------------------------------------- #
+let $engine = 'Falcon';
+eval SET @@storage_engine = $engine;
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+# ----------------------------------------------------- #
+# --- Test                                          --- #
+# ----------------------------------------------------- #
+CREATE TABLE t1 (id decimal unsigned, key (id));
+INSERT INTO t1 VALUES (5),(6),(7), (8), (9);
+SELECT * FROM t1 WHERE id < 7;
+SELECT * FROM t1 WHERE id = 7;
+SELECT * FROM t1 WHERE id > 7;
+
+# ----------------------------------------------------- #
+# --- Check                                         --- #
+# ----------------------------------------------------- #
+SELECT count(*) FROM t1;
+
+# ----------------------------------------------------- #
+# --- Final cleanup                                 --- #
+# ----------------------------------------------------- #
+DROP TABLE t1;											

=== added file 'mysql-test/suite/falcon/t/falcon_bug_41582.test'
--- a/mysql-test/suite/falcon/t/falcon_bug_41582.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/falcon/t/falcon_bug_41582.test	2009-01-20 08:09:02 +0000
@@ -0,0 +1,107 @@
+--source include/have_falcon.inc
+
+#
+# Bug #41582: Falcon index access returns no result for indexes with
+# numeric datatype
+#
+--echo *** Bug #41582 ***
+
+# ----------------------------------------------------- #
+# --- Initialisation                                --- #
+# ----------------------------------------------------- #
+let $engine = 'Falcon';
+eval SET @@storage_engine = $engine;
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+# ----------------------------------------------------- #
+# --- Test                                          --- #
+# ----------------------------------------------------- #
+
+# Testing first for the decimal type, then for the numeric type, which both map
+# the same internal type.
+
+# Using values with a precision greater than 9, because these will
+# not fit within a group of 4 bytes. For more information about the
+# storage representation of the decimal type, please see:
+#
+# http://dev.mysql.com/doc/refman/6.0/en/precision-math-decimal-changes.html
+#
+CREATE TABLE t1(id decimal(11,0), key(id));
+INSERT INTO t1 VALUES (4299999998), (4299999999), (4300000000), (4300000001), (4300000002);
+SELECT count(*) FROM t1;
+SELECT * FROM t1 WHERE id > 4300000000;
+SELECT * FROM t1 WHERE id = 4300000000;
+SELECT * FROM t1 WHERE id < 4300000000;
+DROP TABLE t1;
+
+CREATE TABLE t1(id numeric(11), key(id));
+INSERT INTO t1 VALUES (4299999998), (4299999999), (4300000000), (4300000001), (4300000002);
+SELECT count(*) FROM t1;
+SELECT * FROM t1 WHERE id > 4300000000;
+SELECT * FROM t1 WHERE id = 4300000000;
+SELECT * FROM t1 WHERE id < 4300000000;
+DROP TABLE t1;
+
+# Testing again using values with a precision less than 9
+CREATE TABLE t1(id decimal(11,0), key(id));
+INSERT INTO t1 VALUES (11), (12), (13), (14), (15);
+SELECT count(*) FROM t1;
+SELECT * FROM t1 WHERE id > 13;
+SELECT * FROM t1 WHERE id = 13;
+SELECT * FROM t1 WHERE id < 13;
+DROP TABLE t1;
+
+CREATE TABLE t1(id numeric(11), key(id));
+INSERT INTO t1 VALUES (11), (12), (13), (14), (15);
+SELECT count(*) FROM t1;
+SELECT * FROM t1 WHERE id > 13;
+SELECT * FROM t1 WHERE id = 13;
+SELECT * FROM t1 WHERE id < 13;
+DROP TABLE t1;
+
+# We also check some numbers with a scale different than 0 just to be
+# on the safe side. We do this for precision both greater than and
+# less than 9
+CREATE TABLE t1(id decimal(13,3), key(id));
+INSERT INTO t1 VALUES (4299999998.123), (4299999998.125), (4300000000.123), (4300000000.125), (4300000002.123);
+SELECT count(*) FROM t1;
+SELECT * FROM t1 WHERE id > 4300000000.123;
+SELECT * FROM t1 WHERE id = 4300000000.123;
+SELECT * FROM t1 WHERE id < 4300000000.123;
+DROP TABLE t1;
+
+CREATE TABLE t1(id numeric(13,3), key(id));
+INSERT INTO t1 VALUES (4299999998.123), (4299999998.125), (4300000000.123), (4300000000.125), (4300000002.123);
+SELECT count(*) FROM t1;
+SELECT * FROM t1 WHERE id > 4300000000.123;
+SELECT * FROM t1 WHERE id = 4300000000.123;
+SELECT * FROM t1 WHERE id < 4300000000.123;
+DROP TABLE t1;
+
+CREATE TABLE t1(id decimal(7,2), key(id));
+INSERT INTO t1 VALUES (12.75), (13.10), (13.15), (13.27), (15.01);
+SELECT count(*) FROM t1;
+SELECT * FROM t1 WHERE id > 13.15;
+SELECT * FROM t1 WHERE id = 13.15;
+SELECT * FROM t1 WHERE id < 13.15;
+DROP TABLE t1;
+
+CREATE TABLE t1(id numeric(7,2), key(id));
+INSERT INTO t1 VALUES (12.75), (13.10), (13.15), (13.27), (15.01);
+SELECT count(*) FROM t1;
+SELECT * FROM t1 WHERE id > 13.15;
+SELECT * FROM t1 WHERE id = 13.15;
+SELECT * FROM t1 WHERE id < 13.15;
+
+# ----------------------------------------------------- #
+# --- Check                                         --- #
+# ----------------------------------------------------- #
+SELECT count(*) FROM t1;
+
+# ----------------------------------------------------- #
+# --- Final cleanup                                 --- #
+# ----------------------------------------------------- #
+DROP TABLE t1;

=== added file 'mysql-test/suite/falcon/t/falcon_bug_42196.test'
--- a/mysql-test/suite/falcon/t/falcon_bug_42196.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/falcon/t/falcon_bug_42196.test	2009-01-21 16:48:25 +0000
@@ -0,0 +1,42 @@
+--source include/have_falcon.inc
+
+#
+# Bug #42196: Issue with key look up for bit field in Falcon table after insert + stored func
+#
+--echo *** Bug #42196 ***
+
+# ----------------------------------------------------- #
+# --- Initialisation                                --- #
+# ----------------------------------------------------- #
+let $engine = 'Falcon';
+eval SET @@storage_engine = $engine;
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP FUNCTION IF EXISTS f1;
+--enable_warnings
+
+# ----------------------------------------------------- #
+# --- Test                                          --- #
+# ----------------------------------------------------- #
+
+CREATE TABLE t1 (s1 bit(3), key(s1));
+CREATE FUNCTION f1() RETURNS int RETURN 1;
+INSERT INTO t1 VALUES (2*f1());
+
+# Following tatement failed to return any rows
+SELECT s1+0 FROM t1 WHERE s1 = 2;
+
+# Following statement returns row with value '2'
+SELECT s1+0 from t1;
+
+# ----------------------------------------------------- #
+# --- Check                                         --- #
+# ----------------------------------------------------- #
+SELECT count(*) FROM t1;
+
+# ----------------------------------------------------- #
+# --- Final cleanup                                 --- #
+# ----------------------------------------------------- #
+DROP TABLE t1;
+DROP FUNCTION f1;

=== modified file 'storage/falcon/SRLUpdateIndex.cpp'
--- a/storage/falcon/SRLUpdateIndex.cpp	2009-01-22 07:32:08 +0000
+++ b/storage/falcon/SRLUpdateIndex.cpp	2009-01-22 18:06:25 +0000
@@ -53,10 +53,10 @@ void SRLUpdateIndex::append(DeferredInde
 
 	// A null index or indexId == -1 means that the index has been deleted
 	
-	if (!index || indexId == -1)
+	if (!index || index->indexId == -1)
 		return;
 	
-	uint indexId = index->indexId;
+	int idxId = index->indexId;
 	int idxVersion = index->indexVersion;
 	int tableSpaceId = index->dbb->tableSpaceId;
 
@@ -77,7 +77,7 @@ void SRLUpdateIndex::append(DeferredInde
 		if (virtualOffset == 0)
 			virtualOffset = log->startRecordVirtualOffset;
 
-		log->updateIndexUseVector(indexId, tableSpaceId, 1);
+		log->updateIndexUseVector(idxId, tableSpaceId, 1);
 		SerialLogTransaction *srlTrans = log->getTransaction(transaction->transactionId);
 		srlTrans->setTransaction(transaction);
 		ASSERT(transaction->writePending);
@@ -86,7 +86,7 @@ void SRLUpdateIndex::append(DeferredInde
 		
 		putInt(tableSpaceId);
 		putInt(transaction->transactionId);
-		putInt(indexId);
+		putInt(idxId);
 		putInt(idxVersion);
 		
 		// Initialize the length field, adjust with correct length later.
@@ -112,7 +112,7 @@ void SRLUpdateIndex::append(DeferredInde
 			}
 		
 		int len = (int) (log->writePtr - start);
-		//printf("SRLUpdateIndex::append tid %d, index %d, length %d, ptr %x (%x)\n",  transaction->transactionId, indexId, len, lengthPtr, org);
+		//printf("SRLUpdateIndex::append tid %d, index %d, length %d, ptr %x (%x)\n",  transaction->transactionId, idxId, len, lengthPtr, org);
 		ASSERT(len >= 0);
 
 		// Update the length field

=== modified file 'storage/falcon/StorageDatabase.cpp'
--- a/storage/falcon/StorageDatabase.cpp	2009-01-08 09:05:26 +0000
+++ b/storage/falcon/StorageDatabase.cpp	2009-01-20 08:09:02 +0000
@@ -947,10 +947,10 @@ void StorageDatabase::validateCache(void
 int StorageDatabase::getSegmentValue(StorageSegment* segment, const UCHAR* ptr, Value* value, Field *field)
 {
 	int length = segment->length;
-	
-	switch (segment->type)
+
+	switch (segment->keyFormat)
 		{
-		case HA_KEYTYPE_LONG_INT:
+		case KEY_FORMAT_LONG_INT:
 			{
 			int32 temp = (int32)
 				(((int32) ((UCHAR) ptr[0])) +
@@ -961,7 +961,7 @@ int StorageDatabase::getSegmentValue(Sto
 			}
 			break;
 
-		case HA_KEYTYPE_SHORT_INT:
+		case KEY_FORMAT_SHORT_INT:
 			{
 			short temp = (int16)
 				(((short) ((UCHAR) ptr[0])) +
@@ -970,8 +970,8 @@ int StorageDatabase::getSegmentValue(Sto
 			}
 			break;
 
-		case HA_KEYTYPE_ULONGLONG:
-		case HA_KEYTYPE_LONGLONG:
+		case KEY_FORMAT_ULONGLONG:
+		case KEY_FORMAT_LONGLONG:
 			{
 			int64 temp = (int64)
 				((uint64)(((uint32) ((UCHAR) ptr[0])) +
@@ -987,7 +987,7 @@ int StorageDatabase::getSegmentValue(Sto
 			}
 			break;
 				
-		case HA_KEYTYPE_FLOAT:
+		case KEY_FORMAT_FLOAT:
 			{
 			float temp;
 #ifdef _BIG_ENDIAN
@@ -1002,7 +1002,7 @@ int StorageDatabase::getSegmentValue(Sto
 			}
 			break;
 		
-		case HA_KEYTYPE_DOUBLE:
+		case KEY_FORMAT_DOUBLE:
 			{
 			double temp;
 #ifdef _BIG_ENDIAN
@@ -1020,11 +1020,9 @@ int StorageDatabase::getSegmentValue(Sto
 			value->setValue(temp);
 			}
 			break;
-		
-		case HA_KEYTYPE_VARBINARY1:
-		case HA_KEYTYPE_VARBINARY2:
-		case HA_KEYTYPE_VARTEXT1:
-		case HA_KEYTYPE_VARTEXT2:
+			
+		case KEY_FORMAT_VARBINARY:		
+		case KEY_FORMAT_VARTEXT:
 			{
 			unsigned short len = (unsigned short)
                         	(((short) ((UCHAR) ptr[0])) +
@@ -1033,45 +1031,32 @@ int StorageDatabase::getSegmentValue(Sto
 			length += 2;
 			}
 			break;
-		
-		case HA_KEYTYPE_BINARY:
-			if (field->isString())
-				value->setString(length, (const char*) ptr, false);
-			else if (segment->isUnsigned)
-				{
-				int64 number = 0;
-				
-				for (int n = 0; n < length; ++n)
-					number = number << 8 | *ptr++;
-					
-				value->setValue(number);
-				}
-			else if (field->precision < 19 && field->scale == 0)
-				{
-				int64 number = (signed char) (*ptr++ ^ 0x80);
-				
-				for (int n = 1; n < length; ++n)
-					number = (number << 8) | *ptr++;
-				
-				if (number < 0)
-					++number;
-					
-				value->setValue(number);
-				}
-			else
-				{
-				BigInt bigInt;
-				ScaledBinary::getBigIntFromBinaryDecimal((const char*) ptr, field->precision, field->scale, &bigInt);
-				value->setValue(&bigInt);
-				}
 
+		case KEY_FORMAT_TEXT:
+		case KEY_FORMAT_BINARY_STRING:
+			value->setString(length, (const char*) ptr, false);
+			break;
+
+		case KEY_FORMAT_BINARY_NEWDECIMAL:
+			{		
+			BigInt bigInt;
+			ScaledBinary::getBigIntFromBinaryDecimal((const char*) 
+													 ptr, field->precision, field->scale, &bigInt);
+			value->setValue(&bigInt);
+			}
 			break;
+		case KEY_FORMAT_BINARY_INTEGER:
+			{
+			int64 number = 0;
 			
-		case HA_KEYTYPE_TEXT:
-			value->setString(length, (const char*) ptr, false);
+			for (int n = 0; n < length; ++n)
+				number = number << 8 | *ptr++;
+			
+			value->setValue(number);
+			}
 			break;
-		
-		case HA_KEYTYPE_ULONG_INT:
+	
+		case KEY_FORMAT_ULONG_INT:
 			{
 			uint32 temp = (uint32)
 				(((uint32) ((UCHAR) ptr[0])) +
@@ -1079,18 +1064,27 @@ int StorageDatabase::getSegmentValue(Sto
 				(((uint32) ((UCHAR) ptr[2]) << 16)) +
 				(((uint32) ((UCHAR) ptr[3]) << 24)));
 			
-			if (field && field->type == Timestamp)
-				value->setValue((int64) temp * 1000);
-			else
 				value->setValue((int64) temp);
 			}
 			break;
+
+		case KEY_FORMAT_TIMESTAMP:
+			{
+			uint32 temp = (uint32)
+				(((uint32) ((UCHAR) ptr[0])) +
+				(((uint32) ((UCHAR) ptr[1]) << 8)) +
+				(((uint32) ((UCHAR) ptr[2]) << 16)) +
+				(((uint32) ((UCHAR) ptr[3]) << 24)));
+			
+				value->setValue((int64) temp * 1000);
+			}
+			break;
 		
-		case HA_KEYTYPE_INT8:
+		case KEY_FORMAT_INT8:
 			value->setValue(*(signed char*) ptr);
 			break;
 		
-		case HA_KEYTYPE_USHORT_INT:
+		case KEY_FORMAT_USHORT_INT:
 			{
 			unsigned short temp = (unsigned short)
 				(((uint16) ((UCHAR) ptr[0])) +
@@ -1099,7 +1093,7 @@ int StorageDatabase::getSegmentValue(Sto
 			}
 			break;
 			
-		case HA_KEYTYPE_UINT24:
+		case KEY_FORMAT_UINT24:
 			{
 			uint32 temp = (uint32)
 				(((uint32) ((UCHAR) ptr[0])) +
@@ -1109,7 +1103,7 @@ int StorageDatabase::getSegmentValue(Sto
 			}
 			break;
 			
-		case HA_KEYTYPE_INT24:
+		case KEY_FORMAT_INT24:
 			{
 			int32 temp = (int32)
 				((((UCHAR) ptr[2]) & 128) ?

=== modified file 'storage/falcon/StorageTableShare.h'
--- a/storage/falcon/StorageTableShare.h	2008-11-05 14:51:37 +0000
+++ b/storage/falcon/StorageTableShare.h	2009-01-21 16:48:25 +0000
@@ -38,13 +38,35 @@ class Sequence;
 class SyncObject;
 class Format;
 
+enum KeyFormat {
+	KEY_FORMAT_LONG_INT = 1,
+	KEY_FORMAT_SHORT_INT,
+	KEY_FORMAT_LONGLONG,
+	KEY_FORMAT_ULONGLONG,
+	KEY_FORMAT_FLOAT,
+	KEY_FORMAT_DOUBLE,
+	KEY_FORMAT_VARBINARY,
+	KEY_FORMAT_VARTEXT,
+	KEY_FORMAT_BINARY_STRING,
+	KEY_FORMAT_BINARY_NEWDECIMAL,
+	KEY_FORMAT_BINARY_INTEGER,
+	KEY_FORMAT_TEXT,
+	KEY_FORMAT_ULONG_INT,
+	KEY_FORMAT_TIMESTAMP,
+	KEY_FORMAT_INT8,
+	KEY_FORMAT_USHORT_INT,
+	KEY_FORMAT_UINT24,
+	KEY_FORMAT_INT24,
+	KEY_FORMAT_OTHER
+};
+
 struct StorageSegment {
 	short			type;
+	KeyFormat       keyFormat;
 	short			nullPosition;
 	int				offset;
 	int				length;
 	unsigned char	nullBit;
-	char			isUnsigned;
 	void			*mysql_charset;
 	};
 

=== modified file 'storage/falcon/ha_falcon.cpp'
--- a/storage/falcon/ha_falcon.cpp	2009-01-16 18:02:24 +0000
+++ b/storage/falcon/ha_falcon.cpp	2009-01-21 16:48:25 +0000
@@ -1586,21 +1586,104 @@ void StorageInterface::getKeyDesc(TABLE 
 		segment->length	= part->length;
 		segment->type	= part->field->key_type();
 		segment->nullBit = part->null_bit;
-		segment->isUnsigned = (part->field->flags & ENUM_FLAG) ?
-			true : ((Field_num*) part->field)->unsigned_flag;
+		segment->mysql_charset = NULL;
 
+		// Separate correctly between types that may map to
+		// the same key type, but that should be treated differently.
+		// This way StorageInterface::getSegmentValue only have
+		// to switch on the keyFormat, and the logic needed at runtime
+		// is minimal.
+		// Also set the correct charset where appropriate.
 		switch (segment->type)
 			{
-			case HA_KEYTYPE_TEXT:
-			case HA_KEYTYPE_VARTEXT1:
-			case HA_KEYTYPE_VARTEXT2:
+			case HA_KEYTYPE_LONG_INT:
+				segment->keyFormat = KEY_FORMAT_LONG_INT;
+				break;
+				
+			case HA_KEYTYPE_SHORT_INT:
+				segment->keyFormat = KEY_FORMAT_SHORT_INT;
+				break;
+				
+			case HA_KEYTYPE_ULONGLONG:
+				segment->keyFormat = KEY_FORMAT_ULONGLONG;
+				break;
+
+			case HA_KEYTYPE_LONGLONG:
+				segment->keyFormat = KEY_FORMAT_LONGLONG;
+				break;
+				
+			case HA_KEYTYPE_FLOAT:
+				segment->keyFormat = KEY_FORMAT_FLOAT;
+				break;
+				
+			case HA_KEYTYPE_DOUBLE:
+				segment->keyFormat = KEY_FORMAT_DOUBLE;
+				break;
+				
 			case HA_KEYTYPE_VARBINARY1:
 			case HA_KEYTYPE_VARBINARY2:
+				segment->keyFormat = KEY_FORMAT_VARBINARY;
 				segment->mysql_charset = part->field->charset();
 				break;
 
+			case HA_KEYTYPE_VARTEXT1:
+			case HA_KEYTYPE_VARTEXT2:
+				segment->keyFormat = KEY_FORMAT_VARTEXT;
+				segment->mysql_charset = part->field->charset();
+				break;
+				
+			case HA_KEYTYPE_BINARY:
+				switch (part->field->real_type())
+					{
+					case MYSQL_TYPE_TINY:
+					case MYSQL_TYPE_BIT:
+					case MYSQL_TYPE_YEAR:
+					case MYSQL_TYPE_SET:
+					case MYSQL_TYPE_ENUM:
+					case MYSQL_TYPE_DATETIME:
+						segment->keyFormat = KEY_FORMAT_BINARY_INTEGER;
+						break;
+						
+					case MYSQL_TYPE_NEWDECIMAL:
+						segment->keyFormat = KEY_FORMAT_BINARY_NEWDECIMAL;
+						break;
+						
+					default:
+						segment->keyFormat = KEY_FORMAT_BINARY_STRING;
+						break;
+					}
+				break;
+				
+			case HA_KEYTYPE_TEXT:
+				segment->keyFormat = KEY_FORMAT_TEXT;
+				segment->mysql_charset = part->field->charset();
+				break;
+				
+			case HA_KEYTYPE_ULONG_INT:
+				if (part->field->real_type() == MYSQL_TYPE_TIMESTAMP)
+					segment->keyFormat = KEY_FORMAT_TIMESTAMP;
+				else
+					segment->keyFormat = KEY_FORMAT_ULONG_INT;
+				break;
+				
+			case HA_KEYTYPE_INT8:
+				segment->keyFormat = KEY_FORMAT_INT8;
+				break;
+				
+			case HA_KEYTYPE_USHORT_INT:
+				segment->keyFormat = KEY_FORMAT_USHORT_INT;
+				break;
+				
+			case HA_KEYTYPE_UINT24:
+				segment->keyFormat = KEY_FORMAT_UINT24;
+				break;
+				
+			case HA_KEYTYPE_INT24:
+				segment->keyFormat = KEY_FORMAT_INT24;
+				break;
+				
 			default:
-				segment->mysql_charset = NULL;
+				segment->keyFormat = KEY_FORMAT_OTHER;
 			}
 		}
 }

Thread
bzr commit into mysql-6.0-falcon-team branch (christopher.powers:2970)Bug#39678Christopher Powers22 Jan