• Igor Babaev's avatar
    MDEV-21104 Wrong result (extra rows and wrong values) with incremental BNLH · 90780bb5
    Igor Babaev authored
    This bug could affect multi-way join queries with embedded outer joins that
    contained a conjunctive IS NULL predicate over a non-nullable column from
    inner table of an outer join. The predicate could occur in WHERE condition
    or in ON condition. Due to this bug a wrong result set could be returned by
    the query. The bug manifested itself only when join buffers were employed
    for join operations.
    
    The problem appeared because
    - a bug in the function JOIN_CACHE::get_match_flag_by_pos that not always
      returned proper match flags for embedding outer joins stored together
      with table rows put a join buffer.
    - bug in the function JOIN_CACHE::join_matching_records that not always
      correctly determined that a row from the buffer could be skipped due
      to applied 'not_exists' optimization.
    Example:
      SELECT * FROM t1 LEFT JOIN ((t2 LEFT JOIN t3 ON c = d) JOIN t4) ON b = e
        WHERE e IS NULL;
    
    The patch introduces a new function that finds the match flag for a record
    from join buffer specifying the buffer where this flag has to be found.
    The function is called JOIN_CACHE::get_match_flag_by_pos_from_join_buffer().
    Now this function rather than JOIN_CACHE::get_match_flag_by_pos() is used
    in JOIN_CACHE::skip_if_matched() to check whether a record from the join
    buffer must be ignored when extending the record by null complements.
    Also the code of the function JOIN_CACHE::skip_if_not_needed_match() has
    been changed. The function checks whether a record from the join buffer
    still may produce some useful extensions.
    Also some clarifying comments has been added.
    
    Approved by monty@mariadb.com.
    90780bb5
join_cache.test 140 KB