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
8ce92878
Commit
8ce92878
authored
Aug 18, 2004
by
serg@serg.mylan
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
a17f9689
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 @
8ce92878
...
@@ -79,3 +79,20 @@ SELECT DATE_FORMAT(f1, "%l.%i %p") , DATE_FORMAT(f2, "%l.%i %p") FROM t1;
...
@@ -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")
DATE_FORMAT(f1, "%l.%i %p") DATE_FORMAT(f2, "%l.%i %p")
9.00 AM 12.00 PM
9.00 AM 12.00 PM
DROP TABLE t1;
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 @
8ce92878
...
@@ -84,3 +84,22 @@ CREATE TABLE t1 (f1 time default NULL, f2 time default NULL) TYPE=MyISAM;
...
@@ -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'
);
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
;
SELECT
DATE_FORMAT
(
f1
,
"%l.%i %p"
)
,
DATE_FORMAT
(
f2
,
"%l.%i %p"
)
FROM
t1
;
DROP
TABLE
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 @
8ce92878
...
@@ -37,6 +37,7 @@
...
@@ -37,6 +37,7 @@
#include "sql_select.h"
#include "sql_select.h"
#include <m_ctype.h>
#include <m_ctype.h>
#include <errno.h>
#include <errno.h>
#include <assert.h>
#ifdef HAVE_FCONVERT
#ifdef HAVE_FCONVERT
#include <floatingpoint.h>
#include <floatingpoint.h>
#endif
#endif
...
@@ -58,6 +59,8 @@ template class List_iterator<create_field>;
...
@@ -58,6 +59,8 @@ template class List_iterator<create_field>;
uchar
Field_null
::
null
[
1
]
=
{
1
};
uchar
Field_null
::
null
[
1
]
=
{
1
};
const
char
field_separator
=
','
;
const
char
field_separator
=
','
;
#define DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE 320
/*****************************************************************************
/*****************************************************************************
Static help functions
Static help functions
*****************************************************************************/
*****************************************************************************/
...
@@ -739,7 +742,7 @@ void Field_decimal::store(double nr)
...
@@ -739,7 +742,7 @@ void Field_decimal::store(double nr)
reg4
uint
i
,
length
;
reg4
uint
i
,
length
;
char
fyllchar
,
*
to
;
char
fyllchar
,
*
to
;
char
buff
[
320
];
char
buff
[
DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE
];
fyllchar
=
zerofill
?
(
char
)
'0'
:
(
char
)
' '
;
fyllchar
=
zerofill
?
(
char
)
'0'
:
(
char
)
' '
;
#ifdef HAVE_SNPRINTF
#ifdef HAVE_SNPRINTF
...
@@ -2326,46 +2329,20 @@ String *Field_double::val_str(String *val_buffer,
...
@@ -2326,46 +2329,20 @@ String *Field_double::val_str(String *val_buffer,
#endif
#endif
doubleget
(
nr
,
ptr
);
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
);
val_buffer
->
alloc
(
to_length
);
char
*
to
=
(
char
*
)
val_buffer
->
ptr
();
char
*
to
=
(
char
*
)
val_buffer
->
ptr
();
if
(
dec
>=
NOT_FIXED_DEC
)
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
);
sprintf
(
to
,
"%-*.*g"
,(
int
)
field_length
,
DBL_DIG
,
nr
);
to
=
strcend
(
to
,
' '
);
to
=
strcend
(
to
,
' '
);
}
}
else
else
{
{
#ifdef HAVE_FCONVERT
#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
;
int
decpt
,
sign
,
tmp_dec
=
dec
;
VOID
(
fconvert
(
nr
,
tmp_dec
,
&
decpt
,
&
sign
,
buff
));
VOID
(
fconvert
(
nr
,
tmp_dec
,
&
decpt
,
&
sign
,
buff
));
...
@@ -3721,13 +3698,50 @@ void Field_string::store(const char *from,uint length)
...
@@ -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
)
void
Field_string
::
store
(
double
nr
)
{
{
char
buff
[
MAX_FIELD_WIDTH
],
*
end
;
store_double_in_string_field
(
this
,
field_length
,
nr
);
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
));
}
}
...
@@ -3927,11 +3941,7 @@ void Field_varstring::store(const char *from,uint length)
...
@@ -3927,11 +3941,7 @@ void Field_varstring::store(const char *from,uint length)
void
Field_varstring
::
store
(
double
nr
)
void
Field_varstring
::
store
(
double
nr
)
{
{
char
buff
[
MAX_FIELD_WIDTH
],
*
end
;
store_double_in_string_field
(
this
,
field_length
,
nr
);
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
));
}
}
...
...
sql/field.h
View file @
8ce92878
...
@@ -255,12 +255,13 @@ public:
...
@@ -255,12 +255,13 @@ public:
class
Field_str
:
public
Field
{
class
Field_str
:
public
Field
{
public:
public:
double
ceiling
;
// for ::store(double nr)
Field_str
(
char
*
ptr_arg
,
uint32
len_arg
,
uchar
*
null_ptr_arg
,
Field_str
(
char
*
ptr_arg
,
uint32
len_arg
,
uchar
*
null_ptr_arg
,
uchar
null_bit_arg
,
utype
unireg_check_arg
,
uchar
null_bit_arg
,
utype
unireg_check_arg
,
const
char
*
field_name_arg
,
const
char
*
field_name_arg
,
struct
st_table
*
table_arg
)
struct
st_table
*
table_arg
)
:
Field
(
ptr_arg
,
len_arg
,
null_ptr_arg
,
null_bit_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
;
}
Item_result
result_type
()
const
{
return
STRING_RESULT
;
}
uint
decimals
()
const
{
return
NOT_FIXED_DEC
;
}
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