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
2c30359a
Commit
2c30359a
authored
May 04, 2004
by
dlenev@brandersnatch.localdomain
Browse files
Options
Browse Files
Download
Plain Diff
Manual merge of bugfix for Bug #1664.
parents
af25c817
c7fbcbca
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
212 additions
and
22 deletions
+212
-22
sql/item.cc
sql/item.cc
+33
-1
sql/item.h
sql/item.h
+1
-1
sql/sql_prepare.cc
sql/sql_prepare.cc
+30
-20
tests/client_test.c
tests/client_test.c
+148
-0
No files found.
sql/item.cc
View file @
2c30359a
...
@@ -605,12 +605,19 @@ Item_param::Item_param(unsigned position) :
...
@@ -605,12 +605,19 @@ Item_param::Item_param(unsigned position) :
set_param_func
(
default_set_param_func
)
set_param_func
(
default_set_param_func
)
{
{
name
=
(
char
*
)
"?"
;
name
=
(
char
*
)
"?"
;
/*
Since we can't say whenever this item can be NULL or cannot be NULL
before mysql_stmt_execute(), so we assuming that it can be NULL until
value is set.
*/
maybe_null
=
1
;
}
}
void
Item_param
::
set_null
()
void
Item_param
::
set_null
()
{
{
DBUG_ENTER
(
"Item_param::set_null"
);
DBUG_ENTER
(
"Item_param::set_null"
);
maybe_null
=
null_value
=
value_is_set
=
1
;
/* These are cleared after each execution by reset() method */
null_value
=
value_is_set
=
1
;
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
...
@@ -620,6 +627,7 @@ void Item_param::set_int(longlong i)
...
@@ -620,6 +627,7 @@ void Item_param::set_int(longlong i)
int_value
=
(
longlong
)
i
;
int_value
=
(
longlong
)
i
;
item_type
=
INT_ITEM
;
item_type
=
INT_ITEM
;
value_is_set
=
1
;
value_is_set
=
1
;
maybe_null
=
0
;
DBUG_PRINT
(
"info"
,
(
"integer: %lld"
,
int_value
));
DBUG_PRINT
(
"info"
,
(
"integer: %lld"
,
int_value
));
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
...
@@ -630,6 +638,7 @@ void Item_param::set_double(double value)
...
@@ -630,6 +638,7 @@ void Item_param::set_double(double value)
real_value
=
value
;
real_value
=
value
;
item_type
=
REAL_ITEM
;
item_type
=
REAL_ITEM
;
value_is_set
=
1
;
value_is_set
=
1
;
maybe_null
=
0
;
DBUG_PRINT
(
"info"
,
(
"double: %lg"
,
real_value
));
DBUG_PRINT
(
"info"
,
(
"double: %lg"
,
real_value
));
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
...
@@ -641,6 +650,7 @@ void Item_param::set_value(const char *str, uint length)
...
@@ -641,6 +650,7 @@ void Item_param::set_value(const char *str, uint length)
str_value
.
copy
(
str
,
length
,
default_charset
());
str_value
.
copy
(
str
,
length
,
default_charset
());
item_type
=
STRING_ITEM
;
item_type
=
STRING_ITEM
;
value_is_set
=
1
;
value_is_set
=
1
;
maybe_null
=
0
;
DBUG_PRINT
(
"info"
,
(
"string: %s"
,
str_value
.
ptr
()));
DBUG_PRINT
(
"info"
,
(
"string: %s"
,
str_value
.
ptr
()));
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
...
@@ -665,6 +675,7 @@ void Item_param::set_time(TIME *tm, timestamp_type type)
...
@@ -665,6 +675,7 @@ void Item_param::set_time(TIME *tm, timestamp_type type)
item_is_time
=
TRUE
;
item_is_time
=
TRUE
;
item_type
=
STRING_ITEM
;
item_type
=
STRING_ITEM
;
value_is_set
=
1
;
value_is_set
=
1
;
maybe_null
=
0
;
}
}
...
@@ -673,6 +684,27 @@ void Item_param::set_longdata(const char *str, ulong length)
...
@@ -673,6 +684,27 @@ void Item_param::set_longdata(const char *str, ulong length)
str_value
.
append
(
str
,
length
);
str_value
.
append
(
str
,
length
);
long_data_supplied
=
1
;
long_data_supplied
=
1
;
value_is_set
=
1
;
value_is_set
=
1
;
maybe_null
=
0
;
}
/*
Resets parameter after execution.
SYNOPSIS
Item_param::reset()
NOTES
We clear null_value here instead of setting it in set_* methods,
because we want more easily handle case for long data.
*/
void
Item_param
::
reset
()
{
str_value
.
set
(
""
,
0
,
&
my_charset_bin
);
value_is_set
=
long_data_supplied
=
0
;
maybe_null
=
1
;
null_value
=
0
;
}
}
...
...
sql/item.h
View file @
2c30359a
...
@@ -419,7 +419,7 @@ public:
...
@@ -419,7 +419,7 @@ public:
void
set_long_end
();
void
set_long_end
();
void
set_time
(
TIME
*
tm
,
timestamp_type
type
);
void
set_time
(
TIME
*
tm
,
timestamp_type
type
);
bool
get_time
(
TIME
*
tm
);
bool
get_time
(
TIME
*
tm
);
void
reset
()
{}
void
reset
()
;
/*
/*
Assign placeholder value from bind data.
Assign placeholder value from bind data.
Note, that 'len' has different semantics in embedded library (as we
Note, that 'len' has different semantics in embedded library (as we
...
...
sql/sql_prepare.cc
View file @
2c30359a
...
@@ -91,7 +91,6 @@ public:
...
@@ -91,7 +91,6 @@ public:
uint
last_errno
;
uint
last_errno
;
char
last_error
[
MYSQL_ERRMSG_SIZE
];
char
last_error
[
MYSQL_ERRMSG_SIZE
];
bool
get_longdata_error
;
bool
get_longdata_error
;
bool
long_data_used
;
bool
log_full_query
;
bool
log_full_query
;
#ifndef EMBEDDED_LIBRARY
#ifndef EMBEDDED_LIBRARY
bool
(
*
set_params
)(
Prepared_statement
*
st
,
uchar
*
data
,
uchar
*
data_end
,
bool
(
*
set_params
)(
Prepared_statement
*
st
,
uchar
*
data
,
uchar
*
data_end
,
...
@@ -471,12 +470,11 @@ static bool insert_params_withlog(Prepared_statement *stmt, uchar *null_array,
...
@@ -471,12 +470,11 @@ static bool insert_params_withlog(Prepared_statement *stmt, uchar *null_array,
{
{
if
(
is_param_null
(
null_array
,
it
-
begin
))
if
(
is_param_null
(
null_array
,
it
-
begin
))
{
{
param
->
maybe_null
=
param
->
null_value
=
param
->
value_is_set
=
1
;
param
->
set_null
()
;
res
=
&
my_null_string
;
res
=
&
my_null_string
;
}
}
else
else
{
{
param
->
maybe_null
=
param
->
null_value
=
0
;
if
(
read_pos
>=
data_end
)
if
(
read_pos
>=
data_end
)
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
param
->
set_param_func
(
param
,
&
read_pos
,
data_end
-
read_pos
);
param
->
set_param_func
(
param
,
&
read_pos
,
data_end
-
read_pos
);
...
@@ -509,10 +507,9 @@ static bool insert_params(Prepared_statement *stmt, uchar *null_array,
...
@@ -509,10 +507,9 @@ static bool insert_params(Prepared_statement *stmt, uchar *null_array,
if
(
!
param
->
long_data_supplied
)
if
(
!
param
->
long_data_supplied
)
{
{
if
(
is_param_null
(
null_array
,
it
-
begin
))
if
(
is_param_null
(
null_array
,
it
-
begin
))
param
->
maybe_null
=
param
->
null_value
=
param
->
value_is_set
=
1
;
param
->
set_null
()
;
else
else
{
{
param
->
maybe_null
=
param
->
null_value
=
0
;
if
(
read_pos
>=
data_end
)
if
(
read_pos
>=
data_end
)
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
param
->
set_param_func
(
param
,
&
read_pos
,
data_end
-
read_pos
);
param
->
set_param_func
(
param
,
&
read_pos
,
data_end
-
read_pos
);
...
@@ -574,11 +571,10 @@ static bool emb_insert_params(Prepared_statement *stmt)
...
@@ -574,11 +571,10 @@ static bool emb_insert_params(Prepared_statement *stmt)
if
(
!
param
->
long_data_supplied
)
if
(
!
param
->
long_data_supplied
)
{
{
if
(
*
client_param
->
is_null
)
if
(
*
client_param
->
is_null
)
param
->
maybe_null
=
param
->
null_value
=
1
;
param
->
set_null
()
;
else
else
{
{
uchar
*
buff
=
(
uchar
*
)
client_param
->
buffer
;
uchar
*
buff
=
(
uchar
*
)
client_param
->
buffer
;
param
->
maybe_null
=
param
->
null_value
=
0
;
param
->
set_param_func
(
param
,
&
buff
,
param
->
set_param_func
(
param
,
&
buff
,
client_param
->
length
?
client_param
->
length
?
*
client_param
->
length
:
*
client_param
->
length
:
...
@@ -616,13 +612,12 @@ static bool emb_insert_params_withlog(Prepared_statement *stmt)
...
@@ -616,13 +612,12 @@ static bool emb_insert_params_withlog(Prepared_statement *stmt)
{
{
if
(
*
client_param
->
is_null
)
if
(
*
client_param
->
is_null
)
{
{
param
->
maybe_null
=
param
->
null_value
=
1
;
param
->
set_null
()
;
res
=
&
my_null_string
;
res
=
&
my_null_string
;
}
}
else
else
{
{
uchar
*
buff
=
(
uchar
*
)
client_param
->
buffer
;
uchar
*
buff
=
(
uchar
*
)
client_param
->
buffer
;
param
->
maybe_null
=
param
->
null_value
=
0
;
param
->
set_param_func
(
param
,
&
buff
,
param
->
set_param_func
(
param
,
&
buff
,
client_param
->
length
?
client_param
->
length
?
*
client_param
->
length
:
*
client_param
->
length
:
...
@@ -1451,6 +1446,24 @@ static void reset_stmt_for_execute(Prepared_statement *stmt)
...
@@ -1451,6 +1446,24 @@ static void reset_stmt_for_execute(Prepared_statement *stmt)
}
}
}
}
/*
Clears parameters from data left from previous execution or long data
SYNOPSIS
reset_stmt_params()
stmt - prepared statement for which parameters should be reset
*/
static
void
reset_stmt_params
(
Prepared_statement
*
stmt
)
{
Item_param
**
item
=
stmt
->
param_array
;
Item_param
**
end
=
item
+
stmt
->
param_count
;
for
(;
item
<
end
;
++
item
)
(
**
item
).
reset
();
}
/*
/*
Executes previously prepared query.
Executes previously prepared query.
If there is any parameters, then replace markers with the data supplied
If there is any parameters, then replace markers with the data supplied
...
@@ -1524,11 +1537,13 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
...
@@ -1524,11 +1537,13 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
my_pthread_setprio
(
pthread_self
(),
WAIT_PRIOR
);
my_pthread_setprio
(
pthread_self
(),
WAIT_PRIOR
);
cleanup_items
(
stmt
->
free_list
);
cleanup_items
(
stmt
->
free_list
);
reset_stmt_params
(
stmt
);
close_thread_tables
(
thd
);
// to close derived tables
close_thread_tables
(
thd
);
// to close derived tables
thd
->
set_statement
(
&
thd
->
stmt_backup
);
thd
->
set_statement
(
&
thd
->
stmt_backup
);
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
set_params_data_err:
set_params_data_err:
reset_stmt_params
(
stmt
);
thd
->
set_statement
(
&
thd
->
stmt_backup
);
thd
->
set_statement
(
&
thd
->
stmt_backup
);
my_error
(
ER_WRONG_ARGUMENTS
,
MYF
(
0
),
"mysql_execute"
);
my_error
(
ER_WRONG_ARGUMENTS
,
MYF
(
0
),
"mysql_execute"
);
send_error
(
thd
);
send_error
(
thd
);
...
@@ -1564,15 +1579,12 @@ void mysql_stmt_reset(THD *thd, char *packet)
...
@@ -1564,15 +1579,12 @@ void mysql_stmt_reset(THD *thd, char *packet)
stmt
->
get_longdata_error
=
0
;
stmt
->
get_longdata_error
=
0
;
/* Free long data if used */
/*
if
(
stmt
->
long_data_used
)
Clear parameters from data which could be set by
{
mysql_stmt_send_long_data() call.
Item_param
**
item
=
stmt
->
param_array
;
*/
Item_param
**
end
=
item
+
stmt
->
param_count
;
reset_stmt_params
(
stmt
);
stmt
->
long_data_used
=
0
;
for
(;
item
<
end
;
item
++
)
(
**
item
).
reset
();
}
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
...
@@ -1658,7 +1670,6 @@ void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length)
...
@@ -1658,7 +1670,6 @@ void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length)
#else
#else
param
->
set_longdata
(
thd
->
extra_data
,
thd
->
extra_length
);
param
->
set_longdata
(
thd
->
extra_data
,
thd
->
extra_length
);
#endif
#endif
stmt
->
long_data_used
=
1
;
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
...
@@ -1670,7 +1681,6 @@ Prepared_statement::Prepared_statement(THD *thd_arg)
...
@@ -1670,7 +1681,6 @@ Prepared_statement::Prepared_statement(THD *thd_arg)
param_count
(
0
),
param_count
(
0
),
last_errno
(
0
),
last_errno
(
0
),
get_longdata_error
(
0
),
get_longdata_error
(
0
),
long_data_used
(
0
),
log_full_query
(
0
)
log_full_query
(
0
)
{
{
*
last_error
=
'\0'
;
*
last_error
=
'\0'
;
...
...
tests/client_test.c
View file @
2c30359a
...
@@ -9432,6 +9432,152 @@ select col1 FROM t1 where col1=2");
...
@@ -9432,6 +9432,152 @@ select col1 FROM t1 where col1=2");
}
}
/*
This tests for various mysql_send_long_data bugs described in #1664
*/
static
void
test_bug1664
()
{
MYSQL_STMT
*
stmt
;
int
rc
,
int_data
;
const
char
*
data
;
const
char
*
str_data
=
"Simple string"
;
MYSQL_BIND
bind
[
2
];
const
char
*
query
=
"INSERT INTO test_long_data(col2, col1) VALUES(?,?)"
;
myheader
(
"test_bug1664"
);
rc
=
mysql_query
(
mysql
,
"DROP TABLE IF EXISTS test_long_data"
);
myquery
(
rc
);
rc
=
mysql_query
(
mysql
,
"CREATE TABLE test_long_data(col1 int, col2 long varchar)"
);
myquery
(
rc
);
stmt
=
mysql_stmt_init
(
mysql
);
mystmt_init
(
stmt
);
rc
=
mysql_stmt_prepare
(
stmt
,
query
,
strlen
(
query
));
mystmt
(
stmt
,
rc
);
verify_param_count
(
stmt
,
2
);
bzero
(
&
bind
,
sizeof
(
bind
));
bind
[
0
].
buffer_type
=
FIELD_TYPE_STRING
;
bind
[
0
].
buffer
=
(
char
*
)
str_data
;
bind
[
0
].
buffer_length
=
strlen
(
str_data
);
bind
[
1
].
buffer
=
(
char
*
)
&
int_data
;
bind
[
1
].
buffer_type
=
FIELD_TYPE_LONG
;
rc
=
mysql_stmt_bind_param
(
stmt
,
bind
);
mystmt
(
stmt
,
rc
);
int_data
=
1
;
/*
Let us supply empty long_data. This should work and should
not break following execution.
*/
data
=
""
;
rc
=
mysql_stmt_send_long_data
(
stmt
,
0
,
data
,
strlen
(
data
));
mystmt
(
stmt
,
rc
);
rc
=
mysql_stmt_execute
(
stmt
);
fprintf
(
stdout
,
" mysql_execute() returned %d
\n
"
,
rc
);
mystmt
(
stmt
,
rc
);
verify_col_data
(
"test_long_data"
,
"col1"
,
"1"
);
verify_col_data
(
"test_long_data"
,
"col2"
,
""
);
rc
=
mysql_query
(
mysql
,
"DELETE FROM test_long_data"
);
myquery
(
rc
);
/* This should pass OK */
data
=
(
char
*
)
"Data"
;
rc
=
mysql_stmt_send_long_data
(
stmt
,
0
,
data
,
strlen
(
data
));
mystmt
(
stmt
,
rc
);
rc
=
mysql_stmt_execute
(
stmt
);
fprintf
(
stdout
,
" mysql_execute() returned %d
\n
"
,
rc
);
mystmt
(
stmt
,
rc
);
verify_col_data
(
"test_long_data"
,
"col1"
,
"1"
);
verify_col_data
(
"test_long_data"
,
"col2"
,
"Data"
);
/* clean up */
rc
=
mysql_query
(
mysql
,
"DELETE FROM test_long_data"
);
myquery
(
rc
);
/*
Now we are changing int parameter and don't do anything
with first parameter. Second mysql_execute() should run
OK treating this first parameter as string parameter.
*/
int_data
=
2
;
/* execute */
rc
=
mysql_stmt_execute
(
stmt
);
fprintf
(
stdout
,
" mysql_execute() returned %d
\n
"
,
rc
);
mystmt
(
stmt
,
rc
);
verify_col_data
(
"test_long_data"
,
"col1"
,
"2"
);
verify_col_data
(
"test_long_data"
,
"col2"
,
str_data
);
/* clean up */
rc
=
mysql_query
(
mysql
,
"DELETE FROM test_long_data"
);
myquery
(
rc
);
/*
Now we are sending other long data. It should not be
concatened to previous.
*/
data
=
(
char
*
)
"SomeOtherData"
;
rc
=
mysql_stmt_send_long_data
(
stmt
,
0
,
data
,
strlen
(
data
));
mystmt
(
stmt
,
rc
);
rc
=
mysql_stmt_execute
(
stmt
);
fprintf
(
stdout
,
" mysql_execute() returned %d
\n
"
,
rc
);
mystmt
(
stmt
,
rc
);
verify_col_data
(
"test_long_data"
,
"col1"
,
"2"
);
verify_col_data
(
"test_long_data"
,
"col2"
,
"SomeOtherData"
);
mysql_stmt_close
(
stmt
);
/* clean up */
rc
=
mysql_query
(
mysql
,
"DELETE FROM test_long_data"
);
myquery
(
rc
);
/* Now let us test how mysql_stmt_reset works. */
stmt
=
mysql_stmt_init
(
mysql
);
mystmt_init
(
stmt
);
rc
=
mysql_stmt_prepare
(
stmt
,
query
,
strlen
(
query
));
mystmt
(
stmt
,
rc
);
rc
=
mysql_bind_param
(
stmt
,
bind
);
mystmt
(
stmt
,
rc
);
data
=
(
char
*
)
"SomeData"
;
rc
=
mysql_stmt_send_long_data
(
stmt
,
0
,
data
,
strlen
(
data
));
mystmt
(
stmt
,
rc
);
rc
=
mysql_stmt_reset
(
stmt
);
mystmt
(
stmt
,
rc
);
rc
=
mysql_stmt_execute
(
stmt
);
fprintf
(
stdout
,
" mysql_execute() returned %d
\n
"
,
rc
);
mystmt
(
stmt
,
rc
);
verify_col_data
(
"test_long_data"
,
"col1"
,
"2"
);
verify_col_data
(
"test_long_data"
,
"col2"
,
str_data
);
mysql_stmt_close
(
stmt
);
/* Final clean up */
rc
=
mysql_query
(
mysql
,
"DROP TABLE test_long_data"
);
myquery
(
rc
);
}
/*
/*
Read and parse arguments and MySQL options from my.cnf
Read and parse arguments and MySQL options from my.cnf
*/
*/
...
@@ -9712,6 +9858,8 @@ int main(int argc, char **argv)
...
@@ -9712,6 +9858,8 @@ int main(int argc, char **argv)
test_xjoin
();
/* complex join test */
test_xjoin
();
/* complex join test */
test_bug3035
();
/* inserts of INT32_MAX/UINT32_MAX */
test_bug3035
();
/* inserts of INT32_MAX/UINT32_MAX */
test_union2
();
/* repeatable execution of union (Bug #3577) */
test_union2
();
/* repeatable execution of union (Bug #3577) */
test_bug1664
();
/* test for bugs in mysql_stmt_send_long_data()
call (Bug #1664) */
end_time
=
time
((
time_t
*
)
0
);
end_time
=
time
((
time_t
*
)
0
);
total_time
+=
difftime
(
end_time
,
start_time
);
total_time
+=
difftime
(
end_time
,
start_time
);
...
...
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