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
51374e56
Commit
51374e56
authored
Sep 02, 2003
by
bell@sanja.is.com.ua
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fixed BUG#1180 (changing WHERE clause of prepared statements by optimisation)
parent
0f456a48
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
186 additions
and
7 deletions
+186
-7
sql/item.h
sql/item.h
+5
-1
sql/item_cmpfunc.cc
sql/item_cmpfunc.cc
+25
-0
sql/item_cmpfunc.h
sql/item_cmpfunc.h
+28
-5
sql/item_func.cc
sql/item_func.cc
+21
-0
sql/item_func.h
sql/item_func.h
+3
-0
sql/sql_lex.cc
sql/sql_lex.cc
+1
-0
sql/sql_lex.h
sql/sql_lex.h
+1
-0
sql/sql_prepare.cc
sql/sql_prepare.cc
+22
-1
tests/client_test.c
tests/client_test.c
+80
-0
No files found.
sql/item.h
View file @
51374e56
...
...
@@ -120,6 +120,9 @@ class Item {
Constructor used by Item_field, Item_ref & agregate (sum) functions.
Used for duplicating lists in processing queries with temporary
tables
Also it used for Item_cond_and/Item_cond_or for creating
top AND/OR ctructure of WHERE clause to protect it of
optimisation changes in prepared statements
*/
Item
(
THD
*
thd
,
Item
&
item
);
virtual
~
Item
()
{
name
=
0
;
}
/*lint -e1509 */
...
...
@@ -184,6 +187,7 @@ class Item {
virtual
void
save_in_result_field
(
bool
no_conversions
)
{}
virtual
void
no_rows_in_result
()
{}
virtual
Item
*
copy_or_same
(
THD
*
thd
)
{
return
this
;
}
virtual
Item
*
copy_andor_structure
(
THD
*
thd
)
{
return
this
;
}
virtual
Item
*
real_item
()
{
return
this
;
}
virtual
Item
*
get_tmp_table_item
(
THD
*
thd
)
{
return
copy_or_same
(
thd
);
}
...
...
@@ -541,7 +545,7 @@ class Item_result_field :public Item /* Item with result field */
public:
Field
*
result_field
;
/* Save result here */
Item_result_field
()
:
result_field
(
0
)
{}
// Constructor used for Item_sum (see Item comment)
// Constructor used for Item_sum
/Item_cond_and/or
(see Item comment)
Item_result_field
(
THD
*
thd
,
Item_result_field
&
item
)
:
Item
(
thd
,
item
),
result_field
(
item
.
result_field
)
{}
...
...
sql/item_cmpfunc.cc
View file @
51374e56
...
...
@@ -1549,6 +1549,31 @@ longlong Item_func_bit_and::val_int()
return
(
longlong
)
(
arg1
&
arg2
);
}
Item_cond
::
Item_cond
(
THD
*
thd
,
Item_cond
&
item
)
:
Item_bool_func
(
thd
,
item
),
abort_on_null
(
item
.
abort_on_null
),
and_tables_cache
(
item
.
and_tables_cache
)
{
/*
here should be following text:
List_iterator_fast<Item*> li(item.list);
while(Item *it= li++)
list.push_back(it);
but it do not need,
because this constructor used only for AND/OR and
argument list will be copied by copy_andor_arguments call
*/
}
void
Item_cond
::
copy_andor_arguments
(
THD
*
thd
,
Item_cond
*
item
)
{
List_iterator_fast
<
Item
>
li
(
item
->
list
);
while
(
Item
*
it
=
li
++
)
list
.
push_back
(
it
->
copy_andor_structure
(
thd
));
}
bool
Item_cond
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
...
...
sql/item_cmpfunc.h
View file @
51374e56
...
...
@@ -82,6 +82,7 @@ class Item_bool_func :public Item_int_func
Item_bool_func
()
:
Item_int_func
()
{}
Item_bool_func
(
Item
*
a
)
:
Item_int_func
(
a
)
{}
Item_bool_func
(
Item
*
a
,
Item
*
b
)
:
Item_int_func
(
a
,
b
)
{}
Item_bool_func
(
THD
*
thd
,
Item_bool_func
&
item
)
:
Item_int_func
(
thd
,
item
)
{}
void
fix_length_and_dec
()
{
decimals
=
0
;
max_length
=
1
;
}
};
...
...
@@ -115,8 +116,8 @@ class Item_bool_func2 :public Item_int_func
String
tmp_value1
,
tmp_value2
;
public:
Item_bool_func2
(
Item
*
a
,
Item
*
b
)
:
Item_int_func
(
a
,
b
),
cmp
(
tmp_arg
,
tmp_arg
+
1
)
{}
Item_bool_func2
(
Item
*
a
,
Item
*
b
)
:
Item_int_func
(
a
,
b
),
cmp
(
tmp_arg
,
tmp_arg
+
1
)
{}
void
fix_length_and_dec
();
void
set_cmp_func
()
{
...
...
@@ -158,7 +159,7 @@ class Item_func_not :public Item_bool_func
class
Item_func_eq
:
public
Item_bool_rowready_func2
{
public:
Item_func_eq
(
Item
*
a
,
Item
*
b
)
:
Item_bool_rowready_func2
(
a
,
b
)
{}
;
Item_func_eq
(
Item
*
a
,
Item
*
b
)
:
Item_bool_rowready_func2
(
a
,
b
)
{}
longlong
val_int
();
enum
Functype
functype
()
const
{
return
EQ_FUNC
;
}
enum
Functype
rev_functype
()
const
{
return
EQ_FUNC
;
}
...
...
@@ -791,8 +792,13 @@ class Item_cond :public Item_bool_func
public:
/* Item_cond() is only used to create top level items */
Item_cond
()
:
Item_bool_func
(),
abort_on_null
(
1
)
{
const_item_cache
=
0
;
}
Item_cond
(
Item
*
i1
,
Item
*
i2
)
:
Item_bool_func
(),
abort_on_null
(
0
)
{
list
.
push_back
(
i1
);
list
.
push_back
(
i2
);
}
Item_cond
(
Item
*
i1
,
Item
*
i2
)
:
Item_bool_func
(),
abort_on_null
(
0
)
{
list
.
push_back
(
i1
);
list
.
push_back
(
i2
);
}
Item_cond
(
THD
*
thd
,
Item_cond
&
item
);
~
Item_cond
()
{
list
.
delete_elements
();
}
bool
add
(
Item
*
item
)
{
return
list
.
push_back
(
item
);
}
bool
fix_fields
(
THD
*
,
struct
st_table_list
*
,
Item
**
ref
);
...
...
@@ -805,6 +811,7 @@ class Item_cond :public Item_bool_func
void
split_sum_func
(
Item
**
ref_pointer_array
,
List
<
Item
>
&
fields
);
friend
int
setup_conds
(
THD
*
thd
,
TABLE_LIST
*
tables
,
COND
**
conds
);
void
top_level_item
()
{
abort_on_null
=
1
;
}
void
copy_andor_arguments
(
THD
*
thd
,
Item_cond
*
item
);
bool
walk
(
Item_processor
processor
,
byte
*
arg
);
};
...
...
@@ -815,9 +822,17 @@ class Item_cond_and :public Item_cond
public:
Item_cond_and
()
:
Item_cond
()
{}
Item_cond_and
(
Item
*
i1
,
Item
*
i2
)
:
Item_cond
(
i1
,
i2
)
{}
Item_cond_and
(
THD
*
thd
,
Item_cond_and
&
item
)
:
Item_cond
(
thd
,
item
)
{}
enum
Functype
functype
()
const
{
return
COND_AND_FUNC
;
}
longlong
val_int
();
const
char
*
func_name
()
const
{
return
"and"
;
}
Item
*
copy_andor_structure
(
THD
*
thd
)
{
Item_cond_and
*
item
;
if
((
item
=
new
Item_cond_and
(
thd
,
*
this
)))
item
->
copy_andor_arguments
(
thd
,
this
);
return
item
;
}
};
class
Item_cond_or
:
public
Item_cond
...
...
@@ -825,10 +840,18 @@ class Item_cond_or :public Item_cond
public:
Item_cond_or
()
:
Item_cond
()
{}
Item_cond_or
(
Item
*
i1
,
Item
*
i2
)
:
Item_cond
(
i1
,
i2
)
{}
Item_cond_or
(
THD
*
thd
,
Item_cond_or
&
item
)
:
Item_cond
(
thd
,
item
)
{}
enum
Functype
functype
()
const
{
return
COND_OR_FUNC
;
}
longlong
val_int
();
const
char
*
func_name
()
const
{
return
"or"
;
}
table_map
not_null_tables
()
const
{
return
and_tables_cache
;
}
Item
*
copy_andor_structure
(
THD
*
thd
)
{
Item_cond_or
*
item
;
if
((
item
=
new
Item_cond_or
(
thd
,
*
this
)))
item
->
copy_andor_arguments
(
thd
,
this
);
return
item
;
}
};
...
...
sql/item_func.cc
View file @
51374e56
...
...
@@ -134,6 +134,27 @@ Item_func::Item_func(List<Item> &list)
set_arguments
(
list
);
}
Item_func
::
Item_func
(
THD
*
thd
,
Item_func
&
item
)
:
Item_result_field
(
thd
,
item
),
allowed_arg_cols
(
item
.
allowed_arg_cols
),
arg_count
(
item
.
arg_count
),
used_tables_cache
(
item
.
used_tables_cache
),
not_null_tables_cache
(
item
.
not_null_tables_cache
),
const_item_cache
(
item
.
const_item_cache
)
{
if
(
arg_count
)
{
if
(
arg_count
<=
2
)
args
=
tmp_arg
;
else
{
if
(
!
(
args
=
(
Item
**
)
thd
->
alloc
(
sizeof
(
Item
*
)
*
arg_count
)))
return
;
}
memcpy
((
char
*
)
args
,
(
char
*
)
item
.
args
,
sizeof
(
Item
*
)
*
arg_count
);
}
}
/*
Resolve references to table column for a function and it's argument
...
...
sql/item_func.h
View file @
51374e56
...
...
@@ -104,6 +104,8 @@ class Item_func :public Item_result_field
}
}
Item_func
(
List
<
Item
>
&
list
);
// Constructor used for Item_cond_and/or (see Item comment)
Item_func
(
THD
*
thd
,
Item_func
&
item
);
~
Item_func
()
{}
/* Nothing to do; Items are freed automaticly */
bool
fix_fields
(
THD
*
,
struct
st_table_list
*
,
Item
**
ref
);
table_map
used_tables
()
const
;
...
...
@@ -196,6 +198,7 @@ class Item_int_func :public Item_func
Item_int_func
(
Item
*
a
,
Item
*
b
)
:
Item_func
(
a
,
b
)
{
max_length
=
21
;
}
Item_int_func
(
Item
*
a
,
Item
*
b
,
Item
*
c
)
:
Item_func
(
a
,
b
,
c
)
{
max_length
=
21
;
}
Item_int_func
(
List
<
Item
>
&
list
)
:
Item_func
(
list
)
{
max_length
=
21
;
}
Item_int_func
(
THD
*
thd
,
Item_int_func
&
item
)
:
Item_func
(
thd
,
item
)
{}
double
val
()
{
return
(
double
)
val_int
();
}
String
*
val_str
(
String
*
str
);
enum
Item_result
result_type
()
const
{
return
INT_RESULT
;
}
...
...
sql/sql_lex.cc
View file @
51374e56
...
...
@@ -982,6 +982,7 @@ void st_select_lex::init_query()
cond_count
=
with_wild
=
0
;
ref_pointer_array
=
0
;
select_n_having_items
=
0
;
prep_where
=
0
;
}
void
st_select_lex
::
init_select
()
...
...
sql/sql_lex.h
View file @
51374e56
...
...
@@ -339,6 +339,7 @@ class st_select_lex: public st_select_lex_node
public:
char
*
db
,
*
db1
,
*
table1
,
*
db2
,
*
table2
;
/* For outer join using .. */
Item
*
where
,
*
having
;
/* WHERE & HAVING clauses */
Item
*
prep_where
;
/* saved WHERE clause for prepared statement processing */
enum
olap_type
olap
;
SQL_LIST
table_list
,
group_list
;
/* FROM & GROUP BY clauses */
List
<
Item
>
item_list
;
/* list of fields & expressions */
...
...
sql/sql_prepare.cc
View file @
51374e56
...
...
@@ -873,11 +873,21 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length)
if
(
!
(
specialflag
&
SPECIAL_NO_PRIOR
))
my_pthread_setprio
(
pthread_self
(),
WAIT_PRIOR
);
// save WHERE clause pointers to avoid damaging they by optimisation
for
(
SELECT_LEX
*
sl
=
thd
->
lex
.
all_selects_list
;
sl
;
sl
=
sl
->
next_select_in_list
())
{
sl
->
prep_where
=
sl
->
where
;
}
if
(
init_param_items
(
&
stmt
))
goto
err
;
stmt
.
mem_root
=
stmt
.
thd
->
mem_root
;
stmt
.
mem_root
=
stmt
.
thd
->
mem_root
;
tree_insert
(
&
thd
->
prepared_statements
,
(
void
*
)
&
stmt
,
0
,
(
void
*
)
0
);
thd
->
mem_root
=
thd_root
;
// restore main mem_root
DBUG_RETURN
(
0
);
...
...
@@ -919,6 +929,17 @@ void mysql_stmt_execute(THD *thd, char *packet)
LEX
thd_lex
=
thd
->
lex
;
thd
->
lex
=
stmt
->
lex
;
for
(
SELECT_LEX
*
sl
=
stmt
->
lex
.
all_selects_list
;
sl
;
sl
=
sl
->
next_select_in_list
())
{
// copy WHERE clause pointers to avoid damaging they by optimisation
if
(
sl
->
prep_where
)
sl
->
where
=
sl
->
prep_where
->
copy_andor_structure
(
thd
);
// force allocation new JOIN for this mem_root (for safety)
sl
->
join
=
0
;
}
init_stmt_execute
(
stmt
);
if
(
stmt
->
param_count
&&
setup_params_data
(
stmt
))
...
...
tests/client_test.c
View file @
51374e56
...
...
@@ -1839,6 +1839,85 @@ session_id char(9) NOT NULL, \
mysql_stmt_close
(
stmt
);
}
/*
test BUG#1180 (optimized away part of WHERE clause)
*/
static
void
test_bug1180
()
{
MYSQL_STMT
*
stmt
;
int
rc
;
MYSQL_BIND
bind
[
1
];
ulong
length
[
1
];
char
szData
[
11
];
int
nData
=
1
;
myheader
(
"test_select_bug"
);
rc
=
mysql_query
(
mysql
,
"DROP TABLE IF EXISTS test_select"
);
myquery
(
rc
);
rc
=
mysql_query
(
mysql
,
"CREATE TABLE test_select(session_id char(9) NOT NULL)"
);
myquery
(
rc
);
rc
=
mysql_query
(
mysql
,
"INSERT INTO test_select VALUES (
\"
abc
\"
)"
);
myquery
(
rc
);
strmov
(
query
,
"SELECT * FROM test_select WHERE ?=
\"
1111
\"
and session_id =
\"
abc
\"
"
);
stmt
=
mysql_prepare
(
mysql
,
query
,
strlen
(
query
));
mystmt_init
(
stmt
);
verify_param_count
(
stmt
,
1
);
strmov
(
szData
,(
char
*
)
"abc"
);
bind
[
0
].
buffer_type
=
FIELD_TYPE_STRING
;
bind
[
0
].
buffer
=
(
char
*
)
szData
;
bind
[
0
].
buffer_length
=
10
;
bind
[
0
].
length
=
&
length
[
0
];
length
[
0
]
=
3
;
bind
[
0
].
is_null
=
0
;
rc
=
mysql_bind_param
(
stmt
,
bind
);
mystmt
(
stmt
,
rc
);
rc
=
mysql_execute
(
stmt
);
mystmt
(
stmt
,
rc
);
myassert
(
my_process_stmt_result
(
stmt
)
==
0
);
strmov
(
szData
,(
char
*
)
"1111"
);
bind
[
0
].
buffer_type
=
FIELD_TYPE_STRING
;
bind
[
0
].
buffer
=
(
char
*
)
szData
;
bind
[
0
].
buffer_length
=
10
;
bind
[
0
].
length
=
&
length
[
0
];
length
[
0
]
=
4
;
bind
[
0
].
is_null
=
0
;
rc
=
mysql_bind_param
(
stmt
,
bind
);
mystmt
(
stmt
,
rc
);
rc
=
mysql_execute
(
stmt
);
mystmt
(
stmt
,
rc
);
myassert
(
my_process_stmt_result
(
stmt
)
==
1
);
strmov
(
szData
,(
char
*
)
"abc"
);
bind
[
0
].
buffer_type
=
FIELD_TYPE_STRING
;
bind
[
0
].
buffer
=
(
char
*
)
szData
;
bind
[
0
].
buffer_length
=
10
;
bind
[
0
].
length
=
&
length
[
0
];
length
[
0
]
=
3
;
bind
[
0
].
is_null
=
0
;
rc
=
mysql_bind_param
(
stmt
,
bind
);
mystmt
(
stmt
,
rc
);
rc
=
mysql_execute
(
stmt
);
mystmt
(
stmt
,
rc
);
myassert
(
my_process_stmt_result
(
stmt
)
==
0
);
mysql_stmt_close
(
stmt
);
}
/********************************************************
* to test simple select show *
*********************************************************/
...
...
@@ -7898,6 +7977,7 @@ int main(int argc, char **argv)
test_sqlmode
();
/* test for SQL_MODE */
test_ts
();
/* test for timestamp BR#819 */
test_bug1115
();
/* BUG#1115 */
test_bug1180
();
/* BUG#1180 */
end_time
=
time
((
time_t
*
)
0
);
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