1. 28 Mar, 2011 1 commit
    • unknown's avatar
      Fix LP BUG#613029 · 7999f40a
      unknown authored
      Analysis:
      There are two code paths through which JOIN::exec may produce
      an all-NULL row for an empty result set. One goes via the
      function return_zero_rows(), when query processing detectes
      early that the where clause is false, the other one is via
      do_select() in the case of join execution.
      
      In the case of do_select(), the problem was that the executioner
      didn't set TABLE::null_row to 1. As result when sending the only
      result row, the evaluation of each field didn't detect that all
      non-aggregated fields are NULL, because Field::is_null returned
      true, after checking that field->table->null_row was false.
      
      Given that the each non-aggregated field was not considered NULL,
      select_result::send_data sent whatever was in the buffer of each
      field. However, since there was no actual data in the field buffer,
      send_data() accessed and sent whatever junk was in the field's
      data buffer.
      
      Solution:
      Similar to the analogous case in return_zero_rows() mark all
      tables that their current row is NULL before sending the
      artificailly created NULL row.
      7999f40a
  2. 24 Mar, 2011 1 commit
    • unknown's avatar
      Fix LP BUG#715738 · ec239491
      unknown authored
      Analysis:
      A query with implicit grouping is one with aggregate functions and
      no GROUP BY clause. MariaDB inherits from MySQL an SQL extenstion
      that allows mixing aggregate functions with non-aggregate fields.
      If a query with such mixed select clause produces an empty result
      set, the meaning of aggregate functions is well defined - either
      NULL (MIN, MAX, etc.), or 0 (count(*)). However the non-aggregated
      fields must also have some value, and the only reasonable value in
      the case of empty result is NULL.
      
      The cause of the many wrong results was that if a field is declared
      as non-nullable (e.g. because it is a PK or NOT NULL), the semantic
      analysis and the optimization phases treat this field as non-nullable,
      and generate all related query plan elements based on this assumption.
      
      Later during execution, these incorrectly configured/generated query
      plan elements result in a wrong result because the selected fields
      are not null due to the not-null assumption during optimization.
      
      Solution:
      Detect before the context analysys phase that a query uses implicit
      grouping with mixed aggregates/non-aggregates, and set all fields
      as nullable. The parser already walks the SELECT clause, and
      already sets Item::with_sum_func for Items that reference aggreagate
      functions. The patch adds a symmetric Item::with_field so that all
      Items that reference an Item_field are marked during their
      construction at parse time in the same way as with aggregate function
      use.
      ec239491
  3. 15 Mar, 2011 1 commit
  4. 13 Mar, 2011 3 commits
    • unknown's avatar
      Merge in the fix for LPBUG#730604, and a corrected fix for LP BUG#719198, · 3f944c43
      unknown authored
      after Monty's review.
      3f944c43
    • unknown's avatar
      Fix LP BUG#719198, LP BUG#730604 · 428b52f5
      unknown authored
      Analysis (BUG#719198):
      The assert failed because the execution code for
      partial matching is designed with the assumption that
      NULLs on the left side are detected as early as possible,
      and a NULL result is returned before any lookups are
      performed at all.
      
      However, in the case of an Item_cache object on the left
      side, null was not detected properly, because detection
      was done via Item::is_null(), which is not implemented at
      all for Item_cache, and resolved to the default Item::is_null()
      which always returns FALSE.
      
      Solution:
      Imlpement Item::is_null().
      
      ******
      
      Analysis (BUG#730604):
      The method Item_field::is_null() determines if an item is NULL from its
      Item_field::field object. However, for Item_fields that represent internal
      temporary tables, Item_field::field represents the field of the original
      table that was the source for the temporary table (in this case t1.f3).
      Both in the committed test case, and in the original bug report the current
      value of t1.f3 is not NULL. This results in an incorrect count of NULLs
      for this column. As a consequence, all related Ordered_key buffers are
      allocated with incorrect sizes. Depending on the exact query and data,
      these incorrect sizes result in various crashes or failed asserts.
      
      Solution:
      The correct value of the current field of the internal temp table is
      in Item_field::result_field. This value is determined by
      Item::is_null_result().
      428b52f5
    • Igor Babaev's avatar
      Merge · edc69e32
      Igor Babaev authored
      edc69e32
  5. 12 Mar, 2011 3 commits
  6. 11 Mar, 2011 8 commits
  7. 10 Mar, 2011 1 commit
  8. 09 Mar, 2011 3 commits
  9. 08 Mar, 2011 5 commits
    • Michael Widenius's avatar
    • unknown's avatar
      Fix LP BUG#719198 · 546a166b
      unknown authored
      Analysis:
      The assert failed because the execution code for
      partial matching is designed with the assumption that
      NULLs on the left side are detected as early as possible,
      and a NULL result is returned before any lookups are
      performed at all.
      
      However, in the case of an Item_cache object on the left
      side, null was not detected properly, because detection
      was done via Item::is_null(), which is not implemented at
      all for Item_cache, and resolved to the default Item::is_null()
      which always returns FALSE.
      
      Solution:
      Use the property Item::null_value instead of is_null(), which
      is properly updated for Item_cache objects as well.
      546a166b
    • Michael Widenius's avatar
      Automatic merge with 5.1 · ce675406
      Michael Widenius authored
      ce675406
    • Michael Widenius's avatar
      Don't check if LAST_IO_Error has changed as this is not a user variable and it... · 251a5fa9
      Michael Widenius authored
      Don't check if LAST_IO_Error has changed as this is not a user variable and it may change depending on timing issues between master and slave
      251a5fa9
    • Igor Babaev's avatar
      Fixed LP bug #729039. · 3d3d5f1d
      Igor Babaev authored
      If join condition is of the form <t2.key>=<t1.no_key> then the server
      performs no index look-ups when looking for matching rows of t2 for
      the rows from t1 with t1.no_key=NULL. It happens because the function
      add_not_null_conds() injects an additional condition of the form 
      IS NOT NULL(<t1.no_key>) into the WHERE condition.
      However if the join condition was of the form <t.key>=<outer_ref> no
      additional null rejecting predicate was generated. This could lead
      to extra records in the result set if the value of <outer_ref> happened
      to be NULL.
      The new code injects null rejecting predicates of the form 
      IS NOT NULL(<outer_ref>) and evaluates them before the first row
      the subquery is constructed.
      3d3d5f1d
  10. 07 Mar, 2011 1 commit
  11. 04 Mar, 2011 7 commits
  12. 03 Mar, 2011 4 commits
    • Sergey Petrunya's avatar
      Merge fix for BUG#693747 · cdd214de
      Sergey Petrunya authored
      cdd214de
    • Sergey Petrunya's avatar
      Merge BUG#707925. · 0e090eaa
      Sergey Petrunya authored
      0e090eaa
    • Sergey Petrunya's avatar
      BUG#707925: Wrong result with join_cache_level=6 optimizer_use_mrr = force (incremental, BKA join) · 8ef094fe
      Sergey Petrunya authored
      - The problem was that Mrr_ordered_index_reader's interrupt_read() and resume_read() would 
        save and restore 1) index tuple  2) the rowid (as bytes returned by handler->position()).  Clustered 
        primary key columns were not saved/restored. 
        They are not explicitly present in the index tuple (i.e. table->key_info[secondary_key].key_parts 
        doesn't list them), but they are actually there, in particular 
        table->field[clustered_primary_key_member].part_of_key(secondary_key) == 1. Index condition pushdown
        code [correctly] uses the latter as inidication that pushed index condition can refer to clustered PK
        members. 
      
        The fix was to make interrupt_read()/resume_read() to save/restore clustered primary key members as well,
        so that we get correct values for them when evaluating pushed index condition.
      [3rd attempt: remove the debugging aids, fix comments in testcase]
      8ef094fe
    • unknown's avatar
      Fix LP BUG#718763 · adce16f9
      unknown authored
      Analysis:
      The reason for the crash was that the inner subquery was executed
      via a scan on a final temporary table applied after all other
      operations. This final operation is implemented by changing the
      contents of the JOIN object of the subquery to represent a table
      scan over the temp table. At the same time query optimization of
      the outer subquery required evaluation of the inner subquery, which
      happened before the actual EXPLAIN. The evaluation left the JOIN
      object of the inner subquery in the changed state, where it represented
      a table scan over a temp table, and EXPLAIN crashed because the temp
      table is not associated with any table reference (TABLE_LIST object).
      The reason the JOIN was not restored was because its saving/restoration
      was controlled by the join->select_lex->uncacheable flag, which was
      not set in the case of materialization.
      
      Solution:
      In the methods Item_in_subselect::[single | row]_value_transformer() set:
          select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
      In addition, for symmetry, change:
          master_unit->uncacheable|= UNCACHEABLE_EXPLAIN;
      instead of UNCACHEABLE_DEPENDENT because if a subquery was not
      dependent initially, the changed methods do not change this
      fact. The subquery may later become correlated if it is transformed
      to an EXISTS query, but it may stay uncorrelated if executed via
      materialization.
      adce16f9
  13. 02 Mar, 2011 1 commit
    • Sergey Petrunya's avatar
      BUG#693747: Assertion multi_range_read.cc:908: int DsMrr_impl::dsmrr_init · 9faf5452
      Sergey Petrunya authored
      - Make DsMrr_impl::dsmrr_init() handle the case of 
         1. 1st MRR scan using DS-MRR strategy (i.e. doing key sorting and rowid sorting)
         2. 2nd MRR scan getting a buffer that's too small to fit one key element 
            and one rowid element, and so falling back to default MRR implementation
        In this case, dsmrr_init() is invoked with {primary_handler, secondary_handler}
        initialized for DS-MRR scan and have to reset them to be initialized for the
        default MRR scan.
      (attempt 2, with simplified testcase)
      9faf5452
  14. 01 Mar, 2011 1 commit