maria-developers team mailing list archive
Mailing list archive
Problem with prep_where (LP BUG#675248)
Preparation statement for PS looks like this (example uses prep_where,
but we have the same problem for other parts stored in
conds->fix_fields(...&conds...) /* (1.1) JOIN::prepare()*/
prep_where= *conds; /* (1.2)
*conds= where= prep_where->copy_andor_structure()
Then executing of the prepared statement is like this:
where= prep_where->copy_andor_structure() /* (2.1) reinit_stmt_before_use */
where->fix_fields() /* (2.2) JOIN::prepare() */
The problem is that during (1.1) we could substitute conds with
reference on other item (for example if we change reference on
Item_field on Item_ref* or Item_ref on Item_field). The new item will be
destroyed after preparation (i.e before (2.1)). So during (2.1)
prep_where points on freed memory.
How to solve the problem.
1.1. Make changing Items inherited from Item_ident (Item_field and
Item_ref*) during resolving permanent.
- Looks logical
- reduce work during second preparation
- Play with statement memory usually complex enough.
- have to be sure that there is no any reference on the original Item
1.2 Add new method for Item, which return 'this' pointer but for
Item_idents creating during resolving original Item. (1.2) turns to
- Looks simple
- Item already overloaded with methods like this
1.3 Assign prep_where before (1.1)
- Easy to implement
- Need changing logic and semantic of some calls and
prep_where/prep_having... class variables.
2. Global solutions for the problem of double/triple/... reference on
transformed expression (it is not applicadle for 5.1-5.3 but could de
universal solution in 5.5 of higher):
2.1 Absolutely transparent wrapper to save only one reference on any
expression which could be transformed:
- Could base class for many other wrappers
- It is difficult to implement such absolutely transparent wrapper.
- A lot of places where it should be put, make Item tree bigger
2.2 Turn THD::change_list to hash (for example) and chack presence
of assigning variable in the list, if it found, also register changing
for variable we are assigning value now. For example instead of
prep_where= *conds; use thd->assign_changeable(&prep_where, conds), where:
void THD::assign_changeable(void **newref, void **oldref)
- no additional work for usual statements
- List supports order of assigments easyly, but hash can't
- time for finding pointers in the hash