summaryrefslogtreecommitdiff
path: root/sql/field.cc
diff options
context:
space:
mode:
authorunknown <serg@serg.mylan>2004-08-18 19:57:55 +0200
committerunknown <serg@serg.mylan>2004-08-18 19:57:55 +0200
commit945625ebaa21468fdf0b2a3c1786fca50bdd5aa2 (patch)
tree8ac7985dc9b6caddd1c2402ef8606e4a4cd85ada /sql/field.cc
parent992ff0a27274c0c95da2f4ea1496bb9356201f89 (diff)
parent0c6b96658e96cc604c9c5fedb41a5e43bad4f74b (diff)
downloadmariadb-git-945625ebaa21468fdf0b2a3c1786fca50bdd5aa2.tar.gz
manually merged
BitKeeper/etc/logging_ok: auto-union BitKeeper/deleted/.del-mytest-old.c~5237697b30cf59e4: Auto merged Build-tools/Bootstrap: Auto merged Build-tools/mysql-copyright: Auto merged configure.in: Auto merged BitKeeper/deleted/.del-mysql_fix_privilege_tables.sql: Auto merged VC++Files/innobase/innobase.dsp: Auto merged client/mysql.cc: Auto merged include/my_global.h: Auto merged innobase/dict/dict0crea.c: Auto merged innobase/dict/dict0dict.c: Auto merged innobase/include/mtr0log.h: Auto merged innobase/include/mtr0log.ic: Auto merged innobase/include/srv0srv.h: Auto merged innobase/include/ut0dbg.h: Auto merged innobase/lock/lock0lock.c: Auto merged innobase/os/os0file.c: Auto merged innobase/row/row0mysql.c: Auto merged innobase/row/row0sel.c: Auto merged innobase/srv/srv0srv.c: Auto merged innobase/ut/ut0dbg.c: Auto merged innobase/ut/ut0mem.c: Auto merged libmysql/Makefile.am: Auto merged libmysql/Makefile.shared: Auto merged libmysql/conf_to_src.c: Auto merged libmysql/dll.c: Auto merged libmysql/errmsg.c: Auto merged libmysql/manager.c: Auto merged libmysql_r/Makefile.am: Auto merged myisam/mi_key.c: Auto merged mysql-test/Makefile.am: Auto merged mysql-test/mysql-test-run.sh: Auto merged mysql-test/r/having.result: Auto merged mysql-test/r/heap.result: Auto merged mysql-test/r/type_date.result: Auto merged mysql-test/r/type_float.result: Auto merged mysql-test/t/having.test: Auto merged mysql-test/t/heap.test: Auto merged mysql-test/t/type_date.test: Auto merged mysql-test/t/type_float.test: Auto merged mysql-test/t/type_uint.test: Auto merged scripts/make_binary_distribution.sh: Auto merged scripts/make_win_src_distribution.sh: Auto merged sql/Makefile.am: Auto merged sql/field.h: Auto merged sql/ha_heap.cc: Auto merged sql/item_func.cc: Auto merged sql/item_func.h: Auto merged sql/item_sum.h: Auto merged sql/lock.cc: Auto merged sql/log.cc: Auto merged sql/protocol.cc: Auto merged sql/repl_failsafe.cc: Auto merged sql/sql_acl.cc: Auto merged sql/sql_analyse.cc: Auto merged sql/sql_class.cc: Auto merged sql/sql_class.h: Auto merged sql/sql_parse.cc: Auto merged sql/share/czech/errmsg.txt: Auto merged sql/share/danish/errmsg.txt: Auto merged sql/share/dutch/errmsg.txt: Auto merged sql/share/english/errmsg.txt: Auto merged sql/share/estonian/errmsg.txt: Auto merged sql/share/french/errmsg.txt: Auto merged sql/sql_select.cc: Auto merged sql/sql_table.cc: Auto merged sql/share/greek/errmsg.txt: Auto merged sql/share/hungarian/errmsg.txt: Auto merged sql/share/japanese/errmsg.txt: Auto merged sql/share/korean/errmsg.txt: Auto merged sql/share/norwegian-ny/errmsg.txt: Auto merged sql/share/norwegian/errmsg.txt: Auto merged sql/share/polish/errmsg.txt: Auto merged sql/share/portuguese/errmsg.txt: Auto merged sql/share/romanian/errmsg.txt: Auto merged sql/share/russian/errmsg.txt: Auto merged sql/share/slovak/errmsg.txt: Auto merged sql/share/spanish/errmsg.txt: Auto merged sql/share/swedish/errmsg.txt: Auto merged sql/share/ukrainian/errmsg.txt: Auto merged
Diffstat (limited to 'sql/field.cc')
-rw-r--r--sql/field.cc95
1 files changed, 80 insertions, 15 deletions
diff --git a/sql/field.cc b/sql/field.cc
index af9ad110f0e..4458c14160d 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -46,6 +46,8 @@ template class List_iterator<create_field>;
uchar Field_null::null[1]={1};
const char field_separator=',';
+#define DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE 320
+
/*****************************************************************************
Static help functions
*****************************************************************************/
@@ -876,7 +878,7 @@ int Field_decimal::store(double nr)
reg4 uint i,length;
char fyllchar,*to;
- char buff[320];
+ char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE];
fyllchar = zerofill ? (char) '0' : (char) ' ';
#ifdef HAVE_SNPRINTF
@@ -1751,13 +1753,14 @@ void Field_medium::sql_type(String &res) const
int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
{
long tmp;
- int error= 0;
+ int error= 0, cuted_fields= 0;
char *end;
tmp= cs->cset->scan(cs, from, from+len, MY_SEQ_SPACES);
len-= tmp;
from+= tmp;
my_errno=0;
+
if (unsigned_flag)
{
if (!len || *from == '-')
@@ -1774,6 +1777,34 @@ int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
if (error ||
(from+len != end && table->in_use->count_cuted_fields &&
!test_if_int(from,len,end,cs)))
+ error= 1;
+#if SIZEOF_LONG > 4
+ if (unsigned_flag)
+ {
+ if (tmp > UINT_MAX32)
+ {
+ tmp= UINT_MAX32;
+ error= 1;
+ my_errno=ERANGE;
+ }
+ }
+ else
+ {
+ if (tmp > INT_MAX32)
+ {
+ tmp= INT_MAX32;
+ error= 1;
+ my_errno=ERANGE;
+ }
+ else if (tmp < INT_MIN32)
+ {
+ tmp= INT_MIN32;
+ error= 1;
+ my_errno=ERANGE;
+ }
+ }
+#endif
+ if (error)
{
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
error= 1;
@@ -2695,7 +2726,7 @@ String *Field_double::val_str(String *val_buffer,
#endif
doubleget(nr,ptr);
- uint to_length=max(field_length,320);
+ uint to_length=max(field_length, DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE);
val_buffer->alloc(to_length);
char *to=(char*) val_buffer->ptr();
@@ -2707,7 +2738,8 @@ String *Field_double::val_str(String *val_buffer,
else
{
#ifdef HAVE_FCONVERT
- char buff[320],*pos=buff;
+ char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE],
+ char *pos= buff;
int decpt,sign,tmp_dec=dec;
VOID(fconvert(nr,tmp_dec,&decpt,&sign,buff));
@@ -4232,13 +4264,50 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
}
-int Field_string::store(double nr)
+/*
+ Store double value in Field_string or Field_varstring.
+
+ SYNOPSIS
+ store_double_in_string_field()
+ field field to store value in
+ field_length number of characters in the field
+ nr number
+
+ DESCRIPTION
+ Pretty prints double number into field_length characters buffer.
+*/
+
+static int store_double_in_string_field(Field_str *field, uint32 field_length,
+ double nr)
{
- char buff[MAX_FIELD_WIDTH],*end;
- int width=min(field_length,DBL_DIG+5);
- sprintf(buff,"%-*.*g",width,max(width-5,0),nr);
- end=strcend(buff,' ');
- return Field_string::store(buff,(uint) (end - buff), &my_charset_bin);
+ bool use_scientific_notation=TRUE;
+ char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE];
+ int length;
+ if (field_length < 32 && nr > 1)
+ {
+ if (field->ceiling == 0)
+ {
+ static double e[]= {1e1, 1e2, 1e4, 1e8, 1e16 };
+ double p= 1;
+ for (int i= sizeof(e)/sizeof(e[0]), j= 1<<i ; j; i--, j>>= 1 )
+ {
+ if (field_length & j)
+ p*= e[i];
+ }
+ field->ceiling= p-1;
+ }
+ use_scientific_notation= (field->ceiling < nr);
+ }
+ length= sprintf(buff, "%-.*g",
+ use_scientific_notation ? max(0,field_length-5) : field_length,
+ nr);
+ DBUG_ASSERT(length <= field_length);
+ return field->store(buff, (uint) length);
+}
+
+int Field_string::store(double nr)
+ {
+ return store_double_in_string_field(this, field_length, nr);
}
@@ -4412,11 +4481,7 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
int Field_varstring::store(double nr)
{
- char buff[MAX_FIELD_WIDTH],*end;
- int width=min(field_length,DBL_DIG+5);
- sprintf(buff,"%-*.*g",width,max(width-5,0),nr);
- end=strcend(buff,' ');
- return Field_varstring::store(buff,(uint) (end - buff), &my_charset_bin);
+ return store_double_in_string_field(this, field_length, nr);
}