Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
22a76c1d
Commit
22a76c1d
authored
Feb 22, 2005
by
monty@mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge bk-internal.mysql.com:/home/bk/mysql-4.1
into mysql.com:/home/my/mysql-4.1
parents
c0230f6f
e2dc9b40
Changes
19
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
239 additions
and
103 deletions
+239
-103
client/mysql.cc
client/mysql.cc
+2
-2
include/m_string.h
include/m_string.h
+1
-1
mysql-test/mysql-test-run.sh
mysql-test/mysql-test-run.sh
+2
-1
mysql-test/r/ps_1general.result
mysql-test/r/ps_1general.result
+1
-0
mysql-test/r/type_float.result
mysql-test/r/type_float.result
+33
-1
mysql-test/t/mysql_client_test.test
mysql-test/t/mysql_client_test.test
+7
-0
mysql-test/t/ps_1general.test
mysql-test/t/ps_1general.test
+1
-0
mysql-test/t/type_float.test
mysql-test/t/type_float.test
+25
-1
sql/field.cc
sql/field.cc
+10
-4
sql/item.cc
sql/item.cc
+7
-4
sql/item.h
sql/item.h
+4
-2
sql/item_func.h
sql/item_func.h
+5
-2
sql/item_strfunc.cc
sql/item_strfunc.cc
+2
-1
sql/item_sum.cc
sql/item_sum.cc
+2
-1
sql/item_sum.h
sql/item_sum.h
+4
-2
sql/procedure.h
sql/procedure.h
+8
-3
strings/ctype-simple.c
strings/ctype-simple.c
+3
-24
strings/ctype-ucs2.c
strings/ctype-ucs2.c
+3
-6
strings/strtod.c
strings/strtod.c
+119
-48
No files found.
client/mysql.cc
View file @
22a76c1d
...
...
@@ -2914,9 +2914,9 @@ com_status(String *buffer __attribute__((unused)),
MYSQL_ROW
cur
=
mysql_fetch_row
(
result
);
if
(
cur
)
{
tee_fprintf
(
stdout
,
"Server characterset:
\t
%s
\n
"
,
cur
[
0
]
?
cur
[
2
]
:
""
);
tee_fprintf
(
stdout
,
"Server characterset:
\t
%s
\n
"
,
cur
[
2
]
?
cur
[
2
]
:
""
);
tee_fprintf
(
stdout
,
"Db characterset:
\t
%s
\n
"
,
cur
[
3
]
?
cur
[
3
]
:
""
);
tee_fprintf
(
stdout
,
"Client characterset:
\t
%s
\n
"
,
cur
[
2
]
?
cur
[
0
]
:
""
);
tee_fprintf
(
stdout
,
"Client characterset:
\t
%s
\n
"
,
cur
[
0
]
?
cur
[
0
]
:
""
);
tee_fprintf
(
stdout
,
"Conn. characterset:
\t
%s
\n
"
,
cur
[
1
]
?
cur
[
1
]
:
""
);
}
mysql_free_result
(
result
);
...
...
include/m_string.h
View file @
22a76c1d
...
...
@@ -215,7 +215,7 @@ extern char *strstr(const char *, const char *);
extern
int
is_prefix
(
const
char
*
,
const
char
*
);
/* Conversion routines */
double
my_strtod
(
const
char
*
str
,
char
**
end
);
double
my_strtod
(
const
char
*
str
,
char
**
end
,
int
*
error
);
double
my_atof
(
const
char
*
nptr
);
extern
char
*
llstr
(
longlong
value
,
char
*
buff
);
...
...
mysql-test/mysql-test-run.sh
View file @
22a76c1d
...
...
@@ -444,6 +444,7 @@ while test $# -gt 0; do
--debug=d:t:A,
$MYSQL_TEST_DIR
/var/log/mysqldump.trace"
EXTRA_MYSQLBINLOG_OPT
=
"
$EXTRA_MYSQLBINLOG_OPT
\
--debug=d:t:A,
$MYSQL_TEST_DIR
/var/log/mysqlbinlog.trace"
EXTRA_MYSQL_CLIENT_TEST_OPT
=
"--debug=d:t:A,
$MYSQL_TEST_DIR
/var/log/mysql_client_test.trace"
;;
--fast
)
FAST_START
=
1
...
...
@@ -681,7 +682,7 @@ then
EXTRA_SLAVE_MYSQLD_OPT
=
"
$EXTRA_SLAVE_MYSQLD_OPT
--user=root"
fi
MYSQL_CLIENT_TEST
=
"
$MYSQL_CLIENT_TEST
--no-defaults --testcase --user=root --socket=
$MASTER_MYSOCK
--port=
$MYSQL_TCP_PORT
--silent"
MYSQL_CLIENT_TEST
=
"
$MYSQL_CLIENT_TEST
--no-defaults --testcase --user=root --socket=
$MASTER_MYSOCK
--port=
$MYSQL_TCP_PORT
--silent
$EXTRA_MYSQL_CLIENT_TEST_OPT
"
MYSQL_DUMP
=
"
$MYSQL_DUMP
--no-defaults -uroot --socket=
$MASTER_MYSOCK
--password=
$DBPASSWD
$EXTRA_MYSQLDUMP_OPT
"
MYSQL_BINLOG
=
"
$MYSQL_BINLOG
--no-defaults --local-load=
$MYSQL_TMP_DIR
$EXTRA_MYSQLBINLOG_OPT
"
MYSQL_FIX_SYSTEM_TABLES
=
"
$MYSQL_FIX_SYSTEM_TABLES
--no-defaults --host=localhost --port=
$MASTER_MYPORT
--socket=
$MASTER_MYSOCK
--user=root --password=
$DBPASSWD
--basedir=
$BASEDIR
--bindir=
$CLIENT_BINDIR
--verbose"
...
...
mysql-test/r/ps_1general.result
View file @
22a76c1d
drop table if exists t5, t6, t7, t8;
drop database if exists mysqltest ;
drop database if exists client_test_db;
test_sequence
------ basic tests ------
drop table if exists t1, t9 ;
...
...
mysql-test/r/type_float.result
View file @
22a76c1d
drop table if exists t1;
drop table if exists t1
,t2
;
SELECT 10,10.0,10.,.1e+2,100.0e-1;
10 10.0 10. .1e+2 100.0e-1
10 10.0 10 10 10
...
...
@@ -8,6 +8,15 @@ SELECT 6e-05, -6e-05, --6e-05, -6e-05+1.000000;
SELECT 1e1,1.e1,1.0e1,1e+1,1.e+1,1.0e+1,1e-1,1.e-1,1.0e-1;
1e1 1.e1 1.0e1 1e+1 1.e+1 1.0e+1 1e-1 1.e-1 1.0e-1
10 10 10 10 10 10 0.1 0.1 0.1
SELECT 0.001e+1,0.001e-1, -0.001e+01,-0.001e-01;
0.001e+1 0.001e-1 -0.001e+01 -0.001e-01
0.01 0.0001 -0.01 -0.0001
SELECT 123.23E+02,-123.23E-02,"123.23E+02"+0.0,"-123.23E-02"+0.0;
123.23E+02 -123.23E-02 "123.23E+02"+0.0 "-123.23E-02"+0.0
12323 -1.2323 12323 -1.2323
SELECT 2147483647E+02,21474836.47E+06;
2147483647E+02 21474836.47E+06
214748364700 21474836470000
create table t1 (f1 float(24),f2 float(52));
show full columns from t1;
Field Type Collation Null Key Default Extra Privileges Comment
...
...
@@ -139,6 +148,9 @@ create table t1 (c20 char);
insert into t1 values (5000.0);
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
insert into t1 values (0.5e4);
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
drop table t1;
create table t1 (f float(54));
ERROR 42000: Incorrect column specifier for column 'f'
...
...
@@ -203,3 +215,23 @@ c
0.0002
2e-05
drop table t1;
CREATE TABLE t1 (
reckey int unsigned NOT NULL,
recdesc varchar(50) NOT NULL,
PRIMARY KEY (reckey)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
INSERT INTO t1 VALUES (108, 'Has 108 as key');
INSERT INTO t1 VALUES (109, 'Has 109 as key');
select * from t1 where reckey=108;
reckey recdesc
108 Has 108 as key
select * from t1 where reckey=1.08E2;
reckey recdesc
108 Has 108 as key
select * from t1 where reckey=109;
reckey recdesc
109 Has 109 as key
select * from t1 where reckey=1.09E2;
reckey recdesc
109 Has 109 as key
drop table t1;
mysql-test/t/mysql_client_test.test
View file @
22a76c1d
# We run with different binaries for normal and --embedded-server
#
# If this test fails with "command "$MYSQL_CLIENT_TEST" failed",
# you should either run mysql_client_test separartely against a running
# server or run mysql-test-run --debug mysql_client_test and check
# var/log/mysql_client_test.trace
--
disable_result_log
--
exec
echo
$MYSQL_CLIENT_TEST
--
exec
$MYSQL_CLIENT_TEST
mysql-test/t/ps_1general.test
View file @
22a76c1d
...
...
@@ -11,6 +11,7 @@
--
disable_warnings
drop
table
if
exists
t5
,
t6
,
t7
,
t8
;
drop
database
if
exists
mysqltest
;
drop
database
if
exists
client_test_db
;
--
enable_warnings
--
disable_query_log
...
...
mysql-test/t/type_float.test
View file @
22a76c1d
...
...
@@ -3,7 +3,7 @@
# Numeric floating point.
--
disable_warnings
drop
table
if
exists
t1
;
drop
table
if
exists
t1
,
t2
;
--
enable_warnings
--
replace_result
e
-
0
e
-
e
+
0
e
+
...
...
@@ -11,6 +11,9 @@ SELECT 10,10.0,10.,.1e+2,100.0e-1;
--
replace_result
e
-
00
e
-
0
SELECT
6
e
-
05
,
-
6
e
-
05
,
--
6
e
-
05
,
-
6
e
-
05
+
1.000000
;
SELECT
1
e1
,
1.e1
,
1.0e1
,
1
e
+
1
,
1.e+1
,
1.0e+1
,
1
e
-
1
,
1.e-1
,
1.0e-1
;
SELECT
0.001e+1
,
0.001e-1
,
-
0.001e+01
,
-
0.001e-01
;
SELECT
123.23E+02
,
-
123.23E-02
,
"123.23E+02"
+
0.0
,
"-123.23E-02"
+
0.0
;
SELECT
2147483647
E
+
02
,
21474836.47E+06
;
create
table
t1
(
f1
float
(
24
),
f2
float
(
52
));
show
full
columns
from
t1
;
...
...
@@ -83,6 +86,7 @@ drop table t1;
#
create
table
t1
(
c20
char
);
insert
into
t1
values
(
5000.0
);
insert
into
t1
values
(
0.5e4
);
drop
table
t1
;
# Errors
...
...
@@ -120,3 +124,23 @@ create table t1 (c char(6));
insert
into
t1
values
(
2
e5
),(
2
e6
),(
2
e
-
4
),(
2
e
-
5
);
select
*
from
t1
;
drop
table
t1
;
#
# Test of comparison of integer with float-in-range (Bug #7840)
# This is needed because some ODBC applications (like Foxpro) uses
# floats for everything.
#
CREATE
TABLE
t1
(
reckey
int
unsigned
NOT
NULL
,
recdesc
varchar
(
50
)
NOT
NULL
,
PRIMARY
KEY
(
reckey
)
)
ENGINE
=
MyISAM
DEFAULT
CHARSET
=
latin1
;
INSERT
INTO
t1
VALUES
(
108
,
'Has 108 as key'
);
INSERT
INTO
t1
VALUES
(
109
,
'Has 109 as key'
);
select
*
from
t1
where
reckey
=
108
;
select
*
from
t1
where
reckey
=
1.08E2
;
select
*
from
t1
where
reckey
=
109
;
select
*
from
t1
where
reckey
=
1.09E2
;
drop
table
t1
;
sql/field.cc
View file @
22a76c1d
...
...
@@ -968,7 +968,9 @@ int Field_decimal::store(longlong nr)
double
Field_decimal
::
val_real
(
void
)
{
int
not_used
;
return
my_strntod
(
&
my_charset_bin
,
ptr
,
field_length
,
NULL
,
&
not_used
);
char
*
end_not_used
;
return
my_strntod
(
&
my_charset_bin
,
ptr
,
field_length
,
&
end_not_used
,
&
not_used
);
}
longlong
Field_decimal
::
val_int
(
void
)
...
...
@@ -4370,8 +4372,9 @@ int Field_string::store(longlong nr)
double
Field_string
::
val_real
(
void
)
{
int
not_used
;
char
*
end_not_used
;
CHARSET_INFO
*
cs
=
charset
();
return
my_strntod
(
cs
,
ptr
,
field_length
,(
char
**
)
0
,
&
not_used
);
return
my_strntod
(
cs
,
ptr
,
field_length
,
&
end_not_used
,
&
not_used
);
}
...
...
@@ -4587,7 +4590,9 @@ double Field_varstring::val_real(void)
int
not_used
;
uint
length
=
uint2korr
(
ptr
)
+
HA_KEY_BLOB_LENGTH
;
CHARSET_INFO
*
cs
=
charset
();
return
my_strntod
(
cs
,
ptr
+
HA_KEY_BLOB_LENGTH
,
length
,
(
char
**
)
0
,
&
not_used
);
char
*
end_not_used
;
return
my_strntod
(
cs
,
ptr
+
HA_KEY_BLOB_LENGTH
,
length
,
&
end_not_used
,
&
not_used
);
}
...
...
@@ -4965,12 +4970,13 @@ double Field_blob::val_real(void)
{
int
not_used
;
char
*
blob
;
char
*
end_not_used
;
memcpy_fixed
(
&
blob
,
ptr
+
packlength
,
sizeof
(
char
*
));
if
(
!
blob
)
return
0.0
;
uint32
length
=
get_length
(
ptr
);
CHARSET_INFO
*
cs
=
charset
();
return
my_strntod
(
cs
,
blob
,
length
,
(
char
**
)
0
,
&
not_used
);
return
my_strntod
(
cs
,
blob
,
length
,
&
end_not_used
,
&
not_used
);
}
...
...
sql/item.cc
View file @
22a76c1d
...
...
@@ -1140,8 +1140,9 @@ double Item_param::val()
case
LONG_DATA_VALUE
:
{
int
dummy_err
;
char
*
end_not_used
;
return
my_strntod
(
str_value
.
charset
(),
(
char
*
)
str_value
.
ptr
(),
str_value
.
length
(),
(
char
**
)
0
,
&
dummy_err
);
str_value
.
length
(),
&
end_not_used
,
&
dummy_err
);
}
case
TIME_VALUE
:
/*
...
...
@@ -2585,10 +2586,12 @@ double Item_cache_str::val()
DBUG_ASSERT
(
fixed
==
1
);
int
err
;
if
(
value
)
{
char
*
end_not_used
;
return
my_strntod
(
value
->
charset
(),
(
char
*
)
value
->
ptr
(),
value
->
length
(),
(
char
**
)
0
,
&
err
);
else
return
(
double
)
0
;
value
->
length
(),
&
end_not_used
,
&
err
);
}
return
(
double
)
0
;
}
...
...
sql/item.h
View file @
22a76c1d
...
...
@@ -719,8 +719,9 @@ public:
{
DBUG_ASSERT
(
fixed
==
1
);
int
err
;
char
*
end_not_used
;
return
my_strntod
(
str_value
.
charset
(),
(
char
*
)
str_value
.
ptr
(),
str_value
.
length
(),
(
char
**
)
0
,
&
err
);
str_value
.
length
(),
&
end_not_used
,
&
err
);
}
longlong
val_int
()
{
...
...
@@ -1044,9 +1045,10 @@ public:
double
val
()
{
int
err
;
char
*
end_not_used
;
return
(
null_value
?
0.0
:
my_strntod
(
str_value
.
charset
(),
(
char
*
)
str_value
.
ptr
(),
str_value
.
length
(),
NULL
,
&
err
));
str_value
.
length
(),
&
end_not_used
,
&
err
));
}
longlong
val_int
()
{
...
...
sql/item_func.h
View file @
22a76c1d
...
...
@@ -828,8 +828,11 @@ public:
double
val
()
{
int
err
;
String
*
res
;
res
=
val_str
(
&
str_value
);
return
res
?
my_strntod
(
res
->
charset
(),(
char
*
)
res
->
ptr
(),
res
->
length
(),
0
,
&
err
)
:
0.0
;
String
*
res
;
char
*
end_not_used
;
res
=
val_str
(
&
str_value
);
return
res
?
my_strntod
(
res
->
charset
(),
(
char
*
)
res
->
ptr
(),
res
->
length
(),
&
end_not_used
,
&
err
)
:
0.0
;
}
longlong
val_int
()
{
...
...
sql/item_strfunc.cc
View file @
22a76c1d
...
...
@@ -63,10 +63,11 @@ double Item_str_func::val()
DBUG_ASSERT
(
fixed
==
1
);
int
err
;
char
buff
[
64
];
char
*
end_not_used
;
String
*
res
,
tmp
(
buff
,
sizeof
(
buff
),
&
my_charset_bin
);
res
=
val_str
(
&
tmp
);
return
res
?
my_strntod
(
res
->
charset
(),
(
char
*
)
res
->
ptr
(),
res
->
length
(),
NULL
,
&
err
)
:
0.0
;
&
end_not_used
,
&
err
)
:
0.0
;
}
longlong
Item_str_func
::
val_int
()
...
...
sql/item_sum.cc
View file @
22a76c1d
...
...
@@ -471,13 +471,14 @@ double Item_sum_hybrid::val()
{
DBUG_ASSERT
(
fixed
==
1
);
int
err
;
char
*
end_not_used
;
if
(
null_value
)
return
0.0
;
switch
(
hybrid_type
)
{
case
STRING_RESULT
:
String
*
res
;
res
=
val_str
(
&
str_value
);
return
(
res
?
my_strntod
(
res
->
charset
(),
(
char
*
)
res
->
ptr
(),
res
->
length
(),
(
char
**
)
0
,
&
err
)
:
0.0
);
&
end_not_used
,
&
err
)
:
0.0
);
case
INT_RESULT
:
if
(
unsigned_flag
)
return
ulonglong2double
(
sum_int
);
...
...
sql/item_sum.h
View file @
22a76c1d
...
...
@@ -600,9 +600,11 @@ public:
double
val
()
{
int
err
;
String
*
res
;
res
=
val_str
(
&
str_value
);
char
*
end_not_used
;
String
*
res
;
res
=
val_str
(
&
str_value
);
return
res
?
my_strntod
(
res
->
charset
(),(
char
*
)
res
->
ptr
(),
res
->
length
(),
(
char
**
)
0
,
&
err
)
:
0.0
;
&
end_not_used
,
&
err
)
:
0.0
;
}
longlong
val_int
()
{
...
...
sql/procedure.h
View file @
22a76c1d
...
...
@@ -59,7 +59,11 @@ public:
void
set
(
double
nr
)
{
value
=
nr
;
}
void
set
(
longlong
nr
)
{
value
=
(
double
)
nr
;
}
void
set
(
const
char
*
str
,
uint
length
,
CHARSET_INFO
*
cs
)
{
int
err
;
value
=
my_strntod
(
cs
,(
char
*
)
str
,
length
,(
char
**
)
0
,
&
err
);
}
{
int
err
;
char
*
end_not_used
;
value
=
my_strntod
(
cs
,
(
char
*
)
str
,
length
,
&
end_not_used
,
&
err
);
}
double
val
()
{
return
value
;
}
longlong
val_int
()
{
return
(
longlong
)
value
;
}
String
*
val_str
(
String
*
s
)
{
s
->
set
(
value
,
decimals
,
default_charset
());
return
s
;
}
...
...
@@ -99,9 +103,10 @@ public:
double
val
()
{
int
err
;
CHARSET_INFO
*
cs
=
str_value
.
charset
();
CHARSET_INFO
*
cs
=
str_value
.
charset
();
char
*
end_not_used
;
return
my_strntod
(
cs
,
(
char
*
)
str_value
.
ptr
(),
str_value
.
length
(),
(
char
**
)
0
,
&
err
);
&
end_not_used
,
&
err
);
}
longlong
val_int
()
{
...
...
strings/ctype-simple.c
View file @
22a76c1d
...
...
@@ -773,31 +773,10 @@ double my_strntod_8bit(CHARSET_INFO *cs __attribute__((unused)),
char
*
str
,
uint
length
,
char
**
end
,
int
*
err
)
{
char
end_char
;
double
result
;
errno
=
0
;
/* Safety */
/*
The following define is to avoid warnings from valgrind as str[length]
may not be defined (which is not fatal in real life)
*/
#ifdef HAVE_purify
if
(
length
==
INT_MAX32
)
#else
if
(
length
==
INT_MAX32
||
str
[
length
]
==
0
)
#endif
result
=
my_strtod
(
str
,
end
);
else
{
end_char
=
str
[
length
];
str
[
length
]
=
0
;
result
=
my_strtod
(
str
,
end
);
str
[
length
]
=
end_char
;
/* Restore end char */
}
*
err
=
errno
;
return
result
;
length
=
65535
;
/* Should be big enough */
*
end
=
str
+
length
;
return
my_strtod
(
str
,
end
,
err
);
}
...
...
strings/ctype-ucs2.c
View file @
22a76c1d
...
...
@@ -946,13 +946,10 @@ double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)),
break
;
/* Can't be part of double */
*
b
++=
(
char
)
wc
;
}
*
b
=
0
;
errno
=
0
;
res
=
my_strtod
(
buf
,
endptr
);
*
err
=
errno
;
if
(
endptr
)
*
endptr
=
(
char
*
)
(
*
endptr
-
buf
+
nptr
);
*
endptr
=
b
;
res
=
my_strtod
(
buf
,
endptr
,
err
);
*
endptr
=
nptr
+
(
uint
)
(
*
endptr
-
buf
);
return
res
;
}
...
...
strings/strtod.c
View file @
22a76c1d
...
...
@@ -2,7 +2,7 @@
An alternative implementation of "strtod()" that is both
simplier, and thread-safe.
F
rom mit-threads as bundled with MySQL 3.23
Original code f
rom mit-threads as bundled with MySQL 3.23
SQL:2003 specifies a number as
...
...
@@ -29,6 +29,8 @@
#include "my_base.h"
/* Includes errno.h */
#include "m_ctype.h"
#define MAX_DBL_EXP 308
#define MAX_RESULT_FOR_MAX_EXP 1.79769313486232
static
double
scaler10
[]
=
{
1
.
0
,
1e10
,
1e20
,
1e30
,
1e40
,
1e50
,
1e60
,
1e70
,
1e80
,
1e90
};
...
...
@@ -37,89 +39,157 @@ static double scaler1[] = {
};
double
my_strtod
(
const
char
*
str
,
char
**
end
)
/*
Convert string to double (string doesn't have to be null terminated)
SYNOPSIS
my_strtod()
str String to convert
end_ptr Pointer to pointer that points to end of string
Will be updated to point to end of double.
error Will contain error number in case of error (else 0)
RETURN
value of str as double
*/
double
my_strtod
(
const
char
*
str
,
char
**
end_ptr
,
int
*
error
)
{
double
result
=
0
.
0
;
int
negative
,
ndigits
;
const
char
*
old_str
;
uint
negative
=
0
,
ndigits
,
dec_digits
=
0
,
neg_exp
=
0
;
int
exp
=
0
,
digits_after_dec_point
=
0
;
const
char
*
old_str
,
*
end
=
*
end_ptr
,
*
start_of_number
;
char
next_char
;
my_bool
overflow
=
0
;
*
error
=
0
;
if
(
str
>=
end
)
goto
done
;
while
(
my_isspace
(
&
my_charset_latin1
,
*
str
))
str
++
;
{
if
(
++
str
==
end
)
goto
done
;
}
start_of_number
=
str
;
if
((
negative
=
(
*
str
==
'-'
))
||
*
str
==
'+'
)
str
++
;
{
if
(
++
str
==
end
)
goto
done
;
/* Could be changed to error */
}
/* Skip pre-zero for easier calculation of overflows */
while
(
*
str
==
'0'
)
{
if
(
++
str
==
end
)
goto
done
;
start_of_number
=
0
;
/* Found digit */
}
old_str
=
str
;
while
(
my_isdigit
(
&
my_charset_latin1
,
*
str
)
)
while
(
(
next_char
=
*
str
)
>=
'0'
&&
next_char
<=
'9'
)
{
result
=
result
*
10
.
0
+
(
*
str
-
'0'
);
str
++
;
result
=
result
*
10
.
0
+
(
next_char
-
'0'
);
if
(
++
str
==
end
)
{
next_char
=
0
;
/* Found end of string */
break
;
}
start_of_number
=
0
;
/* Found digit */
}
ndigits
=
str
-
old_str
;
ndigits
=
(
uint
)
(
str
-
old_str
)
;
if
(
*
str
==
'.'
)
if
(
next_char
==
'.'
&&
str
<
end
-
1
)
{
double
p10
=
10
;
str
++
;
old_str
=
str
;
while
(
my_isdigit
(
&
my_charset_latin1
,
*
str
))
/*
Continue to add numbers after decimal point to the result, as if there
was no decimal point. We will later (in the exponent handling) shift
the number down with the required number of fractions. We do it this
way to be able to get maximum precision for numbers like 123.45E+02,
which are normal for some ODBC applications.
*/
old_str
=
++
str
;
while
(
my_isdigit
(
&
my_charset_latin1
,
(
next_char
=
*
str
)))
{
result
+=
(
*
str
++
-
'0'
)
/
p10
;
p10
*=
10
;
result
=
result
*
10
.
0
+
(
next_char
-
'0'
);
digits_after_dec_point
++
;
if
(
++
str
==
end
)
{
next_char
=
0
;
break
;
}
}
ndigits
+=
str
-
old_str
;
if
(
!
ndigits
)
str
--
;
/* If we found just '+.' or '.' then point at first character */
if
(
!
(
dec_digits
=
(
uint
)
(
str
-
old_str
))
&&
start_of_number
)
str
=
start_of_number
;
/* Point at '+' or '.' */
}
if
(
ndigits
&&
(
*
str
==
'e'
||
*
str
==
'E'
))
if
((
next_char
==
'e'
||
next_char
==
'E'
)
&&
dec_digits
+
ndigits
!=
0
&&
str
<
end
-
1
)
{
int
exp
=
0
;
int
neg
=
0
;
const
char
*
old_str
=
str
++
;
if
((
neg
=
(
*
str
==
'-'
))
||
*
str
==
'+'
)
if
((
neg
_exp
=
(
*
str
==
'-'
))
||
*
str
==
'+'
)
str
++
;
if
(
!
my_isdigit
(
&
my_charset_latin1
,
*
str
))
if
(
str
==
end
||
!
my_isdigit
(
&
my_charset_latin1
,
*
str
))
str
=
old_str
;
else
{
double
scaler
=
1
.
0
;
while
(
my_isdigit
(
&
my_charset_latin1
,
*
str
))
do
{
if
(
exp
<
9999
)
/* protection against exp overflow
*/
exp
=
exp
*
10
+
*
str
-
'0'
;
if
(
exp
<
9999
)
/* prot. against exp overfl.
*/
exp
=
exp
*
10
+
(
*
str
-
'0'
)
;
str
++
;
}
if
(
exp
>=
1000
)
}
while
(
str
<
end
&&
my_isdigit
(
&
my_charset_latin1
,
*
str
));
}
}
if
((
exp
=
(
neg_exp
?
exp
+
digits_after_dec_point
:
exp
-
digits_after_dec_point
)))
{
double
scaler
;
if
(
exp
<
0
)
{
exp
=
-
exp
;
neg_exp
=
1
;
/* neg_exp was 0 before */
}
if
(
exp
+
ndigits
>=
MAX_DBL_EXP
+
1
&&
result
)
{
/*
This is not 100 % as we actually will give an owerflow for
17E307 but not for 1.7E308 but lets cut some corners to make life
simpler
*/
if
(
exp
+
ndigits
>
MAX_DBL_EXP
+
1
||
result
>=
MAX_RESULT_FOR_MAX_EXP
)
{
if
(
neg
)
result
=
0
.
0
;
else
if
(
neg_exp
)
result
=
0
.
0
;
else
overflow
=
1
;
goto
done
;
}
while
(
exp
>=
100
)
{
scaler
*=
1.0e100
;
exp
-=
100
;
}
scaler
*=
scaler10
[
exp
/
10
]
*
scaler1
[
exp
%
10
];
if
(
neg
)
result
/=
scaler
;
else
result
*=
scaler
;
}
scaler
=
1
.
0
;
while
(
exp
>=
100
)
{
scaler
*=
1.0e100
;
exp
-=
100
;
}
scaler
*=
scaler10
[
exp
/
10
]
*
scaler1
[
exp
%
10
];
if
(
neg_exp
)
result
/=
scaler
;
else
result
*=
scaler
;
}
done:
if
(
end
)
*
end
=
(
char
*
)
str
;
*
end_ptr
=
(
char
*
)
str
;
/* end of number */
if
(
overflow
||
isinf
(
result
))
{
result
=
DBL_MAX
;
errno
=
EOVERFLOW
;
*
error
=
EOVERFLOW
;
}
return
negative
?
-
result
:
result
;
...
...
@@ -127,6 +197,7 @@ done:
double
my_atof
(
const
char
*
nptr
)
{
return
(
my_strtod
(
nptr
,
0
));
int
error
;
const
char
*
end
=
nptr
+
65535
;
/* Should be enough */
return
(
my_strtod
(
nptr
,
(
char
**
)
&
end
,
&
error
));
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment