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
5568155e
Commit
5568155e
authored
Apr 01, 2004
by
bell@sanja.is.com.ua
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix for table/field caching mechanism
save moving ON/USING tables conditions to WHERE clause (BUG#2794)
parent
ad7e09de
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
92 additions
and
11 deletions
+92
-11
sql/sql_base.cc
sql/sql_base.cc
+37
-9
sql/sql_class.cc
sql/sql_class.cc
+1
-0
sql/sql_class.h
sql/sql_class.h
+10
-2
sql/sql_insert.cc
sql/sql_insert.cc
+5
-0
tests/client_test.c
tests/client_test.c
+39
-0
No files found.
sql/sql_base.cc
View file @
5568155e
...
@@ -1884,7 +1884,7 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
...
@@ -1884,7 +1884,7 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
char
name_buff
[
NAME_LEN
+
1
];
char
name_buff
[
NAME_LEN
+
1
];
if
(
item
->
cached_table
)
if
(
!
thd
->
no_table_fix_fields_cache
&&
item
->
cached_table
)
{
{
/*
/*
This shortcut is used by prepared statements. We assuming that
This shortcut is used by prepared statements. We assuming that
...
@@ -1895,8 +1895,9 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
...
@@ -1895,8 +1895,9 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
field makes some prepared query ambiguous and so erronous, but we
field makes some prepared query ambiguous and so erronous, but we
accept this trade off.
accept this trade off.
*/
*/
found
=
find_field_in_table
(
thd
,
tables
->
table
,
name
,
length
,
found
=
find_field_in_table
(
thd
,
item
->
cached_table
->
table
,
name
,
length
,
test
(
tables
->
table
->
grant
.
want_privilege
),
test
(
item
->
cached_table
->
table
->
grant
.
want_privilege
),
1
,
&
(
item
->
cached_field_index
));
1
,
&
(
item
->
cached_field_index
));
if
(
found
)
if
(
found
)
...
@@ -2381,6 +2382,8 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name,
...
@@ -2381,6 +2382,8 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name,
int
setup_conds
(
THD
*
thd
,
TABLE_LIST
*
tables
,
COND
**
conds
)
int
setup_conds
(
THD
*
thd
,
TABLE_LIST
*
tables
,
COND
**
conds
)
{
{
table_map
not_null_tables
=
0
;
table_map
not_null_tables
=
0
;
Statement
*
stmt
=
thd
->
current_statement
,
backup
;
DBUG_ENTER
(
"setup_conds"
);
DBUG_ENTER
(
"setup_conds"
);
thd
->
set_query_id
=
1
;
thd
->
set_query_id
=
1
;
...
@@ -2394,18 +2397,21 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
...
@@ -2394,18 +2397,21 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
not_null_tables
=
(
*
conds
)
->
not_null_tables
();
not_null_tables
=
(
*
conds
)
->
not_null_tables
();
}
}
/* Check if we are using outer joins */
/* Check if we are using outer joins */
for
(
TABLE_LIST
*
table
=
tables
;
table
;
table
=
table
->
next
)
for
(
TABLE_LIST
*
table
=
tables
;
table
;
table
=
table
->
next
)
{
{
if
(
table
->
on_expr
)
if
(
table
->
on_expr
)
{
{
if
(
stmt
)
thd
->
set_n_backup_item_arena
(
stmt
,
&
backup
);
/* Make a join an a expression */
/* Make a join an a expression */
thd
->
where
=
"on clause"
;
thd
->
where
=
"on clause"
;
if
(
!
table
->
on_expr
->
fixed
&&
if
(
!
table
->
on_expr
->
fixed
&&
table
->
on_expr
->
fix_fields
(
thd
,
tables
,
&
table
->
on_expr
)
||
table
->
on_expr
->
fix_fields
(
thd
,
tables
,
&
table
->
on_expr
)
||
table
->
on_expr
->
check_cols
(
1
))
table
->
on_expr
->
check_cols
(
1
))
DBUG_RETURN
(
1
)
;
goto
err
;
thd
->
lex
->
current_select
->
cond_count
++
;
thd
->
lex
->
current_select
->
cond_count
++
;
/*
/*
...
@@ -2418,18 +2424,22 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
...
@@ -2418,18 +2424,22 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
{
{
table
->
outer_join
=
0
;
table
->
outer_join
=
0
;
if
(
!
(
*
conds
=
and_conds
(
thd
,
*
conds
,
table
->
on_expr
,
tables
)))
if
(
!
(
*
conds
=
and_conds
(
thd
,
*
conds
,
table
->
on_expr
,
tables
)))
DBUG_RETURN
(
1
)
;
goto
err
;
table
->
on_expr
=
0
;
table
->
on_expr
=
0
;
}
}
if
(
stmt
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
}
}
if
(
table
->
natural_join
)
if
(
table
->
natural_join
)
{
{
if
(
stmt
)
thd
->
set_n_backup_item_arena
(
stmt
,
&
backup
);
/* Make a join of all fields with have the same name */
/* Make a join of all fields with have the same name */
TABLE
*
t1
=
table
->
table
;
TABLE
*
t1
=
table
->
table
;
TABLE
*
t2
=
table
->
natural_join
->
table
;
TABLE
*
t2
=
table
->
natural_join
->
table
;
Item_cond_and
*
cond_and
=
new
Item_cond_and
();
Item_cond_and
*
cond_and
=
new
Item_cond_and
();
if
(
!
cond_and
)
// If not out of memory
if
(
!
cond_and
)
// If not out of memory
DBUG_RETURN
(
1
)
;
goto
err
;
cond_and
->
top_level_item
();
cond_and
->
top_level_item
();
Field
**
t1_field
,
*
t2_field
;
Field
**
t1_field
,
*
t2_field
;
...
@@ -2445,7 +2455,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
...
@@ -2445,7 +2455,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
Item_func_eq
*
tmp
=
new
Item_func_eq
(
new
Item_field
(
*
t1_field
),
Item_func_eq
*
tmp
=
new
Item_func_eq
(
new
Item_field
(
*
t1_field
),
new
Item_field
(
t2_field
));
new
Item_field
(
t2_field
));
if
(
!
tmp
)
if
(
!
tmp
)
DBUG_RETURN
(
1
)
;
goto
err
;
/* Mark field used for table cache */
/* Mark field used for table cache */
(
*
t1_field
)
->
query_id
=
t2_field
->
query_id
=
thd
->
query_id
;
(
*
t1_field
)
->
query_id
=
t2_field
->
query_id
=
thd
->
query_id
;
cond_and
->
list
.
push_back
(
tmp
);
cond_and
->
list
.
push_back
(
tmp
);
...
@@ -2460,18 +2470,36 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
...
@@ -2460,18 +2470,36 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
if
(
!
(
*
conds
=
and_conds
(
thd
,
*
conds
,
cond_and
,
tables
))
||
if
(
!
(
*
conds
=
and_conds
(
thd
,
*
conds
,
cond_and
,
tables
))
||
(
*
conds
&&
!
(
*
conds
)
->
fixed
&&
(
*
conds
&&
!
(
*
conds
)
->
fixed
&&
(
*
conds
)
->
fix_fields
(
thd
,
tables
,
conds
)))
(
*
conds
)
->
fix_fields
(
thd
,
tables
,
conds
)))
DBUG_RETURN
(
1
)
;
goto
err
;
}
}
else
else
{
{
table
->
on_expr
=
and_conds
(
thd
,
table
->
on_expr
,
cond_and
,
tables
);
table
->
on_expr
=
and_conds
(
thd
,
table
->
on_expr
,
cond_and
,
tables
);
if
(
table
->
on_expr
&&
!
table
->
on_expr
->
fixed
&&
if
(
table
->
on_expr
&&
!
table
->
on_expr
->
fixed
&&
table
->
on_expr
->
fix_fields
(
thd
,
tables
,
&
table
->
on_expr
))
table
->
on_expr
->
fix_fields
(
thd
,
tables
,
&
table
->
on_expr
))
DBUG_RETURN
(
1
)
;
goto
err
;
}
}
if
(
stmt
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
}
}
}
}
if
(
stmt
)
{
/*
We are in prepared statement preparation code => we should store
WHERE clause changing for next executions.
We do this ON -> WHERE transformation only once per PS statement.
*/
thd
->
lex
->
current_select
->
where
=
*
conds
;
}
DBUG_RETURN
(
test
(
thd
->
net
.
report_error
));
DBUG_RETURN
(
test
(
thd
->
net
.
report_error
));
err:
if
(
stmt
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
DBUG_RETURN
(
1
);
}
}
...
...
sql/sql_class.cc
View file @
5568155e
...
@@ -84,6 +84,7 @@ extern "C" void free_user_var(user_var_entry *entry)
...
@@ -84,6 +84,7 @@ extern "C" void free_user_var(user_var_entry *entry)
****************************************************************************/
****************************************************************************/
THD
::
THD
()
:
user_time
(
0
),
current_statement
(
0
),
is_fatal_error
(
0
),
THD
::
THD
()
:
user_time
(
0
),
current_statement
(
0
),
is_fatal_error
(
0
),
no_table_fix_fields_cache
(
0
),
last_insert_id_used
(
0
),
last_insert_id_used
(
0
),
insert_id_used
(
0
),
rand_used
(
0
),
in_lock_tables
(
0
),
insert_id_used
(
0
),
rand_used
(
0
),
in_lock_tables
(
0
),
global_read_lock
(
0
),
bootstrap
(
0
)
global_read_lock
(
0
),
bootstrap
(
0
)
...
...
sql/sql_class.h
View file @
5568155e
...
@@ -787,6 +787,12 @@ public:
...
@@ -787,6 +787,12 @@ public:
bool
charset_is_system_charset
,
charset_is_collation_connection
;
bool
charset_is_system_charset
,
charset_is_collation_connection
;
bool
slow_command
;
bool
slow_command
;
/*
Used in prepared statement to prevent using table/field cache in
Item_idend, bacuse it can point on removed table.
*/
bool
no_table_fix_fields_cache
;
/*
/*
If we do a purge of binary logs, log index info of the threads
If we do a purge of binary logs, log index info of the threads
that are currently reading it needs to be adjusted. To do that
that are currently reading it needs to be adjusted. To do that
...
@@ -1044,13 +1050,15 @@ public:
...
@@ -1044,13 +1050,15 @@ public:
class
select_insert
:
public
select_result
{
class
select_insert
:
public
select_result
{
public:
public:
TABLE_LIST
*
table_list
;
TABLE
*
table
;
TABLE
*
table
;
List
<
Item
>
*
fields
;
List
<
Item
>
*
fields
;
ulonglong
last_insert_id
;
ulonglong
last_insert_id
;
COPY_INFO
info
;
COPY_INFO
info
;
select_insert
(
TABLE
*
table_par
,
List
<
Item
>
*
fields_par
,
enum_duplicates
duplic
)
select_insert
(
TABLE
*
table_par
,
List
<
Item
>
*
fields_par
,
:
table
(
table_par
),
fields
(
fields_par
),
last_insert_id
(
0
)
enum_duplicates
duplic
)
:
table
(
table_par
),
fields
(
fields_par
),
last_insert_id
(
0
)
{
{
bzero
((
char
*
)
&
info
,
sizeof
(
info
));
bzero
((
char
*
)
&
info
,
sizeof
(
info
));
info
.
handle_duplicates
=
duplic
;
info
.
handle_duplicates
=
duplic
;
...
...
sql/sql_insert.cc
View file @
5568155e
...
@@ -84,9 +84,14 @@ check_insert_fields(THD *thd,TABLE *table,List<Item> &fields,
...
@@ -84,9 +84,14 @@ check_insert_fields(THD *thd,TABLE *table,List<Item> &fields,
table_list
.
grant
=
table
->
grant
;
table_list
.
grant
=
table
->
grant
;
thd
->
dupp_field
=
0
;
thd
->
dupp_field
=
0
;
thd
->
no_table_fix_fields_cache
=
1
;
if
(
setup_tables
(
&
table_list
)
||
if
(
setup_tables
(
&
table_list
)
||
setup_fields
(
thd
,
0
,
&
table_list
,
fields
,
1
,
0
,
0
))
setup_fields
(
thd
,
0
,
&
table_list
,
fields
,
1
,
0
,
0
))
{
thd
->
no_table_fix_fields_cache
=
0
;
return
-
1
;
return
-
1
;
}
thd
->
no_table_fix_fields_cache
=
0
;
if
(
thd
->
dupp_field
)
if
(
thd
->
dupp_field
)
{
{
my_error
(
ER_FIELD_SPECIFIED_TWICE
,
MYF
(
0
),
thd
->
dupp_field
->
field_name
);
my_error
(
ER_FIELD_SPECIFIED_TWICE
,
MYF
(
0
),
thd
->
dupp_field
->
field_name
);
...
...
tests/client_test.c
View file @
5568155e
...
@@ -8494,6 +8494,43 @@ static void test_bug3117()
...
@@ -8494,6 +8494,43 @@ static void test_bug3117()
myquery
(
rc
);
myquery
(
rc
);
}
}
static
void
test_on
()
{
MYSQL_STMT
*
stmt
;
int
rc
,
i
;
const
char
*
query
=
"SELECT * FROM t2 join t1 on (t1.a=t2.a)"
;
myheader
(
"test_on"
);
rc
=
mysql_query
(
mysql
,
"DROP TABLE IF EXISTS t1,t2"
);
myquery
(
rc
);
rc
=
mysql_query
(
mysql
,
"CREATE TABLE t1 (a int , b int);"
);
myquery
(
rc
);
rc
=
mysql_query
(
mysql
,
"insert into t1 values (1,1), (2, 2), (3,3), (4,4), (5,5);"
);
myquery
(
rc
);
rc
=
mysql_query
(
mysql
,
"create table t2 select * from t1;"
);
myquery
(
rc
);
stmt
=
mysql_prepare
(
mysql
,
query
,
strlen
(
query
));
mystmt_init
(
stmt
);
for
(
i
=
0
;
i
<
3
;
i
++
)
{
rc
=
mysql_execute
(
stmt
);
mystmt
(
stmt
,
rc
);
assert
(
5
==
my_process_stmt_result
(
stmt
));
}
mysql_stmt_close
(
stmt
);
rc
=
mysql_query
(
mysql
,
"DROP TABLE t1,t2"
);
myquery
(
rc
);
}
/*
/*
Read and parse arguments and MySQL options from my.cnf
Read and parse arguments and MySQL options from my.cnf
*/
*/
...
@@ -8753,6 +8790,8 @@ int main(int argc, char **argv)
...
@@ -8753,6 +8790,8 @@ int main(int argc, char **argv)
Item_field -> Item_ref */
Item_field -> Item_ref */
test_union
();
/* test union with prepared statements */
test_union
();
/* test union with prepared statements */
test_bug3117
();
/* BUG#3117: LAST_INSERT_ID() */
test_bug3117
();
/* BUG#3117: LAST_INSERT_ID() */
test_on
();
/* ... join ... on(), BUG#2794 */
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