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
4643854b
Commit
4643854b
authored
Jun 09, 2004
by
paul@ice.snake.net
Browse files
Options
Browse Files
Download
Plain Diff
Merge paul@bk-internal.mysql.com:/home/bk/mysql-4.1
into ice.snake.net:/Volumes/ice2/MySQL/bk/mysql-4.1
parents
8e723734
1b76aa07
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
217 additions
and
57 deletions
+217
-57
BitKeeper/etc/logging_ok
BitKeeper/etc/logging_ok
+1
-0
libmysql/libmysql.c
libmysql/libmysql.c
+97
-29
mysys/charset.c
mysys/charset.c
+2
-1
sql/item.cc
sql/item.cc
+12
-0
sql/item.h
sql/item.h
+12
-1
sql/protocol.cc
sql/protocol.cc
+13
-11
sql/protocol.h
sql/protocol.h
+0
-1
sql/sql_prepare.cc
sql/sql_prepare.cc
+12
-14
tests/client_test.c
tests/client_test.c
+68
-0
No files found.
BitKeeper/etc/logging_ok
View file @
4643854b
...
@@ -22,6 +22,7 @@ bar@bar.mysql.r18.ru
...
@@ -22,6 +22,7 @@ bar@bar.mysql.r18.ru
bar@bar.udmsearch.izhnet.ru
bar@bar.udmsearch.izhnet.ru
bar@deer.(none)
bar@deer.(none)
bar@gw.udmsearch.izhnet.ru
bar@gw.udmsearch.izhnet.ru
bar@mysql.com
bell@laptop.sanja.is.com.ua
bell@laptop.sanja.is.com.ua
bell@sanja.is.com.ua
bell@sanja.is.com.ua
bk@admin.bk
bk@admin.bk
...
...
libmysql/libmysql.c
View file @
4643854b
...
@@ -1667,6 +1667,27 @@ static int stmt_read_row_buffered(MYSQL_STMT *stmt, unsigned char **row);
...
@@ -1667,6 +1667,27 @@ static int stmt_read_row_buffered(MYSQL_STMT *stmt, unsigned char **row);
static
int
stmt_read_row_no_data
(
MYSQL_STMT
*
stmt
,
unsigned
char
**
row
);
static
int
stmt_read_row_no_data
(
MYSQL_STMT
*
stmt
,
unsigned
char
**
row
);
/*
Maximum sizes of MYSQL_TYPE_DATE, MYSQL_TYPE_TIME, MYSQL_TYPE_DATETIME
values stored in network buffer.
*/
/* 1 (length) + 2 (year) + 1 (month) + 1 (day) */
static
const
unsigned
MAX_DATE_REP_LENGTH
=
5
;
/*
1 (length) + 1 (is negative) + 4 (day count) + 1 (hour)
+ 1 (minute) + 1 (seconds) + 4 (microseconds)
*/
static
const
unsigned
MAX_TIME_REP_LENGTH
=
13
;
/*
1 (length) + 2 (year) + 1 (month) + 1 (day) +
1 (hour) + 1 (minute) + 1 (second) + 4 (microseconds)
*/
static
const
unsigned
MAX_DATETIME_REP_LENGTH
=
12
;
/**************** Misc utility functions ****************************/
/**************** Misc utility functions ****************************/
/*
/*
...
@@ -2030,6 +2051,30 @@ static unsigned int alloc_stmt_fields(MYSQL_STMT *stmt)
...
@@ -2030,6 +2051,30 @@ static unsigned int alloc_stmt_fields(MYSQL_STMT *stmt)
return
stmt
->
field_count
;
return
stmt
->
field_count
;
}
}
/*
Update result set columns metadata if it was sent again in
reply to COM_EXECUTE.
*/
static
void
update_stmt_fields
(
MYSQL_STMT
*
stmt
)
{
MYSQL_FIELD
*
field
=
stmt
->
mysql
->
fields
;
MYSQL_FIELD
*
field_end
=
field
+
stmt
->
field_count
;
MYSQL_FIELD
*
stmt_field
=
stmt
->
fields
;
DBUG_ASSERT
(
stmt
->
field_count
==
stmt
->
mysql
->
field_count
);
for
(;
field
<
field_end
;
++
field
,
++
stmt_field
)
{
stmt_field
->
charsetnr
=
field
->
charsetnr
;
stmt_field
->
length
=
field
->
length
;
stmt_field
->
type
=
field
->
type
;
stmt_field
->
flags
=
field
->
flags
;
stmt_field
->
decimals
=
field
->
decimals
;
}
}
/*
/*
Returns prepared statement metadata in the form of a result set.
Returns prepared statement metadata in the form of a result set.
...
@@ -2166,7 +2211,7 @@ static void store_param_double(NET *net, MYSQL_BIND *param)
...
@@ -2166,7 +2211,7 @@ static void store_param_double(NET *net, MYSQL_BIND *param)
static
void
store_param_time
(
NET
*
net
,
MYSQL_BIND
*
param
)
static
void
store_param_time
(
NET
*
net
,
MYSQL_BIND
*
param
)
{
{
MYSQL_TIME
*
tm
=
(
MYSQL_TIME
*
)
param
->
buffer
;
MYSQL_TIME
*
tm
=
(
MYSQL_TIME
*
)
param
->
buffer
;
char
buff
[
15
],
*
pos
;
char
buff
[
MAX_TIME_REP_LENGTH
],
*
pos
;
uint
length
;
uint
length
;
pos
=
buff
+
1
;
pos
=
buff
+
1
;
...
@@ -2177,7 +2222,7 @@ static void store_param_time(NET *net, MYSQL_BIND *param)
...
@@ -2177,7 +2222,7 @@ static void store_param_time(NET *net, MYSQL_BIND *param)
pos
[
7
]
=
(
uchar
)
tm
->
second
;
pos
[
7
]
=
(
uchar
)
tm
->
second
;
int4store
(
pos
+
8
,
tm
->
second_part
);
int4store
(
pos
+
8
,
tm
->
second_part
);
if
(
tm
->
second_part
)
if
(
tm
->
second_part
)
length
=
1
1
;
length
=
1
2
;
else
if
(
tm
->
hour
||
tm
->
minute
||
tm
->
second
||
tm
->
day
)
else
if
(
tm
->
hour
||
tm
->
minute
||
tm
->
second
||
tm
->
day
)
length
=
8
;
length
=
8
;
else
else
...
@@ -2189,7 +2234,7 @@ static void store_param_time(NET *net, MYSQL_BIND *param)
...
@@ -2189,7 +2234,7 @@ static void store_param_time(NET *net, MYSQL_BIND *param)
static
void
net_store_datetime
(
NET
*
net
,
MYSQL_TIME
*
tm
)
static
void
net_store_datetime
(
NET
*
net
,
MYSQL_TIME
*
tm
)
{
{
char
buff
[
12
],
*
pos
;
char
buff
[
MAX_DATETIME_REP_LENGTH
],
*
pos
;
uint
length
;
uint
length
;
pos
=
buff
+
1
;
pos
=
buff
+
1
;
...
@@ -2280,7 +2325,7 @@ static my_bool store_param(MYSQL_STMT *stmt, MYSQL_BIND *param)
...
@@ -2280,7 +2325,7 @@ static my_bool store_param(MYSQL_STMT *stmt, MYSQL_BIND *param)
Param->length should ALWAYS point to the correct length for the type
Param->length should ALWAYS point to the correct length for the type
Either to the length pointer given by the user or param->buffer_length
Either to the length pointer given by the user or param->buffer_length
*/
*/
if
((
my_realloc_str
(
net
,
9
+
*
param
->
length
)))
if
((
my_realloc_str
(
net
,
*
param
->
length
)))
{
{
set_stmt_error
(
stmt
,
CR_OUT_OF_MEMORY
,
unknown_sqlstate
);
set_stmt_error
(
stmt
,
CR_OUT_OF_MEMORY
,
unknown_sqlstate
);
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
...
@@ -2557,16 +2602,37 @@ int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt)
...
@@ -2557,16 +2602,37 @@ int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt)
*/
*/
if
(
mysql
->
methods
->
stmt_execute
(
stmt
))
if
(
mysql
->
methods
->
stmt_execute
(
stmt
))
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
if
(
!
stmt
->
field_count
&&
mysql
->
field_count
)
if
(
mysql
->
field_count
)
{
/* Server has sent result set metadata */
if
(
stmt
->
field_count
==
0
)
{
{
/*
/*
This is 'SHOW'/'EXPLAIN'-like query. Current implementation of
This is 'SHOW'/'EXPLAIN'-like query. Current implementation of
prepared statements can't send result set metadata for this
queries
prepared statements can't send result set metadata for these
queries
on prepare stage. Read it now.
on prepare stage. Read it now.
*/
*/
alloc_stmt_fields
(
stmt
);
alloc_stmt_fields
(
stmt
);
}
}
else
{
/*
Update result set metadata if it for some reason changed between
prepare and execute, i.e.:
- in case of 'SELECT ?' we don't know column type unless data was
supplied to mysql_stmt_execute, so updated column type is sent
now.
- if data dictionary changed between prepare and execute, for
example a table used in the query was altered.
Note, that now (4.1.3) we always send metadata in reply to
COM_EXECUTE (even if it is not necessary), so either this or
previous always branch works.
TODO: send metadata only when it's really necessary and add a warning
'Metadata changed' when it's sent twice.
*/
update_stmt_fields
(
stmt
);
}
}
stmt
->
state
=
MYSQL_STMT_EXECUTE_DONE
;
stmt
->
state
=
MYSQL_STMT_EXECUTE_DONE
;
if
(
stmt
->
field_count
)
if
(
stmt
->
field_count
)
{
{
...
@@ -2693,15 +2759,17 @@ my_bool STDCALL mysql_stmt_bind_param(MYSQL_STMT *stmt, MYSQL_BIND * bind)
...
@@ -2693,15 +2759,17 @@ my_bool STDCALL mysql_stmt_bind_param(MYSQL_STMT *stmt, MYSQL_BIND * bind)
param
->
store_param_func
=
store_param_double
;
param
->
store_param_func
=
store_param_double
;
break
;
break
;
case
MYSQL_TYPE_TIME
:
case
MYSQL_TYPE_TIME
:
/* Buffer length ignored for DATE, TIME and DATETIME */
param
->
store_param_func
=
store_param_time
;
param
->
store_param_func
=
store_param_time
;
param
->
buffer_length
=
MAX_TIME_REP_LENGTH
;
break
;
break
;
case
MYSQL_TYPE_DATE
:
case
MYSQL_TYPE_DATE
:
param
->
store_param_func
=
store_param_date
;
param
->
store_param_func
=
store_param_date
;
param
->
buffer_length
=
MAX_DATE_REP_LENGTH
;
break
;
break
;
case
MYSQL_TYPE_DATETIME
:
case
MYSQL_TYPE_DATETIME
:
case
MYSQL_TYPE_TIMESTAMP
:
case
MYSQL_TYPE_TIMESTAMP
:
param
->
store_param_func
=
store_param_datetime
;
param
->
store_param_func
=
store_param_datetime
;
param
->
buffer_length
=
MAX_DATETIME_REP_LENGTH
;
break
;
break
;
case
MYSQL_TYPE_TINY_BLOB
:
case
MYSQL_TYPE_TINY_BLOB
:
case
MYSQL_TYPE_MEDIUM_BLOB
:
case
MYSQL_TYPE_MEDIUM_BLOB
:
...
@@ -2861,15 +2929,15 @@ static uint read_binary_time(MYSQL_TIME *tm, uchar **pos)
...
@@ -2861,15 +2929,15 @@ static uint read_binary_time(MYSQL_TIME *tm, uchar **pos)
}
}
to
=
*
pos
;
to
=
*
pos
;
tm
->
second_part
=
(
length
>
8
)
?
(
ulong
)
sint4korr
(
to
+
7
)
:
0
;
tm
->
neg
=
(
bool
)
to
[
0
]
;
tm
->
day
=
(
ulong
)
sint4korr
(
to
+
1
);
tm
->
day
=
(
ulong
)
sint4korr
(
to
+
1
);
tm
->
hour
=
(
uint
)
to
[
5
];
tm
->
hour
=
(
uint
)
to
[
5
];
tm
->
minute
=
(
uint
)
to
[
6
];
tm
->
minute
=
(
uint
)
to
[
6
];
tm
->
second
=
(
uint
)
to
[
7
];
tm
->
second
=
(
uint
)
to
[
7
];
tm
->
second_part
=
(
length
>
8
)
?
(
ulong
)
sint4korr
(
to
+
8
)
:
0
;
tm
->
year
=
tm
->
month
=
0
;
tm
->
year
=
tm
->
month
=
0
;
tm
->
neg
=
(
bool
)
to
[
0
];
return
length
;
return
length
;
}
}
...
@@ -2886,7 +2954,11 @@ static uint read_binary_datetime(MYSQL_TIME *tm, uchar **pos)
...
@@ -2886,7 +2954,11 @@ static uint read_binary_datetime(MYSQL_TIME *tm, uchar **pos)
}
}
to
=
*
pos
;
to
=
*
pos
;
tm
->
second_part
=
(
length
>
7
)
?
(
ulong
)
sint4korr
(
to
+
7
)
:
0
;
tm
->
neg
=
0
;
tm
->
year
=
(
uint
)
sint2korr
(
to
);
tm
->
month
=
(
uint
)
to
[
2
];
tm
->
day
=
(
uint
)
to
[
3
];
if
(
length
>
4
)
if
(
length
>
4
)
{
{
...
@@ -2896,11 +2968,7 @@ static uint read_binary_datetime(MYSQL_TIME *tm, uchar **pos)
...
@@ -2896,11 +2968,7 @@ static uint read_binary_datetime(MYSQL_TIME *tm, uchar **pos)
}
}
else
else
tm
->
hour
=
tm
->
minute
=
tm
->
second
=
0
;
tm
->
hour
=
tm
->
minute
=
tm
->
second
=
0
;
tm
->
second_part
=
(
length
>
7
)
?
(
ulong
)
sint4korr
(
to
+
7
)
:
0
;
tm
->
year
=
(
uint
)
sint2korr
(
to
);
tm
->
month
=
(
uint
)
to
[
2
];
tm
->
day
=
(
uint
)
to
[
3
];
tm
->
neg
=
0
;
return
length
;
return
length
;
}
}
...
...
mysys/charset.c
View file @
4643854b
...
@@ -982,8 +982,9 @@ static my_bool init_uca_charsets()
...
@@ -982,8 +982,9 @@ static my_bool init_uca_charsets()
{
{
my_tailoring
*
t
;
my_tailoring
*
t
;
CHARSET_INFO
cs
=
my_charset_ucs2_general_uca
;
CHARSET_INFO
cs
=
my_charset_ucs2_general_uca
;
cs
.
state
=
MY_CS_STRNXFRM
|
MY_CS_UNICODE
|
MY_CS_NONTEXT
;
char
name
[
64
];
char
name
[
64
];
cs
.
state
=
MY_CS_STRNXFRM
|
MY_CS_UNICODE
|
MY_CS_NONTEXT
;
for
(
t
=
tailoring
;
t
->
tailoring
;
t
++
)
for
(
t
=
tailoring
;
t
->
tailoring
;
t
++
)
{
{
cs
.
number
=
128
+
t
->
number
;
cs
.
number
=
128
+
t
->
number
;
...
...
sql/item.cc
View file @
4643854b
...
@@ -629,6 +629,7 @@ Item_param::Item_param(unsigned pos_in_query_arg) :
...
@@ -629,6 +629,7 @@ Item_param::Item_param(unsigned pos_in_query_arg) :
state
(
NO_VALUE
),
state
(
NO_VALUE
),
item_result_type
(
STRING_RESULT
),
item_result_type
(
STRING_RESULT
),
item_type
(
STRING_ITEM
),
item_type
(
STRING_ITEM
),
param_type
(
MYSQL_TYPE_STRING
),
pos_in_query
(
pos_in_query_arg
),
pos_in_query
(
pos_in_query_arg
),
set_param_func
(
default_set_param_func
)
set_param_func
(
default_set_param_func
)
{
{
...
@@ -870,6 +871,17 @@ bool Item_param::get_time(TIME *res)
...
@@ -870,6 +871,17 @@ bool Item_param::get_time(TIME *res)
}
}
bool
Item_param
::
get_date
(
TIME
*
res
,
uint
fuzzydate
)
{
if
(
state
==
TIME_VALUE
)
{
*
res
=
value
.
time
;
return
0
;
}
return
Item
::
get_date
(
res
,
fuzzydate
);
}
double
Item_param
::
val
()
double
Item_param
::
val
()
{
{
switch
(
state
)
{
switch
(
state
)
{
...
...
sql/item.h
View file @
4643854b
...
@@ -465,6 +465,16 @@ public:
...
@@ -465,6 +465,16 @@ public:
/* Cached values for virtual methods to save us one switch. */
/* Cached values for virtual methods to save us one switch. */
enum
Item_result
item_result_type
;
enum
Item_result
item_result_type
;
enum
Type
item_type
;
enum
Type
item_type
;
/*
Used when this item is used in a temporary table.
This is NOT placeholder metadata sent to client, as this value
is assigned after sending metadata (in setup_one_conversion_function).
For example in case of 'SELECT ?' you'll get MYSQL_TYPE_STRING both
in result set and placeholders metadata, no matter what type you will
supply for this placeholder in mysql_stmt_execute.
*/
enum
enum_field_types
param_type
;
/*
/*
Offset of placeholder inside statement text. Used to create
Offset of placeholder inside statement text. Used to create
no-placeholders version of this statement for the binary log.
no-placeholders version of this statement for the binary log.
...
@@ -475,12 +485,13 @@ public:
...
@@ -475,12 +485,13 @@ public:
enum
Item_result
result_type
()
const
{
return
item_result_type
;
}
enum
Item_result
result_type
()
const
{
return
item_result_type
;
}
enum
Type
type
()
const
{
return
item_type
;
}
enum
Type
type
()
const
{
return
item_type
;
}
enum_field_types
field_type
()
const
{
return
MYSQL_TYPE_STRING
;
}
enum_field_types
field_type
()
const
{
return
param_type
;
}
double
val
();
double
val
();
longlong
val_int
();
longlong
val_int
();
String
*
val_str
(
String
*
);
String
*
val_str
(
String
*
);
bool
get_time
(
TIME
*
tm
);
bool
get_time
(
TIME
*
tm
);
bool
get_date
(
TIME
*
tm
,
uint
fuzzydate
);
int
save_in_field
(
Field
*
field
,
bool
no_conversions
);
int
save_in_field
(
Field
*
field
,
bool
no_conversions
);
void
set_null
();
void
set_null
();
...
...
sql/protocol.cc
View file @
4643854b
...
@@ -26,6 +26,8 @@
...
@@ -26,6 +26,8 @@
#include "mysql_priv.h"
#include "mysql_priv.h"
#include <stdarg.h>
#include <stdarg.h>
static
const
unsigned
int
PACKET_BUFFER_EXTRA_ALLOC
=
1024
;
#ifndef EMBEDDED_LIBRARY
#ifndef EMBEDDED_LIBRARY
bool
Protocol
::
net_store_data
(
const
char
*
from
,
uint
length
)
bool
Protocol
::
net_store_data
(
const
char
*
from
,
uint
length
)
#else
#else
...
@@ -687,7 +689,7 @@ bool Protocol_simple::store_null()
...
@@ -687,7 +689,7 @@ bool Protocol_simple::store_null()
#endif
#endif
char
buff
[
1
];
char
buff
[
1
];
buff
[
0
]
=
(
char
)
251
;
buff
[
0
]
=
(
char
)
251
;
return
packet
->
append
(
buff
,
sizeof
(
buff
),
PACKET_BUFFE
T
_EXTRA_ALLOC
);
return
packet
->
append
(
buff
,
sizeof
(
buff
),
PACKET_BUFFE
R
_EXTRA_ALLOC
);
}
}
#endif
#endif
...
@@ -990,7 +992,7 @@ bool Protocol_prep::store_tiny(longlong from)
...
@@ -990,7 +992,7 @@ bool Protocol_prep::store_tiny(longlong from)
char
buff
[
1
];
char
buff
[
1
];
field_pos
++
;
field_pos
++
;
buff
[
0
]
=
(
uchar
)
from
;
buff
[
0
]
=
(
uchar
)
from
;
return
packet
->
append
(
buff
,
sizeof
(
buff
),
PACKET_BUFFE
T
_EXTRA_ALLOC
);
return
packet
->
append
(
buff
,
sizeof
(
buff
),
PACKET_BUFFE
R
_EXTRA_ALLOC
);
}
}
...
@@ -1002,7 +1004,7 @@ bool Protocol_prep::store_short(longlong from)
...
@@ -1002,7 +1004,7 @@ bool Protocol_prep::store_short(longlong from)
field_types
[
field_pos
]
==
MYSQL_TYPE_YEAR
);
field_types
[
field_pos
]
==
MYSQL_TYPE_YEAR
);
#endif
#endif
field_pos
++
;
field_pos
++
;
char
*
to
=
packet
->
prep_append
(
2
,
PACKET_BUFFE
T
_EXTRA_ALLOC
);
char
*
to
=
packet
->
prep_append
(
2
,
PACKET_BUFFE
R
_EXTRA_ALLOC
);
if
(
!
to
)
if
(
!
to
)
return
1
;
return
1
;
int2store
(
to
,
(
int
)
from
);
int2store
(
to
,
(
int
)
from
);
...
@@ -1018,7 +1020,7 @@ bool Protocol_prep::store_long(longlong from)
...
@@ -1018,7 +1020,7 @@ bool Protocol_prep::store_long(longlong from)
field_types
[
field_pos
]
==
MYSQL_TYPE_LONG
);
field_types
[
field_pos
]
==
MYSQL_TYPE_LONG
);
#endif
#endif
field_pos
++
;
field_pos
++
;
char
*
to
=
packet
->
prep_append
(
4
,
PACKET_BUFFE
T
_EXTRA_ALLOC
);
char
*
to
=
packet
->
prep_append
(
4
,
PACKET_BUFFE
R
_EXTRA_ALLOC
);
if
(
!
to
)
if
(
!
to
)
return
1
;
return
1
;
int4store
(
to
,
from
);
int4store
(
to
,
from
);
...
@@ -1033,7 +1035,7 @@ bool Protocol_prep::store_longlong(longlong from, bool unsigned_flag)
...
@@ -1033,7 +1035,7 @@ bool Protocol_prep::store_longlong(longlong from, bool unsigned_flag)
field_types
[
field_pos
]
==
MYSQL_TYPE_LONGLONG
);
field_types
[
field_pos
]
==
MYSQL_TYPE_LONGLONG
);
#endif
#endif
field_pos
++
;
field_pos
++
;
char
*
to
=
packet
->
prep_append
(
8
,
PACKET_BUFFE
T
_EXTRA_ALLOC
);
char
*
to
=
packet
->
prep_append
(
8
,
PACKET_BUFFE
R
_EXTRA_ALLOC
);
if
(
!
to
)
if
(
!
to
)
return
1
;
return
1
;
int8store
(
to
,
from
);
int8store
(
to
,
from
);
...
@@ -1048,7 +1050,7 @@ bool Protocol_prep::store(float from, uint32 decimals, String *buffer)
...
@@ -1048,7 +1050,7 @@ bool Protocol_prep::store(float from, uint32 decimals, String *buffer)
field_types
[
field_pos
]
==
MYSQL_TYPE_FLOAT
);
field_types
[
field_pos
]
==
MYSQL_TYPE_FLOAT
);
#endif
#endif
field_pos
++
;
field_pos
++
;
char
*
to
=
packet
->
prep_append
(
4
,
PACKET_BUFFE
T
_EXTRA_ALLOC
);
char
*
to
=
packet
->
prep_append
(
4
,
PACKET_BUFFE
R
_EXTRA_ALLOC
);
if
(
!
to
)
if
(
!
to
)
return
1
;
return
1
;
float4store
(
to
,
from
);
float4store
(
to
,
from
);
...
@@ -1063,7 +1065,7 @@ bool Protocol_prep::store(double from, uint32 decimals, String *buffer)
...
@@ -1063,7 +1065,7 @@ bool Protocol_prep::store(double from, uint32 decimals, String *buffer)
field_types
[
field_pos
]
==
MYSQL_TYPE_DOUBLE
);
field_types
[
field_pos
]
==
MYSQL_TYPE_DOUBLE
);
#endif
#endif
field_pos
++
;
field_pos
++
;
char
*
to
=
packet
->
prep_append
(
8
,
PACKET_BUFFE
T
_EXTRA_ALLOC
);
char
*
to
=
packet
->
prep_append
(
8
,
PACKET_BUFFE
R
_EXTRA_ALLOC
);
if
(
!
to
)
if
(
!
to
)
return
1
;
return
1
;
float8store
(
to
,
from
);
float8store
(
to
,
from
);
...
@@ -1112,7 +1114,7 @@ bool Protocol_prep::store(TIME *tm)
...
@@ -1112,7 +1114,7 @@ bool Protocol_prep::store(TIME *tm)
else
else
length
=
0
;
length
=
0
;
buff
[
0
]
=
(
char
)
length
;
// Length is stored first
buff
[
0
]
=
(
char
)
length
;
// Length is stored first
return
packet
->
append
(
buff
,
length
+
1
,
PACKET_BUFFE
T
_EXTRA_ALLOC
);
return
packet
->
append
(
buff
,
length
+
1
,
PACKET_BUFFE
R
_EXTRA_ALLOC
);
}
}
bool
Protocol_prep
::
store_date
(
TIME
*
tm
)
bool
Protocol_prep
::
store_date
(
TIME
*
tm
)
...
@@ -1129,7 +1131,7 @@ bool Protocol_prep::store_time(TIME *tm)
...
@@ -1129,7 +1131,7 @@ bool Protocol_prep::store_time(TIME *tm)
DBUG_ASSERT
(
field_types
==
0
||
DBUG_ASSERT
(
field_types
==
0
||
field_types
[
field_pos
]
==
MYSQL_TYPE_TIME
);
field_types
[
field_pos
]
==
MYSQL_TYPE_TIME
);
#endif
#endif
char
buff
[
1
5
],
*
pos
;
char
buff
[
1
3
],
*
pos
;
uint
length
;
uint
length
;
field_pos
++
;
field_pos
++
;
pos
=
buff
+
1
;
pos
=
buff
+
1
;
...
@@ -1140,13 +1142,13 @@ bool Protocol_prep::store_time(TIME *tm)
...
@@ -1140,13 +1142,13 @@ bool Protocol_prep::store_time(TIME *tm)
pos
[
7
]
=
(
uchar
)
tm
->
second
;
pos
[
7
]
=
(
uchar
)
tm
->
second
;
int4store
(
pos
+
8
,
tm
->
second_part
);
int4store
(
pos
+
8
,
tm
->
second_part
);
if
(
tm
->
second_part
)
if
(
tm
->
second_part
)
length
=
1
1
;
length
=
1
2
;
else
if
(
tm
->
hour
||
tm
->
minute
||
tm
->
second
||
tm
->
day
)
else
if
(
tm
->
hour
||
tm
->
minute
||
tm
->
second
||
tm
->
day
)
length
=
8
;
length
=
8
;
else
else
length
=
0
;
length
=
0
;
buff
[
0
]
=
(
char
)
length
;
// Length is stored first
buff
[
0
]
=
(
char
)
length
;
// Length is stored first
return
packet
->
append
(
buff
,
length
+
1
,
PACKET_BUFFE
T
_EXTRA_ALLOC
);
return
packet
->
append
(
buff
,
length
+
1
,
PACKET_BUFFE
R
_EXTRA_ALLOC
);
}
}
#ifdef EMBEDDED_LIBRARY
#ifdef EMBEDDED_LIBRARY
...
...
sql/protocol.h
View file @
4643854b
...
@@ -18,7 +18,6 @@
...
@@ -18,7 +18,6 @@
#pragma interface
/* gcc class implementation */
#pragma interface
/* gcc class implementation */
#endif
#endif
#define PACKET_BUFFET_EXTRA_ALLOC 1024
class
i_string
;
class
i_string
;
class
THD
;
class
THD
;
...
...
sql/sql_prepare.cc
View file @
4643854b
...
@@ -340,19 +340,18 @@ static void set_param_time(Item_param *param, uchar **pos, ulong len)
...
@@ -340,19 +340,18 @@ static void set_param_time(Item_param *param, uchar **pos, ulong len)
uchar
*
to
=
*
pos
;
uchar
*
to
=
*
pos
;
TIME
tm
;
TIME
tm
;
/* TODO: why length is compared with 8 here? */
tm
.
neg
=
(
bool
)
to
[
0
];
tm
.
second_part
=
(
length
>
8
)
?
(
ulong
)
sint4korr
(
to
+
7
)
:
0
;
day
=
(
uint
)
sint4korr
(
to
+
1
);
/*
/*
Note, that though ranges of hour, minute and second are not checked
Note, that though ranges of hour, minute and second are not checked
here we rely on them being < 256: otherwise
here we rely on them being < 256: otherwise
we'll get buffer overflow in make_{date,time} functions,
we'll get buffer overflow in make_{date,time} functions,
which are called when time value is converted to string.
which are called when time value is converted to string.
*/
*/
day
=
(
uint
)
sint4korr
(
to
+
1
);
tm
.
hour
=
(
uint
)
to
[
5
]
+
day
*
24
;
tm
.
hour
=
(
uint
)
to
[
5
]
+
day
*
24
;
tm
.
minute
=
(
uint
)
to
[
6
];
tm
.
minute
=
(
uint
)
to
[
6
];
tm
.
second
=
(
uint
)
to
[
7
];
tm
.
second
=
(
uint
)
to
[
7
];
tm
.
second_part
=
(
length
>
8
)
?
(
ulong
)
sint4korr
(
to
+
8
)
:
0
;
if
(
tm
.
hour
>
838
)
if
(
tm
.
hour
>
838
)
{
{
/* TODO: add warning 'Data truncated' here */
/* TODO: add warning 'Data truncated' here */
...
@@ -361,7 +360,6 @@ static void set_param_time(Item_param *param, uchar **pos, ulong len)
...
@@ -361,7 +360,6 @@ static void set_param_time(Item_param *param, uchar **pos, ulong len)
tm
.
second
=
59
;
tm
.
second
=
59
;
}
}
tm
.
day
=
tm
.
year
=
tm
.
month
=
0
;
tm
.
day
=
tm
.
year
=
tm
.
month
=
0
;
tm
.
neg
=
(
bool
)
to
[
0
];
param
->
set_time
(
&
tm
,
TIMESTAMP_TIME
,
param
->
set_time
(
&
tm
,
TIMESTAMP_TIME
,
MAX_TIME_WIDTH
*
MY_CHARSET_BIN_MB_MAXLEN
);
MAX_TIME_WIDTH
*
MY_CHARSET_BIN_MB_MAXLEN
);
...
@@ -378,8 +376,10 @@ static void set_param_datetime(Item_param *param, uchar **pos, ulong len)
...
@@ -378,8 +376,10 @@ static void set_param_datetime(Item_param *param, uchar **pos, ulong len)
uchar
*
to
=
*
pos
;
uchar
*
to
=
*
pos
;
TIME
tm
;
TIME
tm
;
tm
.
second_part
=
(
length
>
7
)
?
(
ulong
)
sint4korr
(
to
+
7
)
:
0
;
tm
.
neg
=
0
;
tm
.
year
=
(
uint
)
sint2korr
(
to
);
tm
.
month
=
(
uint
)
to
[
2
];
tm
.
day
=
(
uint
)
to
[
3
];
/*
/*
Note, that though ranges of hour, minute and second are not checked
Note, that though ranges of hour, minute and second are not checked
here we rely on them being < 256: otherwise
here we rely on them being < 256: otherwise
...
@@ -394,10 +394,7 @@ static void set_param_datetime(Item_param *param, uchar **pos, ulong len)
...
@@ -394,10 +394,7 @@ static void set_param_datetime(Item_param *param, uchar **pos, ulong len)
else
else
tm
.
hour
=
tm
.
minute
=
tm
.
second
=
0
;
tm
.
hour
=
tm
.
minute
=
tm
.
second
=
0
;
tm
.
year
=
(
uint
)
sint2korr
(
to
);
tm
.
second_part
=
(
length
>
7
)
?
(
ulong
)
sint4korr
(
to
+
7
)
:
0
;
tm
.
month
=
(
uint
)
to
[
2
];
tm
.
day
=
(
uint
)
to
[
3
];
tm
.
neg
=
0
;
param
->
set_time
(
&
tm
,
TIMESTAMP_DATETIME
,
param
->
set_time
(
&
tm
,
TIMESTAMP_DATETIME
,
MAX_DATETIME_WIDTH
*
MY_CHARSET_BIN_MB_MAXLEN
);
MAX_DATETIME_WIDTH
*
MY_CHARSET_BIN_MB_MAXLEN
);
...
@@ -592,6 +589,7 @@ static void setup_one_conversion_function(THD *thd, Item_param *param,
...
@@ -592,6 +589,7 @@ static void setup_one_conversion_function(THD *thd, Item_param *param,
param
->
item_result_type
=
STRING_RESULT
;
param
->
item_result_type
=
STRING_RESULT
;
}
}
}
}
param
->
param_type
=
(
enum
enum_field_types
)
param_type
;
}
}
#ifndef EMBEDDED_LIBRARY
#ifndef EMBEDDED_LIBRARY
...
...
tests/client_test.c
View file @
4643854b
...
@@ -9802,6 +9802,73 @@ static void test_bug3796()
...
@@ -9802,6 +9802,73 @@ static void test_bug3796()
myquery
(
rc
);
myquery
(
rc
);
}
}
static
void
test_bug4026
()
{
MYSQL_STMT
*
stmt
;
MYSQL_BIND
bind
[
2
];
MYSQL_TIME
time_in
,
time_out
;
MYSQL_TIME
datetime_in
,
datetime_out
;
const
char
*
stmt_text
;
int
rc
;
myheader
(
"test_bug4026"
);
/* Check that microseconds are inserted and selected successfully */
/* Create a statement handle and prepare it with select */
stmt
=
mysql_stmt_init
(
mysql
);
stmt_text
=
"SELECT ?, ?"
;
rc
=
mysql_stmt_prepare
(
stmt
,
stmt_text
,
strlen
(
stmt_text
));
check_execute
(
stmt
,
rc
);
/* Bind input buffers */
bzero
(
bind
,
sizeof
(
bind
));
bzero
(
&
time_in
,
sizeof
(
time_in
));
bzero
(
&
time_out
,
sizeof
(
time_out
));
bzero
(
&
datetime_in
,
sizeof
(
datetime_in
));
bzero
(
&
datetime_out
,
sizeof
(
datetime_out
));
bind
[
0
].
buffer_type
=
MYSQL_TYPE_TIME
;
bind
[
0
].
buffer
=
(
char
*
)
&
time_in
;
bind
[
1
].
buffer_type
=
MYSQL_TYPE_DATETIME
;
bind
[
1
].
buffer
=
(
char
*
)
&
datetime_in
;
time_in
.
hour
=
23
;
time_in
.
minute
=
59
;
time_in
.
second
=
59
;
time_in
.
second_part
=
123456
;
datetime_in
=
time_in
;
datetime_in
.
year
=
2003
;
datetime_in
.
month
=
12
;
datetime_in
.
day
=
31
;
mysql_stmt_bind_param
(
stmt
,
bind
);
/* Execute the select statement */
rc
=
mysql_stmt_execute
(
stmt
);
check_execute
(
stmt
,
rc
);
bind
[
0
].
buffer
=
(
char
*
)
&
time_out
;
bind
[
1
].
buffer
=
(
char
*
)
&
datetime_out
;
mysql_stmt_bind_result
(
stmt
,
bind
);
rc
=
mysql_stmt_fetch
(
stmt
);
assert
(
rc
==
0
);
printf
(
"%d:%d:%d.%lu
\n
"
,
time_out
.
hour
,
time_out
.
minute
,
time_out
.
second
,
time_out
.
second_part
);
printf
(
"%d-%d-%d %d:%d:%d.%lu
\n
"
,
datetime_out
.
year
,
datetime_out
.
month
,
datetime_out
.
day
,
datetime_out
.
hour
,
datetime_out
.
minute
,
datetime_out
.
second
,
datetime_out
.
second_part
);
assert
(
memcmp
(
&
time_in
,
&
time_out
,
sizeof
(
time_in
))
==
0
);
assert
(
memcmp
(
&
datetime_in
,
&
datetime_out
,
sizeof
(
datetime_in
))
==
0
);
mysql_stmt_close
(
stmt
);
}
/*
/*
Read and parse arguments and MySQL options from my.cnf
Read and parse arguments and MySQL options from my.cnf
*/
*/
...
@@ -10094,6 +10161,7 @@ int main(int argc, char **argv)
...
@@ -10094,6 +10161,7 @@ int main(int argc, char **argv)
(Bug #3686 */
(Bug #3686 */
test_ps_i18n
();
/* test for i18n support in binary protocol */
test_ps_i18n
();
/* test for i18n support in binary protocol */
test_bug3796
();
/* test for select concat(?, <string>) */
test_bug3796
();
/* test for select concat(?, <string>) */
test_bug4026
();
/* test microseconds precision of time types */
/*
/*
XXX: PLEASE RUN THIS PROGRAM UNDER VALGRIND AND VERIFY THAT YOUR TEST
XXX: PLEASE RUN THIS PROGRAM UNDER VALGRIND AND VERIFY THAT YOUR TEST
DOESN'T CONTAIN WARNINGS/ERRORS BEFORE YOU PUSH.
DOESN'T CONTAIN WARNINGS/ERRORS BEFORE YOU PUSH.
...
...
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