Details
-
Task
-
Status: Open (View Workflow)
-
Major
-
Resolution: Unresolved
-
None
-
None
-
None
Description
During fixing MDEV-36686 a more general issue was observed: `do_build_clone()` functions of class `Item` descendants are supposed to produce deep copies of instances but often produce shallow copies. For example, `Item_field`:
Item* Item_field::do_build_clone(THD *thd) const override { return get_copy(thd); }
|
`get_copy()` performs shallow copying of an object.
Also, `do_build_clone()` implementation is sometimes omitted at all and is inherited from the parent class. In most cases it is not a problem: clones and shallow copies are equivalent. However, for some `Item` descendants it is not true, like for `Item_default_value`: it has
Item *arg
|
member that has to be deep copied, not shallow copied.
It's easy to overlook the presence of such members in a class, inheritance may also make such things less visible. So, the idea is to add a check whether a deep copy is indeed deep and not shallow.
So far the easiest way seems to be a debug runtime walk()-based sub-item collection, something like:
bool Item::collect_subitems_processor(void *arg) |
{
|
HashSet<Item*> *items = (HashSet<Item*>*) arg;
|
items->insert(this); |
return false; |
}
|
|
// In build_clone():
|
HashSet<Item*> original_items, clone_items;
|
this->walk(&Item::collect_subitems_processor, false, &original_items); |
clone->walk(&Item::collect_subitems_processor, false, &clone_items); |
// Check intersection (excluding clone itself) |
Attachments
Issue Links
- relates to
-
MDEV-36686 Server crashes in Item_field::used_tables upon queries from a view
-
- Closed
-