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
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
bc9b6c9f
Commit
bc9b6c9f
authored
Oct 19, 2002
by
peter@mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge mysql.com:/home/pz/mysql/mysql-4.0-root
into mysql.com:/home/pz/mysql/mysql-4.0
parents
9e8c87e7
0cade54d
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
61 additions
and
15 deletions
+61
-15
mysql-test/r/type_decimal.result
mysql-test/r/type_decimal.result
+11
-0
mysql-test/t/type_decimal.test
mysql-test/t/type_decimal.test
+10
-0
sql/field.cc
sql/field.cc
+40
-15
No files found.
mysql-test/r/type_decimal.result
View file @
bc9b6c9f
...
...
@@ -346,3 +346,14 @@ a
1234567890
9999999999
drop table t1;
create table t1(a decimal(10,0));
insert into t1 values ("1e4294967295");
select * from t1;
a
99999999999
delete from t1;
insert into t1 values("1e4294967297");
select * from t1;
a
99999999999
drop table t1;
mysql-test/t/type_decimal.test
View file @
bc9b6c9f
...
...
@@ -220,3 +220,13 @@ create table t1 (a decimal unsigned zerofill);
insert
into
t1
values
(
-
99999999999999
),(
-
1
),(
'+1'
),(
'01'
),(
'+00000000000001'
),(
'+1234567890'
),(
99999999999999
);
select
*
from
t1
;
drop
table
t1
;
# Exponent overflow bug
create
table
t1
(
a
decimal
(
10
,
0
));
insert
into
t1
values
(
"1e4294967295"
);
select
*
from
t1
;
delete
from
t1
;
insert
into
t1
values
(
"1e4294967297"
);
select
*
from
t1
;
drop
table
t1
;
sql/field.cc
View file @
bc9b6c9f
...
...
@@ -367,6 +367,7 @@ void Field_decimal::store(const char *from,uint len)
/* The pointer where the field value starts (i.e., "where to write") */
char
*
to
=
ptr
;
uint
tmp_dec
,
tmp_uint
;
ulonglong
tmp_ulonglong
;
/*
The sign of the number : will be 0 (means positive but sign not
specified), '+' or '-'
...
...
@@ -380,7 +381,8 @@ void Field_decimal::store(const char *from,uint len)
const
char
*
frac_digits_from
,
*
frac_digits_end
;
/* The sign of the exponent : will be 0 (means no exponent), '+' or '-' */
char
expo_sign_char
=
0
;
uint
exponent
=
0
;
// value of the exponent
uint
exponent
=
0
;
// value of the exponent
ulonglong
exponent_ulonglong
=
0
;
/*
Pointers used when digits move from the left of the '.' to the
right of the '.' (explained below)
...
...
@@ -474,13 +476,23 @@ void Field_decimal::store(const char *from,uint len)
else
expo_sign_char
=
'+'
;
/*
Read digits of the exponent and compute its value
'exponent' overflow (e.g. if 1E10000000000000000) is not a problem
(the value of the field will be overflow anyway, or 0 anyway,
it does not change anything if the exponent is 2^32 or more
Read digits of the exponent and compute its value.
We must care about 'exponent' overflow, because as
unsigned arithmetic is "modulo", big exponents
will become small (e.g.
1e4294967296 will become 1e0, and the field
will finally contain 1 instead of its max possible value).
*/
for
(;
from
!=
end
&&
isdigit
(
*
from
);
from
++
)
exponent
=
10
*
exponent
+
(
*
from
-
'0'
);
for
(;
from
!=
end
&&
isdigit
(
*
from
);
from
++
)
{
exponent_ulonglong
=
10
*
exponent_ulonglong
+
(
ulonglong
)(
*
from
-
'0'
);
if
(
exponent_ulonglong
>
(
ulonglong
)
UINT_MAX
)
{
exponent_ulonglong
=
(
ulonglong
)
UINT_MAX
;
break
;
}
}
exponent
=
(
uint
)(
exponent_ulonglong
);
}
/*
...
...
@@ -521,15 +533,22 @@ void Field_decimal::store(const char *from,uint len)
int_digits_added_zeros=2 (to make 1234500).
*/
/*
Below tmp_ulongulong cannot overflow,
as int_digits_added_zeros<=exponent<4G and
(ulonglong)(int_digits_end-int_digits_from)<=max_allowed_packet<=2G and
(ulonglong)(frac_digits_from-int_digits_tail_from)<=max_allowed_packet<=2G
*/
if
(
!
expo_sign_char
)
tmp_u
int
=
tmp_dec
+
(
uint
)(
int_digits_end
-
int_digits_from
);
tmp_u
longlong
=
(
ulonglong
)
tmp_dec
+
(
ulonglong
)(
int_digits_end
-
int_digits_from
);
else
if
(
expo_sign_char
==
'-'
)
{
tmp_uint
=
min
(
exponent
,(
uint
)(
int_digits_end
-
int_digits_from
));
frac_digits_added_zeros
=
exponent
-
tmp_uint
;
int_digits_end
-=
tmp_uint
;
frac_digits_head_end
=
int_digits_end
+
tmp_uint
;
tmp_u
int
=
tmp_dec
+
(
uint
)(
int_digits_end
-
int_digits_from
);
tmp_u
longlong
=
(
ulonglong
)
tmp_dec
+
(
ulonglong
)(
int_digits_end
-
int_digits_from
);
}
else
// (expo_sign_char=='+')
{
...
...
@@ -556,9 +575,9 @@ void Field_decimal::store(const char *from,uint len)
int_digits_added_zeros
=
0
;
}
}
tmp_u
int
=
(
tmp_dec
+
(
uint
)(
int_digits_end
-
int_digits_from
)
+
(
uint
)(
frac_digits_from
-
int_digits_tail_from
)
+
int_digits_added_zeros
)
;
tmp_u
longlong
=
(
ulonglong
)
tmp_dec
+
(
ulonglong
)(
int_digits_end
-
int_digits_from
)
+
(
ulonglong
)(
frac_digits_from
-
int_digits_tail_from
)
+
(
ulonglong
)
int_digits_added_zeros
;
}
/*
...
...
@@ -569,13 +588,19 @@ void Field_decimal::store(const char *from,uint len)
If the sign is defined and '-', we need one position for it
*/
if
(
field_length
<
tmp_uint
+
(
int
)
(
sign_char
==
'-'
))
if
((
ulonglong
)
field_length
<
tmp_ulonglong
+
(
ulonglong
)
(
sign_char
==
'-'
))
//the rightmost sum above cannot overflow
{
// too big number, change to max or min number
Field_decimal
::
overflow
(
sign_char
==
'-'
);
return
;
}
/*
If the above test was ok, then tmp_ulonglong<4G and the following cast is valid
*/
tmp_uint
=
(
uint
)
tmp_ulonglong
;
/*
Tmp_left_pos is the position where the leftmost digit of
the int_% parts will be written
...
...
@@ -632,7 +657,7 @@ void Field_decimal::store(const char *from,uint len)
*
pos
--=
' '
;
//fill with blanks
}
if
(
tmp_dec
)
// This field has decimals
// if (tmp_dec)
{
/*
Write digits of the frac_% parts ;
...
...
@@ -644,8 +669,8 @@ void Field_decimal::store(const char *from,uint len)
*/
pos
=
to
+
(
uint
)(
field_length
-
tmp_dec
);
// Calculate post to '.'
*
pos
++=
'.'
;
right_wall
=
to
+
field_length
;
if
(
pos
!=
right_wall
)
*
pos
++=
'.'
;
if
(
expo_sign_char
==
'-'
)
{
...
...
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