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
0c6b9665
Commit
0c6b9665
authored
Aug 18, 2004
by
unknown
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Bug 4937: different date -> string conversion when using
SELECT ... UNION and INSERT ... SELECT ... UNION
parent
8ddcba9d
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
88 additions
and
41 deletions
+88
-41
mysql-test/r/type_date.result
mysql-test/r/type_date.result
+17
-0
mysql-test/t/type_date.test
mysql-test/t/type_date.test
+19
-0
sql/field.cc
sql/field.cc
+50
-40
sql/field.h
sql/field.h
+2
-1
No files found.
mysql-test/r/type_date.result
View file @
0c6b9665
...
...
@@ -79,3 +79,20 @@ SELECT DATE_FORMAT(f1, "%l.%i %p") , DATE_FORMAT(f2, "%l.%i %p") FROM t1;
DATE_FORMAT(f1, "%l.%i %p") DATE_FORMAT(f2, "%l.%i %p")
9.00 AM 12.00 PM
DROP TABLE t1;
CREATE TABLE t1 (f1 DATE);
CREATE TABLE t2 (f2 VARCHAR(8));
CREATE TABLE t3 (f2 CHAR(8));
INSERT INTO t1 VALUES ('1978-11-26');
INSERT INTO t2 SELECT f1+0 FROM t1;
INSERT INTO t2 SELECT f1+0 FROM t1 UNION SELECT f1+0 FROM t1;
INSERT INTO t3 SELECT f1+0 FROM t1;
INSERT INTO t3 SELECT f1+0 FROM t1 UNION SELECT f1+0 FROM t1;
SELECT * FROM t2;
f2
19781126
19781126
SELECT * FROM t3;
f2
19781126
19781126
DROP TABLE t1, t2, t3;
mysql-test/t/type_date.test
View file @
0c6b9665
...
...
@@ -84,3 +84,22 @@ CREATE TABLE t1 (f1 time default NULL, f2 time default NULL) TYPE=MyISAM;
INSERT
INTO
t1
(
f1
,
f2
)
VALUES
(
'09:00'
,
'12:00'
);
SELECT
DATE_FORMAT
(
f1
,
"%l.%i %p"
)
,
DATE_FORMAT
(
f2
,
"%l.%i %p"
)
FROM
t1
;
DROP
TABLE
t1
;
#
# Bug 4937: different date -> string conversion when using SELECT ... UNION
# and INSERT ... SELECT ... UNION
#
CREATE
TABLE
t1
(
f1
DATE
);
CREATE
TABLE
t2
(
f2
VARCHAR
(
8
));
CREATE
TABLE
t3
(
f2
CHAR
(
8
));
INSERT
INTO
t1
VALUES
(
'1978-11-26'
);
INSERT
INTO
t2
SELECT
f1
+
0
FROM
t1
;
INSERT
INTO
t2
SELECT
f1
+
0
FROM
t1
UNION
SELECT
f1
+
0
FROM
t1
;
INSERT
INTO
t3
SELECT
f1
+
0
FROM
t1
;
INSERT
INTO
t3
SELECT
f1
+
0
FROM
t1
UNION
SELECT
f1
+
0
FROM
t1
;
SELECT
*
FROM
t2
;
SELECT
*
FROM
t3
;
DROP
TABLE
t1
,
t2
,
t3
;
sql/field.cc
View file @
0c6b9665
...
...
@@ -37,6 +37,7 @@
#include "sql_select.h"
#include <m_ctype.h>
#include <errno.h>
#include <assert.h>
#ifdef HAVE_FCONVERT
#include <floatingpoint.h>
#endif
...
...
@@ -58,6 +59,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
*****************************************************************************/
...
...
@@ -739,7 +742,7 @@ void 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
...
...
@@ -2326,46 +2329,20 @@ 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
();
if
(
dec
>=
NOT_FIXED_DEC
)
{
/*
Let's try to pretty print a floating point number. Here we use
'%-*.*g' conversion string:
'-' stands for left-padding with spaces, if such padding will take
place
'*' is a placeholder for the first argument, field_length, and
signifies minimal width of result string. If result is less than
field length it will be space-padded. Note, however, that we'll not
pass spaces to Field_string::store(const char *, ...), due to
strcend in the next line.
'.*' is a placeholder for DBL_DIG and defines maximum number of
significant digits in the result string. DBL_DIG is a hardware
specific C define for maximum number of decimal digits of a floating
point number, such that rounding to hardware floating point
representation and back to decimal will not lead to loss of
precision. I.e if DBL_DIG is 15, number 123456789111315 can be
represented as double without precision loss. As one can judge from
this description, chosing DBL_DIG here is questionable, especially
because it introduces a system dependency.
'g' means that conversion will use [-]ddd.ddd (conventional) style,
and fall back to [-]d.ddde[+|i]ddd (scientific) style if there is no
enough space for all digits.
Maximum length of result string (not counting spaces) is (I guess)
DBL_DIG + 8, where 8 is 1 for sign, 1 for decimal point, 1 for
exponent sign, 1 for exponent, and 4 for exponent value.
XXX: why do we use space-padding and trim spaces in the next line?
*/
sprintf
(
to
,
"%-*.*g"
,(
int
)
field_length
,
DBL_DIG
,
nr
);
to
=
strcend
(
to
,
' '
);
}
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
));
...
...
@@ -3721,13 +3698,50 @@ void Field_string::store(const char *from,uint length)
}
/*
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
void
store_double_in_string_field
(
Field_str
*
field
,
uint32
field_length
,
double
nr
)
{
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
);
field
->
store
(
buff
,
(
uint
)
length
);
}
void
Field_string
::
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
,
' '
);
Field_string
::
store
(
buff
,(
uint
)
(
end
-
buff
));
store_double_in_string_field
(
this
,
field_length
,
nr
);
}
...
...
@@ -3927,11 +3941,7 @@ void Field_varstring::store(const char *from,uint length)
void
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
,
' '
);
Field_varstring
::
store
(
buff
,(
uint
)
(
end
-
buff
));
store_double_in_string_field
(
this
,
field_length
,
nr
);
}
...
...
sql/field.h
View file @
0c6b9665
...
...
@@ -255,12 +255,13 @@ public:
class
Field_str
:
public
Field
{
public:
double
ceiling
;
// for ::store(double nr)
Field_str
(
char
*
ptr_arg
,
uint32
len_arg
,
uchar
*
null_ptr_arg
,
uchar
null_bit_arg
,
utype
unireg_check_arg
,
const
char
*
field_name_arg
,
struct
st_table
*
table_arg
)
:
Field
(
ptr_arg
,
len_arg
,
null_ptr_arg
,
null_bit_arg
,
unireg_check_arg
,
field_name_arg
,
table_arg
)
unireg_check_arg
,
field_name_arg
,
table_arg
)
,
ceiling
(
0.0
)
{}
Item_result
result_type
()
const
{
return
STRING_RESULT
;
}
uint
decimals
()
const
{
return
NOT_FIXED_DEC
;
}
...
...
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