Commit graph

173 commits

Author SHA1 Message Date
Sergei Golubchik
4933d21e5d merge with mysql-5.5.21 2012-03-09 08:06:59 +01:00
Sergei Golubchik
edab37cd68 5.3 merge 2012-02-21 20:51:56 +01:00
Michael Widenius
15c5a2686f Merge with MariaDB 5.2 2012-02-21 01:58:50 +02:00
Igor Babaev
c563ea0717 Fixed LP bug #933117.
The bug was fixed with the code back-ported from the patch for LP bug 800184
pushed into mariadb-5.3.
2012-02-16 16:06:49 -08:00
Guilhem Bichot
95646db77b merge from 5.1 2012-01-26 10:38:28 +01:00
Guilhem Bichot
9e0b69c0b7 Fixes for:
BUG#13519696 - 62940: SELECT RESULTS VARY WITH VERSION AND
WITH/WITHOUT INDEX RANGE SCAN
BUG#13453382 - REGRESSION SINCE 5.1.39, RANGE OPTIMIZER WRONG
RESULTS WITH DECIMAL CONVERSION
BUG#13463488 - 63437: CHAR & BETWEEN WITH INDEX RETURNS WRONG
RESULT AFTER MYSQL 5.1.
Those are all cases where the range optimizer got it wrong
with > and >=.

mysql-test/r/range.result:
  Without the code fix for DECIMAL, "select count(val) from t2 where val > 0.1155"
  (which uses a range scan) returned 127 instead of 128);
  Moreover, both
  select * from t1 force  index (primary) where a=1 and c>= 2.9;
  and
  select * from t1 force  index (primary) where a=1 and c> 2.9;
  would miss "1	1	3".
  Without the code fix for strings, both
  SELECT * FROM t1 WHERE F1 >= 'A    ';
  and
  SELECT * FROM t1 WHERE F1 BETWEEN 'A    ' AND 'AAAAA';
  would miss "A	A	A".
sql/item.cc:
  Preamble to the explanations below: opt_range.cc:get_mm_leaf() does
  this (this is not changed by the patch): changes
  column > value
  to
  column OP V
  where:
  * V is what is in "column" after we stored "value" in it
  (such store operation may have done rounding...)
  * OP is > or >=, depending on what's correct.
  For example, if c is an INT column,
  c > 2.9 is changed to
  c OP 3
  where OP is >= ('>' would not be correct).
  The bugs below are cases where we chose OP wrongly.
  Note that such transformations are visible in the optimizer trace.
  
  1) Fix for STRING. In the scenario with CHAR(5) in range.test, this happens,
  in get_mm_tree(), for the condition F1>='A    ':
  * value->save_in_field_no_warnings(field, 1) wants to store the right argument
  (named 'item') into the CHAR(5) field; this stores 'A    ' (the item's value)
  padded with spaces (which changes nothing: still 'A    ')
  * we come to
    case Item_func::GE_FUNC:
      /* Don't use open ranges for partial key_segments */
      if ((!(key_part->flag & HA_PART_KEY_SEG)) &&
          (stored_field_cmp_to_item(param->thd, field, value) < 0))
        tree->min_flag= NEAR_MIN;
      tree->max_flag=NO_MAX_RANGE;
  What this wants to do is: if the field's value is strictly smaller
  than the item's, then ">=" can be changed to ">" (this is an optimization,
  it can help pruning one useless partition).
  * stored_field_cmp_to_item() is called; it compares the field's
  and item's values: the item's value (Item_string::val_str()) is
  'A    ') and the field's value (Field_string::val_str()) is
  'A' (yes val_str() removes end spaces unless sql_mode='PAD_CHAR_TO_FULL_LENGTH');
  and the comparison is done with stringcmp() which considers
  end spaces as relevant; as end spaces differ, function returns a
  negative number, and ">='A    '" becomes ">'A'" (i.e. the NEAR_MIN
  flag is turned on).
  During execution the index range scan code will search for "A", find
  a match, but exclude it (because of ">"), wrongly.
  The badness is the string comparison done by stored_field_cmp_to_item():
  we use the reply of this function to determine where the index search
  should start, so it should do comparison like index search does
  comparisons; index search comparisons are ha_key_cmp() which uses
  a collation-aware comparison (in our case, my_strnncollsp_simple(),
  which ignores end spaces); so stored_field_cmp_to_item()
  needs to do the same. When this is fixed, condition becomes
  ">='A    '".
  
  2) Fix for DECIMAL: just like in other comparisons in stored_field_cmp_to_item(),
  we must first pass the field and then the item; otherwise expectations
  on what <0 and >0 mean (inferiority, superiority) get violated.
  In the test in range.test about c>2.9: c is an INT column, so 2.9
  gets stored as 3, then stored_field_cmp_to_item() compares 3
  and 2.9; because of the wrong order of arguments passed
  to my_decimal_cmp(), range optimizer
  thinks that 3 is < 2.9 and thus changes "c> 2.9" to "c> 3".
  After fixing the order, it changes to the correct "c>= 3".
  In the test in range.inc for val > 0.1155, it was changed to
  val > 0.116, now it is changed to val >= 0.116.
2012-01-26 10:25:23 +01:00
Sergei Golubchik
effed09bd7 5.3->5.5 merge 2011-11-27 17:46:20 +01:00
Sergei Golubchik
d2755a2c9c 5.3->5.5 merge 2011-11-22 18:04:38 +01:00
Igor Babaev
af3d1da31d Made the optimizer switch for index condition pushdown set to 'on' by default. 2011-11-21 05:16:16 -08:00
Sergei Golubchik
76f0b94bb0 merge with 5.3
sql/sql_insert.cc:
  CREATE ... IF NOT EXISTS may do nothing, but
  it is still not a failure. don't forget to my_ok it.
  ******
  CREATE ... IF NOT EXISTS may do nothing, but
  it is still not a failure. don't forget to my_ok it.
sql/sql_table.cc:
  small cleanup
  ******
  small cleanup
2011-10-19 21:45:18 +02:00
Igor Babaev
715dc5f99d Fixed a cost estimation bug introduced into in the function best_access_path
of the 5.3 code line after a merge with 5.2 on 2010-10-28
in order not to allow the cost to access a joined table to be equal
to 0 ever.

Expanded data sets for many test cases to get the same execution plans
as before.
2011-09-30 18:55:02 -07:00
Sergey Petrunya
0e19f3e36f Backport of:
revno: 2876.47.174
revision-id: jorgen.loland@oracle.com-20110519120355-qn7eprkad9jqwu5j
parent: mayank.prasad@oracle.com-20110518143645-bdxv4udzrmqsjmhq
committer: Jorgen Loland <jorgen.loland@oracle.com>
branch nick: mysql-trunk-11765831
timestamp: Thu 2011-05-19 14:03:55 +0200
message:
  BUG#11765831: 'RANGE ACCESS' MAY INCORRECTLY FILTER 
                        AWAY QUALIFYING ROWS
        
  The problem was that the ranges created when OR'ing two 
  conditions could be incorrect. Without the bugfix, 
  "I <> 6 OR (I <> 8 AND J = 5)" would create these ranges:
  
  "NULL < I < 6",
  "6 <= I <= 6 AND 5 <= J <= 5",
  "6 < I < 8",
  "8 <= I <= 8 AND 5 <= J <= 5",
  "8 < I"
  
  While the correct ranges is
  "NULL < I < 6",
  "6 <= I <= 6 AND 5 <= J <= 5",
  "6 < I"
  
  The problem occurs when key_or() ORs
  (1) "NULL < I < 6, 6 <= I <= 6 AND 5 <= J <= 5, 6 < I" with 
  (2) "8 < I AND 5 <= J <= 5"
  
  The reason for the bug is that in key_or(), SEL_ARG *tmp is 
  used to point to the range in (1) above that is merged with 
  (2) while key1 points to the root of the red-black tree of 
  (1). When merging (1) and (2), tmp refers to the "6 < I" 
  part whereas the root is the "6 <= ... AND 5 <= J <= 5" part. 
  
  key_or() decides that the tmp range needs to be split into
  "6 < I < 8, 8 <= I <= 8, 8 < I", in which next_key_part of the 
  second range should be that of tmp. However, next_key_part is
  set to key1->next_key_part ("5 <= J <= 5") instead of 
  tmp->next_key_part (empty). Fixing this gives the correct but
  not optimal ranges:
  "NULL < I < 6",
  "6 <= I <= 6 AND 5 <= J <= 5",
  "6 < I < 8",
  "8 <= I <= 8",
  "8 < I"
  
  A second problem can be seen above: key_or() may create 
  adjacent ranges that could be replaced with a single range. 
  Fixes for this is also included in the patch so that the range
  above becomes correct AND optimal:
  "NULL < I < 6",
  "6 <= I <= 6 AND 5 <= J <= 5",
  "6 < I"
  
  Merging adjacent ranges like this gives a slightly lower cost 
  estimate for the range access.
2011-08-05 22:01:49 +04:00
Sergey Petrunya
1492de8563 Set the default to be mrr=off,mrr_sort_keys=off:
- Set the default
- Adjust the testcases so that 'new' tests are run with optimizations turned on.
- Pull out relevant tests from "irrelevant" tests and run them with optimizations on.
- Run range.test and innodb.test with both mrr=on and mrr=off
2011-07-08 18:46:47 +04:00
Sergei Golubchik
b4a0b2c2f8 post-merge fixes.
most tests pass.
5.3 merge is next
2011-07-02 22:12:12 +02:00
Sergei Golubchik
9809f05199 5.5-merge 2011-07-02 22:08:51 +02:00
Sergei Golubchik
9b98cae4cc merge with 5.1-micro 2011-06-07 18:13:02 +02:00
Sergei Golubchik
4d128777dd revert a suggested "optimization" that introduced a bug
compilation error in mysys/my_getsystime.c fixed
some redundant code removed
sec_to_time, time_to_sec, from_unixtime, unix_timestamp, @@timestamp now
  use decimal, not double for numbers with a fractional part.
purge_master_logs_before_date() fixed
many bugs in corner cases fixed

mysys/my_getsystime.c:
  compilation failure fixed
sql/sql_parse.cc:
  don't cut corners. it backfires.
2011-06-06 20:28:15 +02:00
Michael Widenius
f197991f41 Merge with 5.1-microseconds
A lot of small fixes and new test cases.

client/mysqlbinlog.cc:
  Cast removed
client/mysqltest.cc:
  Added missing DBUG_RETURN
include/my_pthread.h:
  set_timespec_time_nsec() now only takes one argument
mysql-test/t/date_formats.test:
  Remove --disable_ps_protocl as now also ps supports microseconds
mysys/my_uuid.c:
  Changed to use my_interval_timer() instead of my_getsystime()
mysys/waiting_threads.c:
  Changed to use my_hrtime()
sql/field.h:
  Added bool special_const_compare() for fields that may convert values before compare (like year)
sql/field_conv.cc:
  Added test to get optimal copying of identical temporal values.
sql/item.cc:
  Return that item_int is equal if it's positive, even if unsigned flag is different.
  Fixed Item_cache_str::save_in_field() to have identical null check as other similar functions
  Added proper NULL check to Item_cache_int::save_in_field()
sql/item_cmpfunc.cc:
  Don't call convert_constant_item() if there is nothing that is worth converting.
  Simplified test when years should be converted
sql/item_sum.cc:
  Mark cache values in Item_sum_hybrid as not constants to ensure they are not replaced by other cache values in compare_datetime()
sql/item_timefunc.cc:
  Changed sec_to_time() to take a my_decimal argument to ensure we don't loose any sub seconds.
  Added Item_temporal_func::get_time() (This simplifies some things)
sql/mysql_priv.h:
  Added Lazy_string_decimal()
sql/mysqld.cc:
  Added my_decimal constants max_seconds_for_time_type, time_second_part_factor
sql/table.cc:
  Changed expr_arena to be of type CONVENTIONAL_EXECUTION to ensure that we don't loose any items that are created by fix_fields()
sql/tztime.cc:
  TIME_to_gmt_sec() now sets *in_dst_time_gap in case of errors
  This is needed to be able to detect if timestamp is 0
storage/maria/lockman.c:
  Changed from my_getsystime() to set_timespec_time_nsec()
storage/maria/ma_loghandler.c:
  Changed from my_getsystime() to my_hrtime()
storage/maria/ma_recovery.c:
  Changed from my_getsystime() to mmicrosecond_interval_timer()
storage/maria/unittest/trnman-t.c:
  Changed from my_getsystime() to mmicrosecond_interval_timer()
storage/xtradb/handler/ha_innodb.cc:
  Added support for new time,datetime and timestamp
unittest/mysys/thr_template.c:
  my_getsystime() -> my_interval_timer()
unittest/mysys/waiting_threads-t.c:
  my_getsystime() -> my_interval_timer()
2011-05-28 05:11:32 +03:00
Michael Widenius
f34be18938 Merge with MariaDB 5.2 2011-05-10 18:17:43 +03:00
Sergei Golubchik
a7ff7918a0 lp:750117 Bogus warning with aggregate and datetime column
implement Item_cache_int::getdate() and Item_cache_int::save_in_field()
that handle the case of the cached packed datetime value.
2011-04-18 21:01:49 +02:00
Sergey Petrunya
997445bc8e Make EXPLAIN better at displaying MRR/BKA:
- "Using MRR" is no longer shown with range access.
- Instead, both range and BKA accesses will show one of the following:
  = "Rowid-ordered scan"
  = "Key-ordered scan"
  = "Key-ordered Rowid-ordered scan"
depending on whether DS-MRR implementation will do scan keys in order, rowids in order,
or both.
- The patch also introduces a way for other storage engines/MRR implementations to
  pass information to EXPLAIN output about the properties of employed MRR scans.
2011-04-02 14:04:45 +04:00
Sergei Golubchik
a8a757c6bb wl#173 - temporal types with sub-second resolution
and collateral changes.

* introduce my_hrtime_t, my_timediff_t, and conversion macros
* inroduce TIME_RESULT, but it can only be returned from Item::cmp_type(),
  never from Item::result_type()
* pack_time/unpack_time function for "packed" representation of
  MYSQL_TIME in a longlong that can be compared
* ADDTIME()/SUBTIME()/+- INTERVAL now work with TIME values
* numbers aren't quoted in EXPLAIN EXTENDED
* new column I_S.COLUMNS.DATETIME_PRECISION
* date/time values are compares to anything as date/time, not as strings or numbers.
* old timestamp(X) is no longer supported
* MYSQL_TIME to string conversion functions take precision as an argument
* unified the warnings from Field_timestamp/datetime/time/date/newdate store methods
* Field_timestamp_hires, Field_datetime_hires, Field_time_hires
* Field_temporal
* Lazy_string class to pass a value (string, number, time) polymorphically down the stack
* make_truncated_value_warning and Field::set_datetime_warning use Lazy_string as an argument, removed char*/int/double variants
* removed Field::can_be_compared_as_longlong(). Use Field::cmp_type() == INT_RESULT instead
* introduced Item::cmp_result() instead of Item::is_datetime() and Item::result_as_longlong()
* in many cases date/time types are treated like other types, not as special cases
* greatly simplified Arg_comparator (regarding date/time/year code)
* SEC_TO_TIME is real function, not integer.
* microsecond precision in NOW, CURTIME, etc
* Item_temporal. All items derived from it only provide get_date, but no val* methods
* replication of NOW(6)
* Protocol::store(time) now takes the precision as an argument
* @@TIMESTAMP is a double

client/mysqlbinlog.cc:
  remove unneded casts
include/my_sys.h:
  introduce my_hrtime_t, my_timediff_t, and conversion macros
include/my_time.h:
  pack_time/unpack_time, etc.
  convenience functions to work with MYSQL_TIME::second_part
libmysql/libmysql.c:
  str_to_time() is gone. str_to_datetime() does it now.
  my_TIME_to_str() takes the precision as an argument
mysql-test/include/ps_conv.inc:
  time is not equal to datetime anymore
mysql-test/r/distinct.result:
  a test for an old MySQL bug
mysql-test/r/explain.result:
  numbers aren't quoted in EXPLAIN EXTENDED
mysql-test/r/func_default.result:
  numbers aren't quoted in EXPLAIN EXTENDED
mysql-test/r/func_sapdb.result:
  when decimals=NOT_FIXED_DEC it means "not fixed" indeed
mysql-test/r/func_test.result:
  numbers aren't quoted in EXPLAIN EXTENDED
mysql-test/r/func_time.result:
  ADDTIME()/SUBTIME()/+- INTERVAL now work with TIME values
mysql-test/r/having.result:
  numbers aren't quoted in EXPLAIN EXTENDED
mysql-test/r/information_schema.result:
  new column I_S.COLUMNS.DATETIME_PRECISION
mysql-test/r/join_outer.result:
  numbers aren't quoted in EXPLAIN EXTENDED
mysql-test/r/metadata.result:
  TIMESTAMP no longer has zerofill flag
mysql-test/r/range.result:
  invalid datetime is not compared with as a string
mysql-test/r/select.result:
  NO_ZERO_IN_DATE, etc only affect storage - according to the manual
  numbers aren't quoted in EXPLAIN EXTENDED
mysql-test/r/subselect.result:
  numbers aren't quoted in EXPLAIN EXTENDED
mysql-test/r/sysdate_is_now.result:
  when decimals=NOT_FIXED_DEC it means "not fixed" indeed
mysql-test/r/type_blob.result:
  TIMESTAMP(N) is not deprecated
mysql-test/r/type_timestamp.result:
  old TIMESTAMP(X) semantics is not supported anymore
mysql-test/r/union.result:
  numbers aren't quoted in EXPLAIN EXTENDED
mysql-test/r/varbinary.result:
  numbers aren't quoted in EXPLAIN EXTENDED
mysql-test/t/distinct.test:
  test for an old MySQL bug
mysql-test/t/func_time.test:
  +- INTERVAL now works with TIME values
mysql-test/t/select.test:
  typo
mysql-test/t/subselect.test:
  only one error per statement, please
mysql-test/t/system_mysql_db_fix40123.test:
  old timestamp(X) is no longer supported
mysql-test/t/system_mysql_db_fix50030.test:
  old timestamp(X) is no longer supported
mysql-test/t/system_mysql_db_fix50117.test:
  old timestamp(X) is no longer supported
mysql-test/t/type_blob.test:
  old timestamp(X) is no longer supported
mysql-test/t/type_timestamp.test:
  old timestamp(X) is no longer supported
mysys/my_getsystime.c:
  functions to get the time with microsecond precision
mysys/my_init.c:
  move the my_getsystime.c initialization code to my_getsystime.c
mysys/my_static.c:
  no need to make these variables extern
mysys/my_static.h:
  no need to make these variables extern
scripts/mysql_system_tables.sql:
  old timestamp(X) is no longer supported
scripts/mysql_system_tables_fix.sql:
  old timestamp(X) is no longer supported
scripts/mysqlhotcopy.sh:
  old timestamp(X) is no longer supported
sql-common/my_time.c:
  * call str_to_time from str_to_datetime, as appropriate
  * date/time to string conversions take precision as an argument
  * number_to_time()
  * TIME_to_double()
  * pack_time() and unpack_time()
sql/event_data_objects.cc:
  cast is not needed
  my_datetime_to_str() takes precision as an argument
sql/event_db_repository.cc:
  avoid dangerous downcast (because the pointer is
  not always Field_timestamp, see events_1.test)
sql/event_queue.cc:
  avoid silly double-work for cond_wait
  (having an endpoint of wait, subtract the current time to get the timeout,
  and use set_timespec() macro to fill in struct timespec, by adding the current
  time to the timeout)
sql/field.cc:
  * remove virtual Field::get_time(), everyone should use only Field::get_date()
  * remove lots of #ifdef WORDS_BIGENDIAN
  * unified the warnings from Field_timestamp/datetime/time/date/newdate store methods
  * Field_timestamp_hires, Field_datetime_hires, Field_time_hires
  * Field_temporal
  * make_truncated_value_warning and Field::set_datetime_warning use Lazy_string as an argument, removed char*/int/double variants
sql/field.h:
  * remove virtual Field::get_time(), everyone should use only Field::get_date()
  * remove lots of #ifdef WORDS_BIGENDIAN
  * unified the warnings from Field_timestamp/datetime/time/date/newdate store methods
  * Field_timestamp_hires, Field_datetime_hires, Field_time_hires
  * Field_temporal
  * make_truncated_value_warning and Field::set_datetime_warning use Lazy_string as an argument, removed char*/int/double variants
  * removed Field::can_be_compared_as_longlong(). Use Field::cmp_type() == INT_RESULT instead
sql/filesort.cc:
  TIME_RESULT, cmp_time()
sql/item.cc:
  * numbers aren't quoted in EXPLAIN EXTENDED
  * Item::cmp_result() instead of Item::is_datetime() and Item::result_as_longlong()
  * virtual Item::get_time() is gone
  * Item_param::field_type() is set correctly
  * Item_datetime, for a datetime constant
  * time to anything is compared as a time
  * Item_cache::print() prints the value is available
  * bug fixed in Item_cache_int::val_str()
sql/item.h:
  * Item::print_value(), to be used from Item_xxx::print() when needed
  * Item::cmp_result() instead of Item::is_datetime() and Item::result_as_longlong()
  * virtual Item::get_time() is gone
  * Item_datetime, for a datetime constant
  * better default for cast_to_int_type()
  * Item_cache objects now *always* have the field_type() set
sql/item_cmpfunc.cc:
  * get_year_value, get_time_value are gone. get_datetime_value does it all
  * get_value_a_func, get_value_b_func are gone
  * can_compare_as_dates() is gone too, TIME_RESULT is used instead
  * cmp_type() instead or result_type() when doing a comparison
  * compare_datetime and compate_e_datetime in the comparator_matrix, is_nulls_eq is gone
  * Item::cmp_result() instead of Item::is_datetime() and Item::result_as_longlong()
sql/item_cmpfunc.h:
  greatly simplified Arg_comparator
sql/item_create.cc:
  * fix a bug in error messages in CAST
sql/item_func.cc:
  Item::cmp_result() instead of Item::is_datetime() and Item::result_as_longlong()
  mention all possibitiles in switch over Item_result values, or use default:
sql/item_row.h:
  overwrite the default cmp_type() for Item_row,
  as no MYSQL_TYPE_xxx value corresponds to ROW_RESULT
sql/item_timefunc.cc:
  rewrite make_datetime to support precision argument
  SEC_TO_TIME is real function, not integer.
  many functions that returned temporal values had duplicate code in val_* methods,
  some of them did not have get_date() which resulted in unnecessary date->str->date conversions. 
  Now they all are derived from Item_temporal_func and *only* provide get_date, not val* methods.
  many fixes to set decimals (datetime precision) correctly.
sql/item_timefunc.h:
  SEC_TO_TIME is real function, not integer.
  many functions that returned temporal values had duplicate code in val_* methods,
  some of them did not have get_date() which resulted in unnecessary date->str->date conversions. 
  Now they all are derived from Item_temporal_func and *only* provide get_date, not val* methods.
  many fixes to set decimals (datetime precision) correctly.
sql/log_event.cc:
  replication of NOW(6)
sql/log_event.h:
  replication of NOW(6)
sql/mysql_priv.h:
  Lazy_string class to pass a value (string, number, time) polymorphically down the stack.
  make_truncated_value_warning() that uses it.
sql/mysqld.cc:
  datetime in Arg_comparator::comparator_matrix
sql/opt_range.cc:
  cleanup: don't disable warnings before calling save_in_field_no_warnings()
sql/protocol.cc:
  Protocol::store(time) now takes the precision as an argument
sql/protocol.h:
  Protocol::store(time) now takes the precision as an argument
sql/rpl_rli.cc:
  small cleanup
sql/set_var.cc:
  SET TIMESTAMP=double
sql/set_var.h:
  @@TIMESTAMP is a double
sql/share/errmsg.txt:
  precision and scale are unsigned
sql/slave.cc:
  replication of NOW(6)
sql/sp_head.cc:
  cleanup
sql/sql_class.cc:
  support for NOW(6)
sql/sql_class.h:
  support for NOW(6)
sql/sql_insert.cc:
  support for NOW(6)
sql/sql_select.cc:
  use item->cmp_type().
  move a comment where it belongs
sql/sql_show.cc:
  new column I_S.COLUMNS.DATETIME_PRECISION
sql/sql_yacc.yy:
  TIME(X), DATETIME(X), cast, NOW(X), CURTIME(X), etc
sql/time.cc:
  fix date_add_interval() to support MYSQL_TIMESTAMP_TIME argument
storage/myisam/ha_myisam.cc:
  TIMESTAMP no longer carries ZEROFIELD flag, still we keep MYI file compatible.
strings/my_vsnprintf.c:
  warnings
tests/mysql_client_test.c:
  old timestamp(X) does not work anymore
  datetime is no longer equal to time
2011-03-01 13:24:36 +01:00
Ole John Aske
59269b1da1 Fix for bug#57030: ('BETWEEN' evaluation is incorrect')
Root cause for this bug is that the optimizer try to detect&
optimize the special case:
      
'<field>  BETWEEN c1 AND c1' and handle this as the condition '<field>  = c1'
            
This was implemented inside add_key_field(.. *field, *value[]...)
which assumed field to refer key Field, and value[] to refer a [low...high]
constant pair. value[0] and value[1] was then compared for equality.
            
In a 'normal' BETWEEN condition of the form '<field>  BETWEEN val1 and val2' the
BETWEEN operation is represented with an argementlist containing the
values [<field>, val1, val2] - add_key_field() is then called with
parameters field=<field>, *value=val1.
            
However, if the BETWEEN predicate specified:
            
 1)  '<const1>  BETWEEN<const2>  AND<field>
            
the 'field' and 'value' arguments to add_key_field() had to be swapped.
This was implemented by trying to cheat add_key_field() to handle it like:
            
 2) '<const1>  GE<const2>  AND<const1>  LE<field>'
            
As we didn't really replace the BETWEEN operation with 'ge' and 'le',
add_key_field() still handled it as a 'BETWEEN' and compared the (swapped)
arguments<const1>  and<const2>  for equality. If they was equal, the
condition 1) was incorrectly 'optimized' to:
            
 3) '<field>  EQ <const1>'
            
This fix moves this optimization of '<field>  BETWEEN c1 AND c1' into
add_key_fields() which then calls add_key_equal_fields() to collect 
key equality / comparison for the key fields in the BETWEEN condition.
2011-02-01 13:20:16 +01:00
Ole John Aske
4b8888f6f0 Merge 2011-02-01 13:23:28 +01:00
Igor Babaev
0dc5ef87d4 Merge 2010-12-27 14:22:05 -08:00
Sergei Golubchik
65ca700def merge.
checkpoint.
does not compile.
2010-11-25 18:17:28 +01:00
Igor Babaev
0b72fd88a1 Merge. 2010-10-30 06:07:45 -07:00
Sergei Golubchik
8e7ebfbce8 5.2 merge 2010-10-28 19:04:23 +02:00
Igor Babaev
25f5debdc7 MWL#128: Added into EXPLAIN output info about types of the used join buffers and
about the employed join algorithms.
Refactored constructors of the JOIN_CACHE* classes.
2010-10-18 13:33:05 -07:00
Alexey Kopytov
b6e89ff7a8 Automerge. 2010-08-26 16:35:38 +04:00
Alexey Kopytov
e7b2688271 Bug #54802: 'NOT BETWEEN' evaluation is incorrect
Queries involving predicates of the form "const NOT BETWEEN
not_indexed_column AND indexed_column" could return wrong data
due to incorrect handling by the range optimizer.

For "c NOT BETWEEN f1 AND f2" predicates, get_mm_tree()
produces a disjunction of the SEL_ARG trees for "f1 > c" and
"f2 < c". If one of the trees is empty (i.e. one of the
arguments is not sargable) the resulting tree should be empty
as well, since the whole expression in this case is not
sargable.

The above logic is implemented in get_mm_tree() as follows. The
initial state of the resulting tree is NULL (aka empty). We
then iterate through arguments and compute the corresponding
SEL_ARG tree (either "f1 > c" or "f2 < c"). If the resulting
tree is NULL, it is simply replaced by the generated
tree. Otherwise it is replaced by a disjunction of itself and
the generated tree. The obvious flaw in this implementation is
that if the first argument is not sargable and thus produces a
NULL tree, the resulting tree will simply be replaced by the
tree for the second argument. As a result, "c NOT BETWEEN f1
AND f2" will end up as just "f2 < c".

Fixed by adding a check so that when the first argument
produces an empty tree for the NOT BETWEEN case, the loop is
aborted with an empty tree as a result. The whole idea of using
a loop for 2 arguments does not make much sense, but it was
probably used to avoid code duplication for several BETWEEN
variants.
2010-08-24 19:51:32 +04:00
Martin Hansson
2c47236bef Merge of fix for Bug#54444. 2010-08-11 17:55:07 +02:00
Martin Hansson
41cfa3e769 Bug#54444: Do not run main.range test for products without partitioning
feature

The test for bug no 50939 was put in range.test which isn't such a good idea
since it requires partitioning. Fixed by moving the test case to
partitioning_range.test.
2010-08-11 14:13:59 +02:00
Alexey Kopytov
d9a5541a34 Manual merge from mysql-5.1-bugteam to mysql-trunk-merge.
Conflicts:

Text conflict in tests/mysql_client_test.c
2010-05-11 12:27:53 +04:00
Martin Hansson
6d0425b18d Bug#50939: Loose Index Scan unduly relies on engine to
remember range endpoints

The Loose Index Scan optimization keeps track of a sequence
of intervals. For the current interval it maintains the
current interval's endpoints. But the maximum endpoint was
not stored in the SQL layer; rather, it relied on the
storage engine to retain this value in-between reads. By
coincidence this holds for MyISAM and InnoDB. Not for the
partitioning engine, however.

Fixed by making the key values iterator 
(QUICK_RANGE_SELECT) keep track of the current maximum endpoint.
This is also more efficient as we save a call through the
handler API in case of open-ended intervals.

The code to calculate endpoints was extracted into 
separate methods in QUICK_RANGE_SELECT, and it was possible to
get rid of some code duplication as part of fix.
2010-05-10 09:23:23 +02:00
Sergey Petrunya
7df026676b Merge MariaDB-5.2 -> MariaDB 5.3 2010-03-20 15:01:47 +03:00
Sergey Petrunya
96e092dc73 Backport into MariaDB-5.2 the following:
WL#2474 "Multi Range Read: Change the default MRR implementation to implement new MRR interface"
WL#2475 "Batched range read functions for MyISAM/InnoDb"
        "Index condition pushdown for MyISAM/InnoDB"
Igor's fix from sp1r-igor@olga.mysql.com-20080330055902-07614:
  There could be observed the following problems:
  1. EXPLAIN did not mention pushdown conditions from on expressions in the 
  'extra' column.  As a result if a query had no where conditions pushed 
  down to a table, but had on conditions pushed to this table the 'extra' 
  column in the EXPLAIN for the table missed 'using where'.
  2. Conditions for ref access were not eliminated from on expressions 
  though such conditions were eliminated from the where condition.
2009-12-15 10:16:46 +03:00
Alexander Nozdrin
5676713687 Manual merge from mysql-trunk.
Conflicts:
  - client/mysqltest.cc
  - mysql-test/collections/default.experimental
  - mysql-test/suite/rpl/t/disabled.def
  - sql/mysqld.cc
  - sql/opt_range.cc
  - sql/sp.cc
  - sql/sql_acl.cc
  - sql/sql_partition.cc
  - sql/sql_table.cc
2009-12-11 12:39:38 +03:00
Martin Hansson
14f2eb1244 Bug#48459: valgrind errors with query using 'Range checked
for each record'

There was an error in an internal structure in the range
optimizer (SEL_ARG). Bad design causes parts of a data
structure not to be initialized when it is in a certain
state. All client code must check that this state is not
present before trying to access the structure's data. Fixed
by

- Checking the state before trying to access data (in
several places, most of which not covered by test case.)

- Copying the keypart id when cloning SEL_ARGs


mysql-test/r/range.result:
  Bug#48459: Test result.
mysql-test/t/range.test:
  Bug#48459: Test case.
sql/opt_range.cc:
  Bug#48459: Fix + doxygenated count_key_part_usage comment.
2009-11-25 11:02:25 +01:00
Georgi Kodinov
405c9310cf Bug #48665: sql-bench's insert test fails due to wrong result
When merging ranges during calculation of the result of OR
to two range sets the current range may be obsoleted by the 
resulting merged range.
The first overlapping range can be obsoleted as well.

Fixed by moving the pointer to the first overlapping range to the
pointer of the resulting union range.
Added few comments at key places in key_or().
2009-11-19 18:26:19 +02:00
Alexander Nozdrin
7cd11f45be Manual merge from mysql-trunk-merge. 2009-11-06 17:20:27 +03:00
Martin Hansson
740b7c4e36 Bug#47925: regression of range optimizer and date comparison in 5.1.39!
When a query was using a DATE or DATETIME value formatted
using any other separator characters beside hyphen '-', a
query with a greater-or-equal '>=' condition matching only
the greatest value in an indexed column, the result was
empty if index range scan was employed.

The range optimizer got a new feature between 5.1.38 and
5.1.39 that changes a greater-or-equal condition to a
greater-than if the value matching that in the query was not
present in the table. But the value comparison function
compared the dates as strings instead of dates.

The bug was fixed by splitting the function
get_date_from_str in two: One part that parses and does
error checking. This function is now visible outside the
module. The old get_date_from_str now calls the new
function.


mysql-test/r/range.result:
  Bug#47925: Test result
mysql-test/t/range.test:
  Bug#47925: Test case
sql/item.cc:
  Bug#47925: Fix + some edit on the comments
sql/item.h:
  Bug#47925: Changed function signature
sql/item_cmpfunc.cc:
  Bug#47925: Split function in two
sql/item_cmpfunc.h:
  Bug#47925: Declaration of new function
sql/opt_range.cc:
  Bug#47925: Added THD to function call
sql/time.cc:
  Bug#47925: Added microsecond comparison
2009-11-02 13:24:07 +01:00
Alexey Kopytov
f6868a4eb4 Bug #47123: Endless 100% CPU loop with STRAIGHT_JOIN
The problem was in incorrect handling of predicates involving 
NULL as a constant value by the range optimizer. 
 
For example, when creating a SEL_ARG node from a condition of 
the form "field < const" (which would normally result in the 
"NULL < field < const" SEL_ARG),  the special case when "const" 
is NULL was not taken into account, so "NULL < field < NULL" 
was produced for the "field < NULL" condition. 
 
As a result, SEL_ARG structures of this form could not be 
further optimized which in turn could lead to incorrectly 
constructed SEL_ARG trees. In particular, code assuming SEL_ARG 
structures to always form a sequence of ordered disjoint 
intervals could enter an infinite loop under some 
circumstances. 
 
Fixed by changing get_mm_leaf() so that for any sargable 
predicate except "<=>" involving NULL as a constant, "empty" 
SEL_ARG is returned, since such a predicate is always false. 

mysql-test/r/partition_pruning.result:
  Fixed a broken test case.
mysql-test/r/range.result:
  Added a test case for bug #47123.
mysql-test/r/subselect.result:
  Fixed a broken test cases.
mysql-test/t/range.test:
  Added a test case for bug #47123.
sql/opt_range.cc:
  Fixed get_mm_leaf() so that for any sargable
  predicate except "<=>" involving NULL as a constant, "empty"
  SEL_ARG is returned, since such a predicate is always false.
2009-10-17 00:19:51 +04:00
Georgi Kodinov
d80e35f26f Revert the fix for bug #47123 until test suite failures are resolved. 2009-10-16 11:42:16 +03:00
Alexey Kopytov
79406bc49a Manual merge. 2009-10-15 14:42:51 +04:00
Alexey Kopytov
bc9f56a6c2 Bug #47123: Endless 100% CPU loop with STRAIGHT_JOIN
The problem was in incorrect handling of predicates involving 
NULL as a constant value by the range optimizer.  
 
For example, when creating a SEL_ARG node from a condition of 
the form "field < const" (which would normally result in the 
"NULL < field < const" SEL_ARG),  the special case when "const" 
is NULL was not taken into account, so "NULL < field < NULL" 
was produced for the "field < NULL" condition. 
 
As a result, SEL_ARG structures of this form could not be 
further optimized which in turn could lead to incorrectly 
constructed SEL_ARG trees. In particular, code assuming SEL_ARG 
structures to always form a sequence of ordered disjoint 
intervals could enter an infinite loop under some 
circumstances. 
 
Fixed by changing get_mm_leaf() so that for any sargable 
predicate except "<=>" involving NULL as a constant, "empty" 
SEL_ARG is returned, since such a predicate is always false. 

mysql-test/r/range.result:
  Added a test case for bug #47123.
mysql-test/t/range.test:
  Added a test case for bug #47123.
sql/opt_range.cc:
  Fixed get_mm_leaf() so that for any sargable 
  predicate except "<=>" involving NULL as a constant, "empty" 
  SEL_ARG is returned, since such a predicate is always false.
2009-10-13 19:49:32 +04:00
Martin Hansson
5ef9ec9d9e Bug#42846: wrong result returned for range scan when using
covering index
      
When two range predicates were combined under an OR
predicate, the algorithm tried to merge overlapping ranges
into one. But the case when a range overlapped several other
ranges was not handled. This lead to

1) ranges overlapping, which gave repeated results and 
2) a range that overlapped several other ranges was cut off.  

Fixed by 

1) Making sure that a range got an upper bound equal to the
next range with a greater minimum.
2) Removing a continue statement


mysql-test/r/group_min_max.result:
  Bug#42846: Changed query plans
mysql-test/r/range.result:
  Bug#42846: Test result.
mysql-test/t/range.test:
  Bug#42846: Test case.
sql/opt_range.cc:
  Bug#42846: The fix. 
  
  Part1: Previously, both endpoints from key2 were copied,
  which is not safe. Since ranges are processed in ascending
  order of minimum endpoints, it is safe to copy the minimum
  endpoint from key2 but not the maximum. The maximum may only
  be copied if there is no other range or the other range's
  minimum is greater than key2's maximum.
2009-10-09 11:30:40 +02:00
unknown
548b389f3a Merge mysql.com:/misc/mysql/34731/50-34731
into  mysql.com:/misc/mysql/34731/51-34731


mysql-test/t/range.test:
  Auto merged
sql/opt_range.cc:
  Auto merged
mysql-test/r/range.result:
  manual merge
2008-03-27 03:18:46 +01:00
unknown
fd1616311d Merge mysql.com:/misc/mysql/34731_/50-34731
into  mysql.com:/misc/mysql/34731/50-34731


sql/opt_range.cc:
  Auto merged
mysql-test/r/range.result:
  manual merge
mysql-test/t/range.test:
  manual merge
2008-03-27 03:16:35 +01:00
unknown
ec62aba3f0 Bug#34731: highest possible value for INT erroneously filtered by WHERE
WHERE f1 < n ignored row if f1 was indexed integer column and
f1 = TYPE_MAX ^ n = TYPE_MAX+1. The latter value when treated
as TYPE overflowed (obviously). This was not handled, it is now.


mysql-test/r/range.result:
  show that on an index int column, we no longer disregard
  a field val of TYPE_MAX in SELECT ... WHERE ... < TYPE_MAX+1
mysql-test/t/range.test:
  show that on an index int column, we no longer disregard
  a field val of TYPE_MAX in SELECT ... WHERE ... < TYPE_MAX+1
sql/opt_range.cc:
  Handle overflowing of int-types in range-optimizer.
  Unfortunately requires re-indentation of entire block.
  Overflow (err == 1) was handled, but only if
  field->cmp_type() != value->result_type(), which it
  just wasn't in our case.
2008-03-10 11:12:12 +01:00