=== modified file 'mysql-test/suite/ndb/r/ndb_restore_print.result' --- mysql-test/suite/ndb/r/ndb_restore_print.result 2007-12-12 17:19:24 +0000 +++ mysql-test/suite/ndb/r/ndb_restore_print.result 2009-04-07 14:01:28 +0000 @@ -307,3 +307,74 @@ drop table t1; drop table t2; drop table t3; drop table t4; +create table t1 (a int primary key, +normal decimal (20,10), +unormal decimal (20, 10) unsigned, +biggest decimal (65,30), +ubiggest decimal (65,30) unsigned, +small1 decimal (1,0), +usmall1 decimal (1,0) unsigned, +small2 decimal (1,1), +usmall2 decimal (1,1) unsigned) engine=ndb; +insert into t1 values (1, +-9999999999.9999999999, +9999999999.9999999999, +-99999999999999999999999999999999999.999999999999999999999999999999, +99999999999999999999999999999999999.999999999999999999999999999999, +-9, +9, +-0.9, +0.9); +insert into t1 values (2, +-1000000000.0000000001, +1000000000.0000000001, +-10000000000000000000000000000000000.000000000000000000000000000001, +10000000000000000000000000000000000.000000000000000000000000000001, +-1, +1, +-0.1, +0.1); +insert into t1 values (3, +-0099.0099, +0099.0099, +-0.1, +0.1, +-5, +5, +-0.5, +0.5); +select * from t1 order by a; +a 1 +normal -9999999999.9999999999 +unormal 9999999999.9999999999 +biggest -99999999999999999999999999999999999.999999999999999999999999999999 +ubiggest 99999999999999999999999999999999999.999999999999999999999999999999 +small1 -9 +usmall1 9 +small2 -0.9 +usmall2 0.9 +a 2 +normal -1000000000.0000000001 +unormal 1000000000.0000000001 +biggest -10000000000000000000000000000000000.000000000000000000000000000001 +ubiggest 10000000000000000000000000000000000.000000000000000000000000000001 +small1 -1 +usmall1 1 +small2 -0.1 +usmall2 0.1 +a 3 +normal -99.0099000000 +unormal 99.0099000000 +biggest -0.100000000000000000000000000000 +ubiggest 0.100000000000000000000000000000 +small1 -5 +usmall1 5 +small2 -0.5 +usmall2 0.5 +CREATE TEMPORARY TABLE test.backup_info (id INT, backup_id INT) ENGINE = HEAP; +LOAD DATA INFILE 'DUMP_FILE' INTO TABLE test.backup_info FIELDS TERMINATED BY ','; +DROP TABLE test.backup_info; +1;-9999999999.9999999999;9999999999.9999999999;-99999999999999999999999999999999999.999999999999999999999999999999;99999999999999999999999999999999999.999999999999999999999999999999;-9;9;-0.9;0.9 +2;-1000000000.0000000001;1000000000.0000000001;-10000000000000000000000000000000000.000000000000000000000000000001;10000000000000000000000000000000000.000000000000000000000000000001;-1;1;-0.1;0.1 +3;-99.0099000000;99.0099000000;-0.100000000000000000000000000000;0.100000000000000000000000000000;-5;5;-0.5;0.5 +drop table t1; === modified file 'mysql-test/suite/ndb/t/ndb_restore_print.test' --- mysql-test/suite/ndb/t/ndb_restore_print.test 2008-09-30 19:32:35 +0000 +++ mysql-test/suite/ndb/t/ndb_restore_print.test 2009-04-07 13:58:01 +0000 @@ -191,3 +191,58 @@ drop table t1; drop table t2; drop table t3; drop table t4; + +# bug 37171 ndb_restore --print_data garbles decimal data + +create table t1 (a int primary key, + normal decimal (20,10), + unormal decimal (20, 10) unsigned, + biggest decimal (65,30), + ubiggest decimal (65,30) unsigned, + small1 decimal (1,0), + usmall1 decimal (1,0) unsigned, + small2 decimal (1,1), + usmall2 decimal (1,1) unsigned) engine=ndb; + +insert into t1 values (1, + -9999999999.9999999999, + 9999999999.9999999999, + -99999999999999999999999999999999999.999999999999999999999999999999, + 99999999999999999999999999999999999.999999999999999999999999999999, + -9, + 9, + -0.9, + 0.9); +insert into t1 values (2, + -1000000000.0000000001, + 1000000000.0000000001, + -10000000000000000000000000000000000.000000000000000000000000000001, + 10000000000000000000000000000000000.000000000000000000000000000001, + -1, + 1, + -0.1, + 0.1); +insert into t1 values (3, + -0099.0099, + 0099.0099, + -0.1, + 0.1, + -5, + 5, + -0.5, + 0.5); +--vertical_results + +select * from t1 order by a; + +--horizontal_results + +# backup and print +--source include/ndb_backup.inc + +--let ndb_restore_filter=test t1 +--let ndb_restore_opts=--verbose=0 --print_data --hex --fields-terminated-by=";" +--source include/ndb_backup_print.inc + +# clean up +drop table t1; === modified file 'storage/ndb/src/ndbapi/NdbRecAttr.cpp' --- storage/ndb/src/ndbapi/NdbRecAttr.cpp 2008-11-11 11:40:42 +0000 +++ storage/ndb/src/ndbapi/NdbRecAttr.cpp 2009-04-07 14:56:35 +0000 @@ -20,6 +20,9 @@ #include #include "NdbDictionaryImpl.hpp" #include +C_MODE_START +#include +C_MODE_END NdbRecAttr::NdbRecAttr(Ndb*) { @@ -262,6 +265,22 @@ ndbrecattr_print_string(NdbOut& out, con } } +/* Three MySQL defs duplicated here : */ +static const int MaxMySQLDecimalPrecision= 65; +static const int MaxMySQLDecimalScale= 30; +static const int DigitsPerDigit_t= 9; // (Decimal digits in 2^32) + +/* Implications */ +/* Space for -, . and \0 */ +static const int MaxDecimalStrLen= MaxMySQLDecimalPrecision + 3; +static const int IntPartDigit_ts= ((MaxMySQLDecimalPrecision - + MaxMySQLDecimalScale) + + DigitsPerDigit_t -1)/ + DigitsPerDigit_t; +static const int FracPartDigit_ts= (MaxMySQLDecimalScale + DigitsPerDigit_t - 1) / + DigitsPerDigit_t; +static const int DigitArraySize= IntPartDigit_ts + FracPartDigit_ts; + NdbOut& ndbrecattr_print_formatted(NdbOut& out, const NdbRecAttr &r, const NdbRecordPrintFormat &f) @@ -385,8 +404,45 @@ ndbrecattr_print_formatted(NdbOut& out, break; case NdbDictionary::Column::Decimal: case NdbDictionary::Column::Decimalunsigned: - goto unknown; // TODO + { + int precision= c->getPrecision(); + int scale= c->getScale(); + + assert(precision <= MaxMySQLDecimalPrecision); + assert(scale <= MaxMySQLDecimalScale); + assert(decimal_size(precision, scale) <= DigitArraySize ); + decimal_digit_t buff[ DigitArraySize ]; + decimal_t tmpDec; + tmpDec.buf= buff; + decimal_make_zero(&tmpDec); + int rc= 0; + + const uchar* data= (const uchar*) r.aRef(); + if ((rc= bin2decimal(data, &tmpDec, precision, scale))) + { + out.print("***Error : Bad bin2decimal conversion %d ***", + rc); + break; + } + + char decStr[MaxDecimalStrLen]; + assert(decimal_string_size(&tmpDec) <= MaxDecimalStrLen); + int len= MaxDecimalStrLen; + if ((rc= decimal2string(&tmpDec, decStr, + &len, + 0, + 0, + 0))) + { + out.print("***Error : bad decimal2string conversion %d ***", + rc); + break; + } + + out.print("%s", decStr); + break; + } // for dates cut-and-paste from field.cc case NdbDictionary::Column::Datetime: { @@ -510,13 +566,15 @@ ndbrecattr_print_formatted(NdbOut& out, break; case NdbDictionary::Column::Undefined: - unknown: - //default: /* no print functions for the rest, just print type */ - out << (int) r.getType(); - j = length; - if (j > 1) - out << " " << j << " times"; - break; + // Fall through + default: /* no print functions for the rest, just print type */ + out << "Unable to format type (" + << (int) r.getType() + << ")"; + j = length; + if (j > 1) + out << " " << j << " times"; + break; } out << f.fields_enclosed_by; }