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
6171119b
Commit
6171119b
authored
Apr 17, 2023
by
Oleksandr Byelkin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MDEV-30889: 3 - Item_in_optimizer leak
Keep Item_in_optimizer cache always (but only once) in statement memory.
parent
45d4f6b9
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
33 additions
and
24 deletions
+33
-24
sql/item.cc
sql/item.cc
+6
-4
sql/item.h
sql/item.h
+8
-3
sql/item_cmpfunc.cc
sql/item_cmpfunc.cc
+15
-11
sql/item_cmpfunc.h
sql/item_cmpfunc.h
+2
-4
sql/item_subselect.cc
sql/item_subselect.cc
+2
-2
No files found.
sql/item.cc
View file @
6171119b
...
...
@@ -10430,7 +10430,8 @@ int Item_cache_str::save_in_field(Field *field, bool no_conversions)
bool
Item_cache_row
::
allocate
(
THD
*
thd
,
uint
num
)
{
item_count
=
num
;
return
(
!
(
values
=
return
(
!
values
&&
!
(
values
=
(
Item_cache
**
)
thd
->
calloc
(
sizeof
(
Item_cache
*
)
*
item_count
)));
}
...
...
@@ -10467,10 +10468,11 @@ bool Item_cache_row::setup(THD *thd, Item *item)
for
(
uint
i
=
0
;
i
<
item_count
;
i
++
)
{
Item
*
el
=
item
->
element_index
(
i
);
Item_cache
*
tmp
;
if
(
!
(
tmp
=
values
[
i
]
=
el
->
get_cache
(
thd
)))
if
(
(
!
values
[
i
])
&&
!
(
values
[
i
]
=
el
->
get_cache
(
thd
)))
return
1
;
tmp
->
setup
(
thd
,
el
);
values
[
i
]
->
setup
(
thd
,
el
);
}
return
0
;
}
...
...
sql/item.h
View file @
6171119b
...
...
@@ -6901,6 +6901,9 @@ class Item_cache: public Item_fixed_hybrid,
}
virtual
void
keep_array
()
{}
#ifndef DBUG_OFF
bool
is_array_kept
()
{
return
TRUE
;
}
#endif
virtual
void
print
(
String
*
str
,
enum_query_type
query_type
);
bool
eq_def
(
const
Field
*
field
)
{
...
...
@@ -7388,13 +7391,15 @@ class Item_cache_row: public Item_cache
bool
null_inside
();
void
bring_value
();
void
keep_array
()
{
save_array
=
1
;
}
#ifndef DBUG_OFF
bool
is_array_kept
()
{
return
save_array
;
}
#endif
void
cleanup
()
{
DBUG_ENTER
(
"Item_cache_row::cleanup"
);
Item_cache
::
cleanup
();
if
(
save_array
)
bzero
(
values
,
item_count
*
sizeof
(
Item
**
));
else
if
(
!
save_array
)
values
=
0
;
DBUG_VOID_RETURN
;
}
...
...
sql/item_cmpfunc.cc
View file @
6171119b
...
...
@@ -1298,9 +1298,22 @@ bool Item_in_optimizer::fix_left(THD *thd)
ref0
=
&
(((
Item_in_subselect
*
)
args
[
1
])
->
left_expr
);
args
[
0
]
=
((
Item_in_subselect
*
)
args
[
1
])
->
left_expr
;
}
if
((
*
ref0
)
->
fix_fields_if_needed
(
thd
,
ref0
)
||
(
!
cache
&&
!
(
cache
=
(
*
ref0
)
->
get_cache
(
thd
))))
if
((
*
ref0
)
->
fix_fields_if_needed
(
thd
,
ref0
))
DBUG_RETURN
(
1
);
if
(
!
cache
)
{
Query_arena
*
arena
,
backup
;
arena
=
thd
->
activate_stmt_arena_if_needed
(
&
backup
);
bool
rc
=
!
(
cache
=
(
*
ref0
)
->
get_cache
(
thd
));
if
(
arena
)
thd
->
restore_active_arena
(
arena
,
&
backup
);
if
(
rc
)
DBUG_RETURN
(
1
);
cache
->
keep_array
();
}
/*
During fix_field() expression could be substituted.
So we copy changes before use
...
...
@@ -1663,19 +1676,10 @@ longlong Item_in_optimizer::val_int()
}
void
Item_in_optimizer
::
keep_top_level_cache
()
{
cache
->
keep_array
();
save_cache
=
1
;
}
void
Item_in_optimizer
::
cleanup
()
{
DBUG_ENTER
(
"Item_in_optimizer::cleanup"
);
Item_bool_func
::
cleanup
();
if
(
!
save_cache
)
cache
=
0
;
expr_cache
=
0
;
DBUG_VOID_RETURN
;
}
...
...
sql/item_cmpfunc.h
View file @
6171119b
...
...
@@ -353,8 +353,7 @@ class Item_in_optimizer: public Item_bool_func
protected:
Item_cache
*
cache
;
Item
*
expr_cache
;
bool
save_cache
;
/*
/*
Stores the value of "NULL IN (SELECT ...)" for uncorrelated subqueries:
UNKNOWN - "NULL in (SELECT ...)" has not yet been evaluated
FALSE - result is FALSE
...
...
@@ -364,7 +363,7 @@ class Item_in_optimizer: public Item_bool_func
public:
Item_in_optimizer
(
THD
*
thd
,
Item
*
a
,
Item
*
b
)
:
Item_bool_func
(
thd
,
a
,
b
),
cache
(
0
),
expr_cache
(
0
),
save_cache
(
0
),
result_for_null_param
(
UNKNOWN
)
result_for_null_param
(
UNKNOWN
)
{
m_with_subquery
=
true
;
}
bool
fix_fields
(
THD
*
,
Item
**
);
bool
fix_left
(
THD
*
thd
);
...
...
@@ -375,7 +374,6 @@ class Item_in_optimizer: public Item_bool_func
enum
Functype
functype
()
const
{
return
IN_OPTIMIZER_FUNC
;
}
const
char
*
func_name
()
const
{
return
"<in_optimizer>"
;
}
Item_cache
**
get_cache
()
{
return
&
cache
;
}
void
keep_top_level_cache
();
Item
*
transform
(
THD
*
thd
,
Item_transformer
transformer
,
uchar
*
arg
);
virtual
Item
*
expr_cache_insert_transformer
(
THD
*
thd
,
uchar
*
unused
);
bool
is_expensive_processor
(
void
*
arg
);
...
...
sql/item_subselect.cc
View file @
6171119b
...
...
@@ -1994,7 +1994,7 @@ Item_in_subselect::single_value_transformer(JOIN *join)
thd
->
lex
->
current_select
=
current
;
/* We will refer to upper level cache array => we have to save it for SP */
optimizer
->
keep_top_level_cache
(
);
DBUG_ASSERT
(
optimizer
->
get_cache
()[
0
]
->
is_array_kept
()
);
/*
As far as Item_in_optimizer does not substitute itself on fix_fields
...
...
@@ -2391,7 +2391,7 @@ Item_in_subselect::row_value_transformer(JOIN *join)
}
// we will refer to upper level cache array => we have to save it in PS
optimizer
->
keep_top_level_cache
(
);
DBUG_ASSERT
(
optimizer
->
get_cache
()[
0
]
->
is_array_kept
()
);
thd
->
lex
->
current_select
=
current
;
/*
...
...
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