diff --git a/mysql-test/r/ndb_index_ordered.result b/mysql-test/r/ndb_index_ordered.result index 9aa7559d660..212c843cc44 100644 --- a/mysql-test/r/ndb_index_ordered.result +++ b/mysql-test/r/ndb_index_ordered.result @@ -554,6 +554,89 @@ select count(*)-9 from t1 use index (ts) where ts <= '2001-01-01 23:59:59'; count(*)-9 0 drop table t1; +create table t1 ( +a int primary key, +s decimal(12), +t decimal(12, 5), +u decimal(12) unsigned, +v decimal(12, 5) unsigned, +key (s), +key (t), +key (u), +key (v) +) engine=ndb; +insert into t1 values +( 0, -000000000007, -0000061.00003, 000000000061, 0000965.00042), +( 1, -000000000007, -0000061.00042, 000000000061, 0000965.00003), +( 2, -071006035767, 4210253.00024, 000000000001, 0000001.84488), +( 3, 000000007115, 0000000.77607, 000077350625, 0000018.00013), +( 4, -000000068391, -0346486.00000, 000000005071, 0005334.00002), +( 5, -521579890459, -1936874.00001, 000000000154, 0000003.00018), +( 6, -521579890459, -1936874.00018, 000000000154, 0000003.00001), +( 7, 000000000333, 0000051.39140, 000000907958, 0788643.08374), +( 8, 000042731229, 0000009.00000, 000000000009, 6428667.00000), +( 9, -000008159769, 0000918.00004, 000096951421, 7607730.00008); +select count(*)- 5 from t1 use index (s) where s < -000000000007; +count(*)- 5 +0 +select count(*)- 7 from t1 use index (s) where s <= -000000000007; +count(*)- 7 +0 +select count(*)- 2 from t1 use index (s) where s = -000000000007; +count(*)- 2 +0 +select count(*)- 5 from t1 use index (s) where s >= -000000000007; +count(*)- 5 +0 +select count(*)- 3 from t1 use index (s) where s > -000000000007; +count(*)- 3 +0 +select count(*)- 4 from t1 use index (t) where t < -0000061.00003; +count(*)- 4 +0 +select count(*)- 5 from t1 use index (t) where t <= -0000061.00003; +count(*)- 5 +0 +select count(*)- 1 from t1 use index (t) where t = -0000061.00003; +count(*)- 1 +0 +select count(*)- 6 from t1 use index (t) where t >= -0000061.00003; +count(*)- 6 +0 +select count(*)- 5 from t1 use index (t) where t > -0000061.00003; +count(*)- 5 +0 +select count(*)- 2 from t1 use index (u) where u < 000000000061; +count(*)- 2 +0 +select count(*)- 4 from t1 use index (u) where u <= 000000000061; +count(*)- 4 +0 +select count(*)- 2 from t1 use index (u) where u = 000000000061; +count(*)- 2 +0 +select count(*)- 8 from t1 use index (u) where u >= 000000000061; +count(*)- 8 +0 +select count(*)- 6 from t1 use index (u) where u > 000000000061; +count(*)- 6 +0 +select count(*)- 5 from t1 use index (v) where v < 0000965.00042; +count(*)- 5 +0 +select count(*)- 6 from t1 use index (v) where v <= 0000965.00042; +count(*)- 6 +0 +select count(*)- 1 from t1 use index (v) where v = 0000965.00042; +count(*)- 1 +0 +select count(*)- 5 from t1 use index (v) where v >= 0000965.00042; +count(*)- 5 +0 +select count(*)- 4 from t1 use index (v) where v > 0000965.00042; +count(*)- 4 +0 +drop table t1; create table t1(a int primary key, b int not null, index(b)); insert into t1 values (1,1), (2,2); set autocommit=0; diff --git a/mysql-test/t/ndb_index_ordered.test b/mysql-test/t/ndb_index_ordered.test index bea21f65381..2ebf06b78a8 100644 --- a/mysql-test/t/ndb_index_ordered.test +++ b/mysql-test/t/ndb_index_ordered.test @@ -280,6 +280,58 @@ select count(*)-9 from t1 use index (ts) where ts <= '2001-01-01 23:59:59'; drop table t1; +# decimal (not the new 5.0 thing) + +create table t1 ( + a int primary key, + s decimal(12), + t decimal(12, 5), + u decimal(12) unsigned, + v decimal(12, 5) unsigned, + key (s), + key (t), + key (u), + key (v) +) engine=ndb; +# +insert into t1 values + ( 0, -000000000007, -0000061.00003, 000000000061, 0000965.00042), + ( 1, -000000000007, -0000061.00042, 000000000061, 0000965.00003), + ( 2, -071006035767, 4210253.00024, 000000000001, 0000001.84488), + ( 3, 000000007115, 0000000.77607, 000077350625, 0000018.00013), + ( 4, -000000068391, -0346486.00000, 000000005071, 0005334.00002), + ( 5, -521579890459, -1936874.00001, 000000000154, 0000003.00018), + ( 6, -521579890459, -1936874.00018, 000000000154, 0000003.00001), + ( 7, 000000000333, 0000051.39140, 000000907958, 0788643.08374), + ( 8, 000042731229, 0000009.00000, 000000000009, 6428667.00000), + ( 9, -000008159769, 0000918.00004, 000096951421, 7607730.00008); +# +select count(*)- 5 from t1 use index (s) where s < -000000000007; +select count(*)- 7 from t1 use index (s) where s <= -000000000007; +select count(*)- 2 from t1 use index (s) where s = -000000000007; +select count(*)- 5 from t1 use index (s) where s >= -000000000007; +select count(*)- 3 from t1 use index (s) where s > -000000000007; +# +select count(*)- 4 from t1 use index (t) where t < -0000061.00003; +select count(*)- 5 from t1 use index (t) where t <= -0000061.00003; +select count(*)- 1 from t1 use index (t) where t = -0000061.00003; +select count(*)- 6 from t1 use index (t) where t >= -0000061.00003; +select count(*)- 5 from t1 use index (t) where t > -0000061.00003; +# +select count(*)- 2 from t1 use index (u) where u < 000000000061; +select count(*)- 4 from t1 use index (u) where u <= 000000000061; +select count(*)- 2 from t1 use index (u) where u = 000000000061; +select count(*)- 8 from t1 use index (u) where u >= 000000000061; +select count(*)- 6 from t1 use index (u) where u > 000000000061; +# +select count(*)- 5 from t1 use index (v) where v < 0000965.00042; +select count(*)- 6 from t1 use index (v) where v <= 0000965.00042; +select count(*)- 1 from t1 use index (v) where v = 0000965.00042; +select count(*)- 5 from t1 use index (v) where v >= 0000965.00042; +select count(*)- 4 from t1 use index (v) where v > 0000965.00042; + +drop table t1; + # bug#7798 create table t1(a int primary key, b int not null, index(b)); insert into t1 values (1,1), (2,2); diff --git a/ndb/include/kernel/signaldata/DictTabInfo.hpp b/ndb/include/kernel/signaldata/DictTabInfo.hpp index 61c043f2998..23926374dd6 100644 --- a/ndb/include/kernel/signaldata/DictTabInfo.hpp +++ b/ndb/include/kernel/signaldata/DictTabInfo.hpp @@ -264,7 +264,8 @@ public: ExtBigunsigned = NdbSqlUtil::Type::Bigunsigned, ExtFloat = NdbSqlUtil::Type::Float, ExtDouble = NdbSqlUtil::Type::Double, - ExtDecimal = NdbSqlUtil::Type::Decimal, + ExtOlddecimal = NdbSqlUtil::Type::Olddecimal, + ExtOlddecimalunsigned = NdbSqlUtil::Type::Olddecimalunsigned, ExtChar = NdbSqlUtil::Type::Char, ExtVarchar = NdbSqlUtil::Type::Varchar, ExtBinary = NdbSqlUtil::Type::Binary, @@ -345,9 +346,18 @@ public: AttributeSize = DictTabInfo::a64Bit; AttributeArraySize = AttributeExtLength; break; - case DictTabInfo::ExtDecimal: - // not yet implemented anywhere - return false; + case DictTabInfo::ExtOlddecimal: + AttributeSize = DictTabInfo::an8Bit; + AttributeArraySize = + (1 + AttributeExtPrecision + (int(AttributeExtScale) > 0)) * + AttributeExtLength; + break; + case DictTabInfo::ExtOlddecimalunsigned: + AttributeSize = DictTabInfo::an8Bit; + AttributeArraySize = + (0 + AttributeExtPrecision + (int(AttributeExtScale) > 0)) * + AttributeExtLength; + break; case DictTabInfo::ExtChar: case DictTabInfo::ExtBinary: AttributeSize = DictTabInfo::an8Bit; diff --git a/ndb/include/ndb_constants.h b/ndb/include/ndb_constants.h index da3fc2cbdd8..36d7ec95b3e 100644 --- a/ndb/include/ndb_constants.h +++ b/ndb/include/ndb_constants.h @@ -48,7 +48,7 @@ #define NDB_TYPE_BIGUNSIGNED 10 #define NDB_TYPE_FLOAT 11 #define NDB_TYPE_DOUBLE 12 -#define NDB_TYPE_DECIMAL 13 /* not used */ +#define NDB_TYPE_OLDDECIMAL 13 #define NDB_TYPE_CHAR 14 #define NDB_TYPE_VARCHAR 15 #define NDB_TYPE_BINARY 16 @@ -63,7 +63,8 @@ #define NDB_TYPE_TIME 25 #define NDB_TYPE_YEAR 26 #define NDB_TYPE_TIMESTAMP 27 +#define NDB_TYPE_OLDDECIMALUNSIGNED 28 -#define NDB_TYPE_MAX 28 +#define NDB_TYPE_MAX 29 #endif diff --git a/ndb/include/ndbapi/NdbDictionary.hpp b/ndb/include/ndbapi/NdbDictionary.hpp index 6b9085fbdca..26f0e71b25c 100644 --- a/ndb/include/ndbapi/NdbDictionary.hpp +++ b/ndb/include/ndbapi/NdbDictionary.hpp @@ -184,7 +184,8 @@ public: Bigunsigned = NDB_TYPE_BIGUNSIGNED, ///< 64 Bit. 8 byte signed integer, can be used in array Float = NDB_TYPE_FLOAT, ///< 32-bit float. 4 bytes float, can be used in array Double = NDB_TYPE_DOUBLE, ///< 64-bit float. 8 byte float, can be used in array - Decimal = NDB_TYPE_DECIMAL, ///< Precision, Scale are applicable + Olddecimal = NDB_TYPE_OLDDECIMAL, ///< MySQL < 5.0 signed decimal, Precision, Scale + Olddecimalunsigned = NDB_TYPE_OLDDECIMALUNSIGNED, Char = NDB_TYPE_CHAR, ///< Len. A fixed array of 1-byte chars Varchar = NDB_TYPE_VARCHAR, ///< Length bytes: 1, Max: 255 Binary = NDB_TYPE_BINARY, ///< Len @@ -248,13 +249,13 @@ public: /** * Get precision of column. - * @note Only applicable for builtin type Decimal + * @note Only applicable for decimal types */ int getPrecision() const; /** * Get scale of column. - * @note Only applicable for builtin type Decimal + * @note Only applicable for decimal types */ int getScale() const; @@ -372,13 +373,13 @@ public: /** * Set precision of column. - * @note Only applicable for builtin type Decimal + * @note Only applicable for decimal types */ void setPrecision(int); /** * Set scale of column. - * @note Only applicable for builtin type Decimal + * @note Only applicable for decimal types */ void setScale(int); diff --git a/ndb/include/util/NdbSqlUtil.hpp b/ndb/include/util/NdbSqlUtil.hpp index a8a2979558a..8cf1d166aa9 100644 --- a/ndb/include/util/NdbSqlUtil.hpp +++ b/ndb/include/util/NdbSqlUtil.hpp @@ -80,7 +80,7 @@ public: Bigunsigned = NDB_TYPE_BIGUNSIGNED, Float = NDB_TYPE_FLOAT, Double = NDB_TYPE_DOUBLE, - Decimal = NDB_TYPE_DECIMAL, + Olddecimal = NDB_TYPE_OLDDECIMAL, Char = NDB_TYPE_CHAR, Varchar = NDB_TYPE_VARCHAR, Binary = NDB_TYPE_BINARY, @@ -94,7 +94,8 @@ public: Longvarbinary = NDB_TYPE_LONG_VARBINARY, Time = NDB_TYPE_TIME, Year = NDB_TYPE_YEAR, - Timestamp = NDB_TYPE_TIMESTAMP + Timestamp = NDB_TYPE_TIMESTAMP, + Olddecimalunsigned = NDB_TYPE_OLDDECIMALUNSIGNED }; Enum m_typeId; // redundant Cmp* m_cmp; // comparison method @@ -130,6 +131,11 @@ public: */ static int strnxfrm_bug7284(CHARSET_INFO* cs, unsigned char* dst, unsigned dstLen, const unsigned char*src, unsigned srcLen); + /** + * Compare decimal numbers. + */ + static int cmp_olddecimal(const uchar* s1, const uchar* s2, unsigned n); + private: /** * List of all types. Must match Type::Enum. @@ -150,7 +156,7 @@ private: static Cmp cmpBigunsigned; static Cmp cmpFloat; static Cmp cmpDouble; - static Cmp cmpDecimal; + static Cmp cmpOlddecimal; static Cmp cmpChar; static Cmp cmpVarchar; static Cmp cmpBinary; @@ -165,6 +171,7 @@ private: static Cmp cmpTime; static Cmp cmpYear; static Cmp cmpTimestamp; + static Cmp cmpOlddecimalunsigned; }; #endif diff --git a/ndb/src/common/util/NdbSqlUtil.cpp b/ndb/src/common/util/NdbSqlUtil.cpp index bff829cbaf8..2686ad5c05f 100644 --- a/ndb/src/common/util/NdbSqlUtil.cpp +++ b/ndb/src/common/util/NdbSqlUtil.cpp @@ -77,117 +77,121 @@ NdbSqlUtil::char_like(const char* s1, unsigned n1, const NdbSqlUtil::Type NdbSqlUtil::m_typeList[] = { - { + { // 0 Type::Undefined, NULL }, - { + { // 1 Type::Tinyint, cmpTinyint }, - { + { // 2 Type::Tinyunsigned, cmpTinyunsigned }, - { + { // 3 Type::Smallint, cmpSmallint }, - { + { // 4 Type::Smallunsigned, cmpSmallunsigned }, - { + { // 5 Type::Mediumint, cmpMediumint }, - { + { // 6 Type::Mediumunsigned, cmpMediumunsigned }, - { + { // 7 Type::Int, cmpInt }, - { + { // 8 Type::Unsigned, cmpUnsigned }, - { + { // 9 Type::Bigint, cmpBigint }, - { + { // 10 Type::Bigunsigned, cmpBigunsigned }, - { + { // 11 Type::Float, cmpFloat }, - { + { // 12 Type::Double, cmpDouble }, - { - Type::Decimal, - NULL // cmpDecimal + { // 13 + Type::Olddecimal, + cmpOlddecimal }, - { + { // 14 Type::Char, cmpChar }, - { + { // 15 Type::Varchar, cmpVarchar }, - { + { // 16 Type::Binary, cmpBinary }, - { + { // 17 Type::Varbinary, cmpVarbinary }, - { + { // 18 Type::Datetime, cmpDatetime }, - { + { // 19 Type::Date, cmpDate }, - { + { // 20 Type::Blob, NULL // cmpBlob }, - { + { // 21 Type::Text, NULL // cmpText }, - { + { // 22 Type::Bit, NULL // cmpBit }, - { + { // 23 Type::Longvarchar, cmpLongvarchar }, - { + { // 24 Type::Longvarbinary, cmpLongvarbinary }, - { + { // 25 Type::Time, cmpTime }, - { + { // 26 Type::Year, cmpYear }, - { + { // 27 Type::Timestamp, cmpTimestamp + }, + { // 28 + Type::Olddecimalunsigned, + cmpOlddecimalunsigned } }; @@ -430,14 +434,55 @@ NdbSqlUtil::cmpDouble(const void* info, const void* p1, unsigned n1, const void* return CmpUnknown; } -// not used by MySQL or NDB int -NdbSqlUtil::cmpDecimal(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) +NdbSqlUtil::cmp_olddecimal(const uchar* s1, const uchar* s2, unsigned n) { - assert(false); + int sgn = +1; + unsigned i = 0; + while (i < n) { + int c1 = s1[i]; + int c2 = s2[i]; + if (c1 == c2) { + if (c1 == '-') + sgn = -1; + } else if (c1 == '-') { + return -1; + } else if (c2 == '-') { + return +1; + } else if (c1 < c2) { + return -1 * sgn; + } else { + return +1 * sgn; + } + i++; + } return 0; } +int +NdbSqlUtil::cmpOlddecimal(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) +{ + if (full) { + assert(n1 == n2); + const uchar* v1 = (const uchar*)p1; + const uchar* v2 = (const uchar*)p2; + return cmp_olddecimal(v1, v2, n1); + } + return CmpUnknown; +} + +int +NdbSqlUtil::cmpOlddecimalunsigned(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) +{ + if (full) { + assert(n1 == n2); + const uchar* v1 = (const uchar*)p1; + const uchar* v2 = (const uchar*)p2; + return cmp_olddecimal(v1, v2, n1); + } + return CmpUnknown; +} + int NdbSqlUtil::cmpChar(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) { diff --git a/ndb/src/ndbapi/NdbDictionary.cpp b/ndb/src/ndbapi/NdbDictionary.cpp index 346f5de9eb5..aee0b455b28 100644 --- a/ndb/src/ndbapi/NdbDictionary.cpp +++ b/ndb/src/ndbapi/NdbDictionary.cpp @@ -948,8 +948,11 @@ operator<<(NdbOut& out, const NdbDictionary::Column& col) case NdbDictionary::Column::Double: out << "Double"; break; - case NdbDictionary::Column::Decimal: - out << "Decimal(" << col.getScale() << "," << col.getPrecision() << ")"; + case NdbDictionary::Column::Olddecimal: + out << "Olddecimal(" << col.getPrecision() << "," << col.getScale() << ")"; + break; + case NdbDictionary::Column::Olddecimalunsigned: + out << "Olddecimalunsigned(" << col.getPrecision() << "," << col.getScale() << ")"; break; case NdbDictionary::Column::Char: out << "Char(" << col.getLength() << ";" << csname << ")"; diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp index 9236c3ef321..d67216a9b88 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp @@ -109,7 +109,8 @@ NdbColumnImpl::init(Type t) m_length = 1; m_cs = NULL; break; - case Decimal: + case Olddecimal: + case Olddecimalunsigned: m_precision = 10; m_scale = 0; m_length = 1; diff --git a/ndb/src/ndbapi/NdbRecAttr.cpp b/ndb/src/ndbapi/NdbRecAttr.cpp index 85b08c0cfa4..51ae14653eb 100644 --- a/ndb/src/ndbapi/NdbRecAttr.cpp +++ b/ndb/src/ndbapi/NdbRecAttr.cpp @@ -178,7 +178,8 @@ NdbOut& operator<<(NdbOut& out, const NdbRecAttr &r) return out; } - uint length = r.getColumn()->getLength(); + const NdbDictionary::Column* c = r.getColumn(); + uint length = c->getLength(); if (length > 1) out << "["; @@ -237,6 +238,18 @@ NdbOut& operator<<(NdbOut& out, const NdbRecAttr &r) case NdbDictionary::Column::Double: out << r.double_value(); break; + case NdbDictionary::Column::Olddecimal: + { + short len = 1 + c->getPrecision() + (c->getScale() > 0); + out.print("%.*s", len, r.aRef()); + } + break; + case NdbDictionary::Column::Olddecimalunsigned: + { + short len = 0 + c->getPrecision() + (c->getScale() > 0); + out.print("%.*s", len, r.aRef()); + } + break; // for dates cut-and-paste from field.cc case NdbDictionary::Column::Datetime: { diff --git a/ndb/test/include/NdbSchemaOp.hpp b/ndb/test/include/NdbSchemaOp.hpp index 77e704c0e5c..e8ab542b00a 100644 --- a/ndb/test/include/NdbSchemaOp.hpp +++ b/ndb/test/include/NdbSchemaOp.hpp @@ -567,7 +567,8 @@ convertColumnTypeToAttrType(NdbDictionary::Column::Type _type) case NdbDictionary::Column::Unsigned: return UnSigned; case NdbDictionary::Column::Float: - case NdbDictionary::Column::Decimal: + case NdbDictionary::Column::Olddecimal: + case NdbDictionary::Column::Olddecimalunsigned: case NdbDictionary::Column::Double: return Float; case NdbDictionary::Column::Char: diff --git a/ndb/test/src/HugoCalculator.cpp b/ndb/test/src/HugoCalculator.cpp index 44edb34295a..0a5b9c342c8 100644 --- a/ndb/test/src/HugoCalculator.cpp +++ b/ndb/test/src/HugoCalculator.cpp @@ -145,7 +145,8 @@ HugoCalculator::calcValue(int record, case NdbDictionary::Column::Bigunsigned: case NdbDictionary::Column::Float: case NdbDictionary::Column::Double: - case NdbDictionary::Column::Decimal: + case NdbDictionary::Column::Olddecimal: + case NdbDictionary::Column::Olddecimalunsigned: case NdbDictionary::Column::Binary: case NdbDictionary::Column::Datetime: case NdbDictionary::Column::Time: diff --git a/ndb/tools/restore/consumer.cpp b/ndb/tools/restore/consumer.cpp index 4d228230423..ecbdbbf8f4e 100644 --- a/ndb/tools/restore/consumer.cpp +++ b/ndb/tools/restore/consumer.cpp @@ -44,9 +44,12 @@ BackupConsumer::create_table_string(const TableS & table, case NdbDictionary::Column::Float: pos += sprintf(buf+pos, "%s", "float"); break; - case NdbDictionary::Column::Decimal: + case NdbDictionary::Column::Olddecimal: pos += sprintf(buf+pos, "%s", "decimal"); break; + case NdbDictionary::Column::Olddecimalunsigned: + pos += sprintf(buf+pos, "%s", "decimal unsigned"); + break; case NdbDictionary::Column::Char: pos += sprintf(buf+pos, "%s", "char"); break; diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 58f744438fc..58a34e21f5f 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -3430,10 +3430,6 @@ static int create_ndb_column(NDBCOL &col, const enum enum_field_types mysql_type= field->real_type(); switch (mysql_type) { // Numeric types - case MYSQL_TYPE_DECIMAL: - col.setType(NDBCOL::Char); - col.setLength(field->pack_length()); - break; case MYSQL_TYPE_TINY: if (field->flags & UNSIGNED_FLAG) col.setType(NDBCOL::Tinyunsigned); @@ -3477,6 +3473,26 @@ static int create_ndb_column(NDBCOL &col, col.setType(NDBCOL::Double); col.setLength(1); break; + case MYSQL_TYPE_DECIMAL: + { + Field_decimal *f= (Field_decimal*)field; + uint precision= f->pack_length(); + uint scale= f->decimals(); + if (field->flags & UNSIGNED_FLAG) + { + col.setType(NDBCOL::Olddecimalunsigned); + precision-= (scale > 0); + } + else + { + col.setType(NDBCOL::Olddecimal); + precision-= 1 + (scale > 0); + } + col.setPrecision(precision); + col.setScale(scale); + col.setLength(1); + } + break; // Date types case MYSQL_TYPE_DATETIME: col.setType(NDBCOL::Datetime);