Below is the list of changes that have just been committed into a local
5.1 repository of evgen. When evgen does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.2218 06/06/18 14:56:35 evgen@stripped +49 -0
Manually merged
sql/item_timefunc.h
1.72 06/06/18 14:56:31 evgen@stripped +1 -1
Manually merged
sql/item_cmpfunc.cc
1.206 06/06/18 14:56:31 evgen@stripped +0 -12
Manually merged
sql/field.h
1.187 06/06/18 14:56:31 evgen@stripped +0 -0
Manually merged
mysql-test/r/select.result
1.129 06/06/18 14:56:31 evgen@stripped +64 -0
Manually merged
mysql-test/r/rpl_stm_log.result
1.69 06/06/18 14:56:31 evgen@stripped +0 -0
Manually merged
mysql-test/extra/rpl_tests/rpl_log.test
1.38 06/06/18 14:56:31 evgen@stripped +6 -5
Manually merged
tests/mysql_client_test.c
1.193 06/06/18 14:20:29 evgen@stripped +0 -0
Auto merged
storage/archive/ha_archive.cc
1.98 06/06/18 14:20:29 evgen@stripped +0 -0
Auto merged
sql/structs.h
1.61 06/06/18 14:20:29 evgen@stripped +0 -0
Auto merged
sql/sql_yacc.yy
1.482 06/06/18 14:20:29 evgen@stripped +0 -0
Auto merged
sql/sql_select.h
1.108 06/06/18 14:20:28 evgen@stripped +0 -0
Auto merged
sql/sql_select.cc
1.413 06/06/18 14:20:28 evgen@stripped +0 -0
Auto merged
sql/sql_parse.cc
1.561 06/06/18 14:20:28 evgen@stripped +0 -0
Auto merged
sql/sql_lex.h
1.233 06/06/18 14:20:28 evgen@stripped +0 -0
Auto merged
sql/sql_lex.cc
1.185 06/06/18 14:20:28 evgen@stripped +0 -0
Auto merged
sql/sql_insert.cc
1.204 06/06/18 14:20:28 evgen@stripped +0 -0
Auto merged
sql/sql_class.h
1.298 06/06/18 14:20:28 evgen@stripped +0 -0
Auto merged
sql/sql_class.cc
1.266 06/06/18 14:20:28 evgen@stripped +0 -0
Auto merged
sql/sql_base.cc
1.328 06/06/18 14:20:27 evgen@stripped +0 -0
Auto merged
sql/opt_sum.cc
1.52 06/06/18 14:20:27 evgen@stripped +0 -0
Auto merged
sql/opt_range.cc
1.221 06/06/18 14:20:27 evgen@stripped +0 -0
Auto merged
sql/item_timefunc.cc
1.122 06/06/18 14:20:27 evgen@stripped +0 -0
Auto merged
sql/item_strfunc.cc
1.273 06/06/18 14:20:27 evgen@stripped +0 -0
Auto merged
sql/item_func.cc
1.299 06/06/18 14:20:27 evgen@stripped +0 -0
Auto merged
sql/item_cmpfunc.h
1.127 06/06/18 14:20:27 evgen@stripped +0 -0
Auto merged
sql/item.h
1.203 06/06/18 14:20:27 evgen@stripped +0 -0
Auto merged
sql/ha_ndbcluster.cc
1.328 06/06/18 14:20:27 evgen@stripped +0 -0
Auto merged
sql/field.cc
1.318 06/06/18 14:20:26 evgen@stripped +0 -0
Auto merged
mysql-test/t/select.test
1.104 06/06/18 14:20:26 evgen@stripped +0 -0
Auto merged
mysql-test/t/ndb_lock.test
1.12 06/06/18 14:20:26 evgen@stripped +0 -0
Auto merged
mysql-test/t/multi_update.test
1.51 06/06/18 14:20:26 evgen@stripped +0 -0
Auto merged
mysql-test/t/func_time.test
1.45 06/06/18 14:20:26 evgen@stripped +0 -0
Auto merged
mysql-test/t/delayed.test
1.14 06/06/18 14:20:26 evgen@stripped +0 -0
Auto merged
mysql-test/t/auto_increment.test
1.27 06/06/18 14:20:26 evgen@stripped +0 -0
Auto merged
mysql-test/t/archive.test
1.22 06/06/18 14:20:26 evgen@stripped +0 -0
Auto merged
mysql-test/r/union.result
1.84 06/06/18 14:20:26 evgen@stripped +0 -0
Auto merged
mysql-test/r/replace.result
1.11 06/06/18 14:20:26 evgen@stripped +0 -0
Auto merged
mysql-test/r/ndb_lock.result
1.12 06/06/18 14:20:26 evgen@stripped +0 -1
Auto merged
mysql-test/r/multi_update.result
1.45 06/06/18 14:20:26 evgen@stripped +0 -0
Auto merged
mysql-test/r/func_time.result
1.55 06/06/18 14:20:26 evgen@stripped +0 -0
Auto merged
mysql-test/r/func_str.result
1.117 06/06/18 14:20:26 evgen@stripped +0 -0
Auto merged
mysql-test/r/func_group.result
1.50 06/06/18 14:20:26 evgen@stripped +0 -0
Auto merged
mysql-test/r/ctype_utf8.result
1.90 06/06/18 14:20:26 evgen@stripped +0 -0
Auto merged
mysql-test/r/cast.result
1.43 06/06/18 14:20:26 evgen@stripped +0 -0
Auto merged
mysql-test/r/auto_increment.result
1.42 06/06/18 14:20:26 evgen@stripped +0 -0
Auto merged
mysql-test/r/archive.result
1.22 06/06/18 14:20:26 evgen@stripped +0 -0
Auto merged
mysql-test/mysql-test-run.pl
1.124 06/06/18 14:20:26 evgen@stripped +0 -0
Auto merged
client/mysqlbinlog.cc
1.131 06/06/18 14:20:26 evgen@stripped +0 -0
Auto merged
storage/archive/ha_archive.cc
1.60.1.11 06/06/18 14:20:25 evgen@stripped +0 -0
Merge rename: sql/ha_archive.cc -> storage/archive/ha_archive.cc
mysql-test/r/rpl_stm_log.result
1.62.2.4 06/06/18 14:20:25 evgen@stripped +0 -0
Merge rename: mysql-test/r/rpl_log.result -> mysql-test/r/rpl_stm_log.result
mysql-test/extra/rpl_tests/rpl_log.test
1.27.2.3 06/06/18 14:20:25 evgen@stripped +0 -0
Merge rename: mysql-test/t/rpl_log.test -> mysql-test/extra/rpl_tests/rpl_log.test
configure.in
1.363 06/06/18 14:20:25 evgen@stripped +0 -0
Auto merged
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: evgen
# Host: moonbone.local
# Root: /work/tmp_merge-5.1-opt-mysql/RESYNC
--- 1.317/sql/field.cc 2006-06-16 18:26:11 +04:00
+++ 1.318/sql/field.cc 2006-06-18 14:20:26 +04:00
@@ -4604,11 +4604,11 @@
int error;
bool have_smth_to_conv;
my_bool in_dst_time_gap;
- THD *thd= table->in_use;
+ THD *thd= table ? table->in_use : current_thd;
/* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */
have_smth_to_conv= (str_to_datetime(from, len, &l_time,
- (table->in_use->variables.sql_mode &
+ (thd->variables.sql_mode &
MODE_NO_ZERO_DATE) |
MODE_NO_ZERO_IN_DATE, &error) >
MYSQL_TIMESTAMP_ERROR);
@@ -4674,7 +4674,7 @@
my_time_t timestamp= 0;
int error;
my_bool in_dst_time_gap;
- THD *thd= table->in_use;
+ THD *thd= table ? table->in_use : current_thd;
/* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */
longlong tmp= number_to_datetime(nr, &l_time, (thd->variables.sql_mode &
@@ -4730,7 +4730,7 @@
ASSERT_COLUMN_MARKED_FOR_READ;
uint32 temp;
TIME time_tmp;
- THD *thd= table->in_use;
+ THD *thd= table ? table->in_use : current_thd;
#ifdef WORDS_BIGENDIAN
if (table->s->db_low_byte_first)
@@ -4756,7 +4756,7 @@
ASSERT_COLUMN_MARKED_FOR_READ;
uint32 temp, temp2;
TIME time_tmp;
- THD *thd= table->in_use;
+ THD *thd= table ? table->in_use : current_thd;
char *to;
val_buffer->alloc(field_length+1);
@@ -4827,7 +4827,7 @@
bool Field_timestamp::get_date(TIME *ltime, uint fuzzydate)
{
long temp;
- THD *thd= table->in_use;
+ THD *thd= table ? table->in_use : current_thd;
#ifdef WORDS_BIGENDIAN
if (table->s->db_low_byte_first)
temp=uint4korr(ptr);
@@ -4910,7 +4910,8 @@
void Field_timestamp::set_time()
{
- long tmp= (long) table->in_use->query_start();
+ THD *thd= table ? table->in_use : current_thd;
+ long tmp= (long) thd->query_start();
set_notnull();
#ifdef WORDS_BIGENDIAN
if (table->s->db_low_byte_first)
@@ -5107,12 +5108,13 @@
bool Field_time::get_date(TIME *ltime, uint fuzzydate)
{
long tmp;
+ THD *thd= table ? table->in_use : current_thd;
if (!(fuzzydate & TIME_FUZZY_DATE))
{
- push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN,
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE,
ER(ER_WARN_DATA_OUT_OF_RANGE), field_name,
- table->in_use->row_count);
+ thd->row_count);
return 1;
}
tmp=(long) sint3korr(ptr);
@@ -5305,9 +5307,10 @@
TIME l_time;
uint32 tmp;
int error;
+ THD *thd= table ? table->in_use : current_thd;
if (str_to_datetime(from, len, &l_time, TIME_FUZZY_DATE |
- (table->in_use->variables.sql_mode &
+ (thd->variables.sql_mode &
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
MODE_INVALID_DATES)),
&error) <= MYSQL_TIMESTAMP_ERROR)
@@ -5361,9 +5364,10 @@
TIME not_used;
int error;
longlong initial_nr= nr;
+ THD *thd= table ? table->in_use : current_thd;
nr= number_to_datetime(nr, ¬_used, (TIME_FUZZY_DATE |
- (table->in_use->variables.sql_mode &
+ (thd->variables.sql_mode &
(MODE_NO_ZERO_IN_DATE |
MODE_NO_ZERO_DATE |
MODE_INVALID_DATES))), &error);
@@ -5513,9 +5517,10 @@
TIME l_time;
long tmp;
int error;
+ THD *thd= table ? table->in_use : current_thd;
if (str_to_datetime(from, len, &l_time,
(TIME_FUZZY_DATE |
- (table->in_use->variables.sql_mode &
+ (thd->variables.sql_mode &
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
MODE_INVALID_DATES))),
&error) <= MYSQL_TIMESTAMP_ERROR)
@@ -5554,9 +5559,10 @@
TIME l_time;
longlong tmp;
int error;
+ THD *thd= table ? table->in_use : current_thd;
if (number_to_datetime(nr, &l_time,
(TIME_FUZZY_DATE |
- (table->in_use->variables.sql_mode &
+ (thd->variables.sql_mode &
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
MODE_INVALID_DATES))),
&error) == LL(-1))
@@ -5704,10 +5710,11 @@
int error;
ulonglong tmp= 0;
enum enum_mysql_timestamp_type func_res;
+ THD *thd= table ? table->in_use : current_thd;
func_res= str_to_datetime(from, len, &time_tmp,
(TIME_FUZZY_DATE |
- (table->in_use->variables.sql_mode &
+ (thd->variables.sql_mode &
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
MODE_INVALID_DATES))),
&error);
@@ -5755,9 +5762,10 @@
TIME not_used;
int error;
longlong initial_nr= nr;
+ THD *thd= table ? table->in_use : current_thd;
nr= number_to_datetime(nr, ¬_used, (TIME_FUZZY_DATE |
- (table->in_use->variables.sql_mode &
+ (thd->variables.sql_mode &
(MODE_NO_ZERO_IN_DATE |
MODE_NO_ZERO_DATE |
MODE_INVALID_DATES))), &error);
@@ -6173,17 +6181,6 @@
{
uint a_len, b_len;
- if (field_charset->strxfrm_multiply > 1)
- {
- /*
- We have to remove end space to be able to compare multi-byte-characters
- like in latin_de 'ae' and 0xe4
- */
- return field_charset->coll->strnncollsp(field_charset,
- (const uchar*) a_ptr, field_length,
- (const uchar*) b_ptr,
- field_length, 0);
- }
if (field_charset->mbmaxlen != 1)
{
uint char_len= field_length/field_charset->mbmaxlen;
@@ -6192,8 +6189,14 @@
}
else
a_len= b_len= field_length;
- return my_strnncoll(field_charset,(const uchar*) a_ptr, a_len,
- (const uchar*) b_ptr, b_len);
+ /*
+ We have to remove end space to be able to compare multi-byte-characters
+ like in latin_de 'ae' and 0xe4
+ */
+ return field_charset->coll->strnncollsp(field_charset,
+ (const uchar*) a_ptr, a_len,
+ (const uchar*) b_ptr, b_len,
+ 0);
}
@@ -9247,7 +9250,11 @@
Field::set_warning(MYSQL_ERROR::enum_warning_level level, uint code,
int cuted_increment)
{
- THD *thd= table->in_use;
+ /*
+ If this field was created only for type conversion purposes it
+ will have table == NULL.
+ */
+ THD *thd= table ? table->in_use : current_thd;
if (thd->count_cuted_fields)
{
thd->cuted_fields+= cuted_increment;
@@ -9282,9 +9289,10 @@
const char *str, uint str_length,
timestamp_type ts_type, int cuted_increment)
{
- if (table->in_use->really_abort_on_warning() ||
+ THD *thd= table ? table->in_use : current_thd;
+ if (thd->really_abort_on_warning() ||
set_warning(level, code, cuted_increment))
- make_truncated_value_warning(table->in_use, str, str_length, ts_type,
+ make_truncated_value_warning(thd, str, str_length, ts_type,
field_name);
}
@@ -9311,13 +9319,13 @@
longlong nr, timestamp_type ts_type,
int cuted_increment)
{
- if (table->in_use->really_abort_on_warning() ||
+ THD *thd= table ? table->in_use : current_thd;
+ if (thd->really_abort_on_warning() ||
set_warning(level, code, cuted_increment))
{
char str_nr[22];
char *str_end= longlong10_to_str(nr, str_nr, -10);
- make_truncated_value_warning(table->in_use, str_nr,
- (uint) (str_end - str_nr),
+ make_truncated_value_warning(thd, str_nr, (uint) (str_end - str_nr),
ts_type, field_name);
}
}
@@ -9343,13 +9351,15 @@
Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level, uint code,
double nr, timestamp_type ts_type)
{
- if (table->in_use->really_abort_on_warning() ||
+ THD *thd= table ? table->in_use : current_thd;
+ if (thd->really_abort_on_warning() ||
set_warning(level, code, 1))
{
/* DBL_DIG is enough to print '-[digits].E+###' */
char str_nr[DBL_DIG + 8];
uint str_len= my_sprintf(str_nr, (str_nr, "%g", nr));
- make_truncated_value_warning(table->in_use, str_nr, str_len, ts_type,
+ make_truncated_value_warning(thd, str_nr, str_len, ts_type,
field_name);
}
}
+
--- 1.186/sql/field.h 2006-06-04 20:23:38 +04:00
+++ 1.187/sql/field.h 2006-06-18 14:56:31 +04:00
@@ -124,7 +124,7 @@
static bool type_can_have_key_part(enum_field_types);
static enum_field_types field_type_merge(enum_field_types, enum_field_types);
static Item_result result_merge_type(enum_field_types);
- bool eq(Field *field)
+ virtual bool eq(Field *field)
{
return (ptr == field->ptr && null_ptr == field->null_ptr &&
null_bit == field->null_bit);
@@ -1386,6 +1386,13 @@
{
bit_ptr= bit_ptr_arg;
bit_ofs= bit_ofs_arg;
+ }
+ bool eq(Field *field)
+ {
+ return (Field::eq(field) &&
+ field->type() == type() &&
+ bit_ptr == ((Field_bit *)field)->bit_ptr &&
+ bit_ofs == ((Field_bit *)field)->bit_ofs);
}
void move_field_offset(my_ptrdiff_t ptr_diff)
{
--- 1.202/sql/item.h 2006-06-13 23:33:08 +04:00
+++ 1.203/sql/item.h 2006-06-18 14:20:27 +04:00
@@ -857,6 +857,14 @@
{
return 0;
}
+ /*
+ result_as_longlong() must return TRUE for Items representing DATE/TIME
+ functions and DATE/TIME table fields.
+ Those Items have result_type()==STRING_RESULT (and not INT_RESULT), but
+ their values should be compared as integers (because the integer
+ representation is more precise than the string one).
+ */
+ virtual bool result_as_longlong() { return FALSE; }
};
@@ -1283,6 +1291,10 @@
bool register_field_in_read_map(byte *arg);
bool check_partition_func_processor(byte *bool_arg) { return 0; }
void cleanup();
+ bool result_as_longlong()
+ {
+ return field->can_be_compared_as_longlong();
+ }
Item_equal *find_item_equal(COND_EQUAL *cond_equal);
Item *equal_fields_propagator(byte *arg);
Item *set_no_const_sub(byte *arg);
@@ -1904,6 +1916,10 @@
bool walk(Item_processor processor, bool walk_subquery, byte *arg)
{ return (*ref)->walk(processor, walk_subquery, arg); }
void print(String *str);
+ bool result_as_longlong()
+ {
+ return (*ref)->result_as_longlong();
+ }
void cleanup();
Item_field *filed_for_view_update()
{ return (*ref)->filed_for_view_update(); }
--- 1.205/sql/item_cmpfunc.cc 2006-06-04 22:05:17 +04:00
+++ 1.206/sql/item_cmpfunc.cc 2006-06-18 14:56:31 +04:00
@@ -63,25 +63,144 @@
}
+/*
+ Aggregates result types from the array of items.
+
+ SYNOPSIS:
+ agg_cmp_type()
+ thd thread handle
+ type [out] the aggregated type
+ items array of items to aggregate the type from
+ nitems number of items in the array
+
+ DESCRIPTION
+ This function aggregates result types from the array of items. Found type
+ supposed to be used later for comparison of values of these items.
+ Aggregation itself is performed by the item_cmp_type() function.
+
+ NOTES
+ Aggregation rules:
+ If all items are constants the type will be aggregated from all items.
+ If there are some non-constant items then only types of non-constant
+ items will be used for aggregation.
+ If there are DATE/TIME fields/functions in the list and no string
+ fields/functions in the list then:
+ The INT_RESULT type will be used for aggregation instead of original
+ result type of any DATE/TIME field/function in the list
+ All constant items in the list will be converted to a DATE/TIME using
+ found field or result field of found function.
+
+ Implementation notes:
+ The code is equivalent to:
+ 1. Check the list for presence of a STRING field/function.
+ Collect the is_const flag.
+ 2. Get a Field* object to use for type coercion
+ 3. Perform type conversion.
+ 1 and 2 are implemented in 2 loops. The first searches for a DATE/TIME
+ field/function and checks presence of a STRING field/function.
+ The second loop works only if a DATE/TIME field/function is found.
+ It checks presence of a STRING field/function in the rest of the list.
+
+ TODO
+ 1) The current implementation can produce false comparison results for
+ expressions like:
+ date_time_field BETWEEN string_field_with_dates AND string_constant
+ if the string_constant will omit some of leading zeroes.
+ In order to fully implement correct comparison of DATE/TIME the new
+ DATETIME_RESULT result type should be introduced and agg_cmp_type()
+ should return the DATE/TIME field used for the conversion. Later
+ this field can be used by comparison functions like Item_func_between to
+ convert string values to ints on the fly and thus return correct results.
+ This modification will affect functions BETWEEN, IN and CASE.
+
+ 2) If in the list a DATE field/function and a DATETIME field/function
+ are present in the list then the first found field/function will be
+ used for conversion. This may lead to wrong results and probably should
+ be fixed.
+*/
+
static void agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems)
{
uint i;
+ Item::Type res= (Item::Type)0;
+ /* Used only for date/time fields, max_length = 19 */
+ char buff[20];
+ uchar null_byte;
Field *field= NULL;
- /* If the first argument is a FIELD_ITEM, pull out the field. */
- if (items[0]->real_item()->type() == Item::FIELD_ITEM)
- field=((Item_field *)(items[0]->real_item()))->field;
- /* But if it can't be compared as a longlong, we don't really care. */
- if (field && !field->can_be_compared_as_longlong())
- field= NULL;
-
- type[0]= items[0]->result_type();
- for (i= 1; i < nitems; i++)
- {
- type[0]= item_cmp_type(type[0], items[i]->result_type());
- if (field && convert_constant_item(thd, field, &items[i]))
- type[0]= INT_RESULT;
+ /* Search for date/time fields/functions */
+ for (i= 0; i < nitems; i++)
+ {
+ if (!items[i]->result_as_longlong())
+ {
+ /* Do not convert anything if a string field/function is present */
+ if (!items[i]->const_item() && items[i]->result_type() == STRING_RESULT)
+ {
+ i= nitems;
+ break;
+ }
+ continue;
+ }
+ if ((res= items[i]->real_item()->type()) == Item::FIELD_ITEM)
+ {
+ field= ((Item_field *)items[i]->real_item())->field;
+ break;
+ }
+ else if (res == Item::FUNC_ITEM)
+ {
+ field= items[i]->tmp_table_field_from_field_type(0);
+ if (field)
+ field->move_field(buff, &null_byte, 0);
+ break;
+ }
}
+ if (field)
+ {
+ /* Check the rest of the list for presence of a string field/function. */
+ for (i++ ; i < nitems; i++)
+ {
+ if (!items[i]->const_item() && items[i]->result_type() == STRING_RESULT &&
+ !items[i]->result_as_longlong())
+ {
+ if (res == Item::FUNC_ITEM)
+ delete field;
+ field= 0;
+ break;
+ }
+ }
+ }
+ /* Reset to 0 on first occurence of non-const item. 1 otherwise */
+ bool is_const= items[0]->const_item();
+ /*
+ If the first item is a date/time function then its result should be
+ compared as int
+ */
+ if (field)
+ {
+ /* Suppose we are comparing dates and some non-constant items are present. */
+ type[0]= INT_RESULT;
+ is_const= 0;
+ }
+ else
+ type[0]= items[0]->result_type();
+
+ for (i= 0; i < nitems ; i++)
+ {
+ if (!items[i]->const_item())
+ {
+ Item_result result= field && items[i]->result_as_longlong() ?
+ INT_RESULT : items[i]->result_type();
+ type[0]= is_const ? result : item_cmp_type(type[0], result);
+ is_const= 0;
+ }
+ else if (is_const)
+ type[0]= item_cmp_type(type[0], items[i]->result_type());
+ else if (field)
+ convert_constant_item(thd, field, &items[i]);
+ }
+
+ if (res == Item::FUNC_ITEM && field)
+ delete field;
}
@@ -238,14 +357,6 @@
if (!(*item)->with_subselect && (*item)->const_item())
{
/* For comparison purposes allow invalid dates like 2000-01-32 */
- TABLE *table= field->table;
- ulong orig_sql_mode= table->in_use->variables.sql_mode;
- my_bitmap_map *old_write_map=
- dbug_tmp_use_all_columns(table, table->write_set);
- my_bitmap_map *old_read_map=
- dbug_tmp_use_all_columns(table, table->read_set);
-
- table->in_use->variables.sql_mode|= MODE_INVALID_DATES;
if (!(*item)->save_in_field(field, 1) && !((*item)->null_value))
{
Item *tmp= new Item_int_with_ref(field->val_int(), *item,
@@ -1106,9 +1217,8 @@
return;
agg_cmp_type(thd, &cmp_type, args, 3);
- if (cmp_type == STRING_RESULT &&
- agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV))
- return;
+ if (cmp_type == STRING_RESULT)
+ agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV);
}
--- 1.126/sql/item_cmpfunc.h 2006-06-04 20:23:40 +04:00
+++ 1.127/sql/item_cmpfunc.h 2006-06-18 14:20:27 +04:00
@@ -46,7 +46,7 @@
inline int set_compare_func(Item_bool_func2 *owner_arg)
{
return set_compare_func(owner_arg, item_cmp_type((*a)->result_type(),
- (*b)->result_type()));
+ (*b)->result_type()));
}
inline int set_cmp_func(Item_bool_func2 *owner_arg,
Item **a1, Item **a2,
@@ -59,8 +59,9 @@
inline int set_cmp_func(Item_bool_func2 *owner_arg,
Item **a1, Item **a2)
{
- return set_cmp_func(owner_arg, a1, a2, item_cmp_type((*a1)->result_type(),
- (*a2)->result_type()));
+ return set_cmp_func(owner_arg, a1, a2,
+ item_cmp_type((*a1)->result_type(),
+ (*a2)->result_type()));
}
inline int compare() { return (this->*func)(); }
--- 1.298/sql/item_func.cc 2006-06-16 14:16:58 +04:00
+++ 1.299/sql/item_func.cc 2006-06-18 14:20:27 +04:00
@@ -3288,7 +3288,7 @@
return value; // Avoid side effect of insert_id()
}
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
- return thd->insert_id();
+ return thd->last_insert_id_used ? thd->current_insert_id : thd->insert_id();
}
/* This function is just used to test speed of different functions */
--- 1.272/sql/item_strfunc.cc 2006-06-16 14:16:58 +04:00
+++ 1.273/sql/item_strfunc.cc 2006-06-18 14:20:27 +04:00
@@ -154,7 +154,15 @@
void Item_func_md5::fix_length_and_dec()
{
- max_length=32;
+ max_length=32;
+ /*
+ The MD5() function treats its parameter as being a case sensitive. Thus
+ we set binary collation on it so different instances of MD5() will be
+ compared properly.
+ */
+ args[0]->collation.set(
+ get_charset_by_csname(args[0]->collation.collation->csname,
+ MY_CS_BINSORT,MYF(0)), DERIVATION_COERCIBLE);
}
@@ -195,7 +203,15 @@
void Item_func_sha::fix_length_and_dec()
{
- max_length=SHA1_HASH_SIZE*2; // size of hex representation of hash
+ max_length=SHA1_HASH_SIZE*2; // size of hex representation of hash
+ /*
+ The SHA() function treats its parameter as being a case sensitive. Thus
+ we set binary collation on it so different instances of MD5() will be
+ compared properly.
+ */
+ args[0]->collation.set(
+ get_charset_by_csname(args[0]->collation.collation->csname,
+ MY_CS_BINSORT,MYF(0)), DERIVATION_COERCIBLE);
}
@@ -288,11 +304,14 @@
DBUG_ASSERT(fixed == 1);
String *res,*res2,*use_as_buff;
uint i;
+ bool is_const= 0;
null_value=0;
if (!(res=args[0]->val_str(str)))
goto null;
use_as_buff= &tmp_value;
+ /* Item_subselect in --ps-protocol mode will state it as a non-const */
+ is_const= args[0]->const_item() || !args[0]->used_tables();
for (i=1 ; i < arg_count ; i++)
{
if (res->length() == 0)
@@ -315,7 +334,7 @@
current_thd->variables.max_allowed_packet);
goto null;
}
- if (res->alloced_length() >= res->length()+res2->length())
+ if (!is_const && res->alloced_length() >= res->length()+res2->length())
{ // Use old buffer
res->append(*res2);
}
@@ -370,6 +389,7 @@
res= &tmp_value;
use_as_buff=str;
}
+ is_const= 0;
}
}
res->set_charset(collation.collation);
@@ -389,7 +409,14 @@
return;
for (uint i=0 ; i < arg_count ; i++)
- max_result_length+= args[i]->max_length;
+ {
+ if (args[i]->collation.collation->mbmaxlen != collation.collation->mbmaxlen)
+ max_result_length+= (args[i]->max_length /
+ args[i]->collation.collation->mbmaxlen) *
+ collation.collation->mbmaxlen;
+ else
+ max_result_length+= args[i]->max_length;
+ }
if (max_result_length >= MAX_BLOB_WIDTH)
{
--- 1.121/sql/item_timefunc.cc 2006-06-16 14:16:59 +04:00
+++ 1.122/sql/item_timefunc.cc 2006-06-18 14:20:27 +04:00
@@ -2344,6 +2344,20 @@
}
+longlong Item_datetime_typecast::val_int()
+{
+ DBUG_ASSERT(fixed == 1);
+ TIME ltime;
+ if (get_arg0_date(<ime,1))
+ {
+ null_value= 1;
+ return 0;
+ }
+
+ return TIME_to_ulonglong_datetime(<ime);
+}
+
+
bool Item_time_typecast::get_time(TIME *ltime)
{
bool res= get_arg0_time(ltime);
@@ -2358,6 +2372,17 @@
}
+longlong Item_time_typecast::val_int()
+{
+ TIME ltime;
+ if (get_time(<ime))
+ {
+ null_value= 1;
+ return 0;
+ }
+ return ltime.hour * 10000L + ltime.minute * 100 + ltime.second;
+}
+
String *Item_time_typecast::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
@@ -2397,6 +2422,14 @@
return 0;
}
+longlong Item_date_typecast::val_int()
+{
+ DBUG_ASSERT(fixed == 1);
+ TIME ltime;
+ if (args[0]->get_date(<ime, TIME_FUZZY_DATE))
+ return 0;
+ return (longlong) (ltime.year * 10000L + ltime.month * 100 + ltime.day);
+}
/*
MAKEDATE(a,b) is a date function that creates a date value
@@ -2429,6 +2462,33 @@
err:
null_value=1;
+ return 0;
+}
+
+
+longlong Item_func_makedate::val_int()
+{
+ DBUG_ASSERT(fixed == 1);
+ TIME l_time;
+ long daynr= (long) args[1]->val_int();
+ long yearnr= (long) args[0]->val_int();
+ long days;
+
+ if (args[0]->null_value || args[1]->null_value ||
+ yearnr < 0 || daynr <= 0)
+ goto err;
+
+ days= calc_daynr(yearnr,1,1) + daynr - 1;
+ /* Day number from year 0 to 9999-12-31 */
+ if (days >= 0 && days < MAX_DAY_NUMBER)
+ {
+ null_value=0;
+ get_date_from_daynr(days,&l_time.year,&l_time.month,&l_time.day);
+ return (longlong) (l_time.year * 10000L + l_time.month * 100 + l_time.day);
+ }
+
+err:
+ null_value= 1;
return 0;
}
--- 1.71/sql/item_timefunc.h 2006-06-15 06:53:51 +04:00
+++ 1.72/sql/item_timefunc.h 2006-06-18 14:56:31 +04:00
@@ -365,6 +365,7 @@
{
return tmp_table_field_from_field_type(table, 0);
}
+ bool result_as_longlong() { return TRUE; }
};
@@ -380,6 +381,7 @@
{
return tmp_table_field_from_field_type(table, 0);
}
+ bool result_as_longlong() { return TRUE; }
};
@@ -409,6 +411,7 @@
TIME representation using UTC-SYSTEM or per-thread time zone.
*/
virtual void store_now_in_TIME(TIME *now_time)=0;
+ bool result_as_longlong() { return TRUE; }
};
@@ -647,6 +650,7 @@
{
return tmp_table_field_from_field_type(table, 0);
}
+ bool result_as_longlong() { return TRUE; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
};
@@ -768,6 +772,8 @@
max_length= 10;
maybe_null= 1;
}
+ bool result_as_longlong() { return TRUE; }
+ longlong val_int();
};
@@ -784,6 +790,8 @@
{
return tmp_table_field_from_field_type(table, 0);
}
+ bool result_as_longlong() { return TRUE; }
+ longlong val_int();
};
@@ -799,6 +807,8 @@
{
return tmp_table_field_from_field_type(table, 0);
}
+ bool result_as_longlong() { return TRUE; }
+ longlong val_int();
};
class Item_func_makedate :public Item_str_func
@@ -817,6 +827,8 @@
{
return tmp_table_field_from_field_type(table, 0);
}
+ bool result_as_longlong() { return TRUE; }
+ longlong val_int();
bool check_partition_func_processor(byte *bool_arg) { return 0;}
};
--- 1.220/sql/opt_range.cc 2006-06-13 23:33:08 +04:00
+++ 1.221/sql/opt_range.cc 2006-06-18 14:20:27 +04:00
@@ -107,7 +107,7 @@
uint8 min_flag, uint8 max_flag, uint8 maybe_flag);
SEL_ARG(enum Type type_arg)
:elements(1),use_count(1),left(0),next_key_part(0),color(BLACK),
- type(type_arg)
+ type(type_arg),min_flag(0)
{}
inline bool is_same(SEL_ARG *arg)
{
--- 1.51/sql/opt_sum.cc 2006-06-04 19:52:12 +04:00
+++ 1.52/sql/opt_sum.cc 2006-06-18 14:20:27 +04:00
@@ -651,7 +651,8 @@
}
else
{
- store_val_in_field(part->field, args[between && max_fl ? 2 : 1]);
+ store_val_in_field(part->field, args[between && max_fl ? 2 : 1],
+ CHECK_FIELD_IGNORE);
if (part->null_bit)
*key_ptr++= (byte) test(part->field->is_null());
part->field->get_key_image((char*) key_ptr, part->length, Field::itRAW);
@@ -706,6 +707,8 @@
field BETWEEN const1 AND const2
3. all references to the columns from the same table as column field
occur only in conjucts mentioned above.
+ 4. each of k first components the index is not partial, i.e. is not
+ defined on a fixed length proper prefix of the field.
If such an index exists the function through the ref parameter
returns the key value to find max/min for the field using the index,
@@ -715,8 +718,8 @@
of the whole search key)
NOTE
- This function may set table->key_read to 1, which must be reset after
- index is used! (This can only happen when function returns 1)
+ This function may set table->key_read to 1, which must be reset after
+ index is used! (This can only happen when function returns 1)
RETURN
0 Index can not be used to optimize MIN(field)/MAX(field)
@@ -749,6 +752,12 @@
{
if (!(table->file->index_flags(idx, jdx, 0) & HA_READ_ORDER))
return 0;
+
+ /* Check whether the index component is partial */
+ Field *part_field= table->field[part->fieldnr-1];
+ if ((part_field->flags & BLOB_FLAG) ||
+ part->length < part_field->key_length())
+ break;
if (field->eq(part->field))
{
--- 1.327/sql/sql_base.cc 2006-06-13 01:40:58 +04:00
+++ 1.328/sql/sql_base.cc 2006-06-18 14:20:27 +04:00
@@ -5084,10 +5084,6 @@
if (from_clause->elements == 0)
return FALSE; /* We come here in the case of UNIONs. */
- /* For stored procedures do not redo work if already done. */
- if (!context->select_lex->first_execution)
- return FALSE;
-
List_iterator_fast<TABLE_LIST> table_ref_it(*from_clause);
TABLE_LIST *table_ref; /* Current table reference. */
/* Table reference to the left of the current. */
@@ -5100,14 +5096,18 @@
{
table_ref= left_neighbor;
left_neighbor= table_ref_it++;
- if (store_top_level_join_columns(thd, table_ref,
- left_neighbor, right_neighbor))
- return TRUE;
- if (left_neighbor)
+ /* For stored procedures do not redo work if already done. */
+ if (context->select_lex->first_execution)
{
- TABLE_LIST *first_leaf_on_the_right;
- first_leaf_on_the_right= table_ref->first_leaf_for_name_resolution();
- left_neighbor->next_name_resolution_table= first_leaf_on_the_right;
+ if (store_top_level_join_columns(thd, table_ref,
+ left_neighbor, right_neighbor))
+ return TRUE;
+ if (left_neighbor)
+ {
+ TABLE_LIST *first_leaf_on_the_right;
+ first_leaf_on_the_right= table_ref->first_leaf_for_name_resolution();
+ left_neighbor->next_name_resolution_table= first_leaf_on_the_right;
+ }
}
right_neighbor= table_ref;
}
--- 1.265/sql/sql_class.cc 2006-06-06 03:47:26 +04:00
+++ 1.266/sql/sql_class.cc 2006-06-18 14:20:28 +04:00
@@ -2121,7 +2121,9 @@
backup->enable_slow_log= enable_slow_log;
backup->last_insert_id= last_insert_id;
backup->next_insert_id= next_insert_id;
+ backup->current_insert_id= current_insert_id;
backup->insert_id_used= insert_id_used;
+ backup->last_insert_id_used= last_insert_id_used;
backup->clear_next_insert_id= clear_next_insert_id;
backup->limit_found_rows= limit_found_rows;
backup->examined_row_count= examined_row_count;
@@ -2171,7 +2173,9 @@
enable_slow_log= backup->enable_slow_log;
last_insert_id= backup->last_insert_id;
next_insert_id= backup->next_insert_id;
+ current_insert_id= backup->current_insert_id;
insert_id_used= backup->insert_id_used;
+ last_insert_id_used= backup->last_insert_id_used;
clear_next_insert_id= backup->clear_next_insert_id;
limit_found_rows= backup->limit_found_rows;
sent_row_count= backup->sent_row_count;
--- 1.297/sql/sql_class.h 2006-06-13 18:44:02 +04:00
+++ 1.298/sql/sql_class.h 2006-06-18 14:20:28 +04:00
@@ -763,12 +763,13 @@
{
public:
ulonglong options;
- ulonglong last_insert_id, next_insert_id;
+ ulonglong last_insert_id, next_insert_id, current_insert_id;
ulonglong limit_found_rows;
ha_rows cuted_fields, sent_row_count, examined_row_count;
ulong client_capabilities;
uint in_sub_stmt;
bool enable_slow_log, insert_id_used, clear_next_insert_id;
+ bool last_insert_id_used;
my_bool no_send_ok;
SAVEPOINT *savepoints;
};
--- 1.203/sql/sql_insert.cc 2006-06-09 18:09:35 +04:00
+++ 1.204/sql/sql_insert.cc 2006-06-18 14:20:28 +04:00
@@ -2009,6 +2009,14 @@
if (!using_bin_log)
table->file->extra(HA_EXTRA_WRITE_CACHE);
pthread_mutex_lock(&mutex);
+
+ /* Reset auto-increment cacheing */
+ if (thd.clear_next_insert_id)
+ {
+ thd.next_insert_id= 0;
+ thd.clear_next_insert_id= 0;
+ }
+
while ((row=rows.get()))
{
stacked_inserts--;
--- 1.232/sql/sql_lex.h 2006-05-30 15:24:26 +04:00
+++ 1.233/sql/sql_lex.h 2006-06-18 14:20:28 +04:00
@@ -1120,6 +1120,8 @@
case SQLCOM_UPDATE_MULTI:
case SQLCOM_INSERT:
case SQLCOM_INSERT_SELECT:
+ case SQLCOM_REPLACE:
+ case SQLCOM_REPLACE_SELECT:
case SQLCOM_LOAD:
return TRUE;
default:
--- 1.412/sql/sql_select.cc 2006-06-09 20:38:51 +04:00
+++ 1.413/sql/sql_select.cc 2006-06-18 14:20:28 +04:00
@@ -4823,7 +4823,7 @@
*/
bool
-store_val_in_field(Field *field,Item *item)
+store_val_in_field(Field *field, Item *item, enum_check_fields check_flag)
{
bool error;
TABLE *table= field->table;
@@ -4838,7 +4838,7 @@
with select_insert, which make count_cuted_fields= 1
*/
enum_check_fields old_count_cuted_fields= thd->count_cuted_fields;
- thd->count_cuted_fields= CHECK_FIELD_WARN;
+ thd->count_cuted_fields= check_flag;
error= item->save_in_field(field, 1);
thd->count_cuted_fields= old_count_cuted_fields;
dbug_tmp_restore_column_map(table->write_set, old_map);
@@ -11031,7 +11031,7 @@
field->real_type() != MYSQL_TYPE_VARCHAR &&
(field->type() != FIELD_TYPE_FLOAT || field->decimals() == 0))
{
- return !store_val_in_field(field,right_item);
+ return !store_val_in_field(field, right_item, CHECK_FIELD_WARN);
}
}
}
--- 1.107/sql/sql_select.h 2006-06-04 19:52:15 +04:00
+++ 1.108/sql/sql_select.h 2006-06-18 14:20:28 +04:00
@@ -406,7 +406,7 @@
void TEST_join(JOIN *join);
/* Extern functions in sql_select.cc */
-bool store_val_in_field(Field *field,Item *val);
+bool store_val_in_field(Field *field, Item *val, enum_check_fields check_flag);
TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
ORDER *group, bool distinct, bool save_sum_fields,
ulonglong select_options, ha_rows rows_limit,
--- 1.481/sql/sql_yacc.yy 2006-06-14 16:41:07 +04:00
+++ 1.482/sql/sql_yacc.yy 2006-06-18 14:20:29 +04:00
@@ -10635,6 +10635,8 @@
yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
+ /* This counter shouldn't be incremented for UNION parts */
+ Lex->nest_level--;
if (mysql_new_select(lex, 0))
YYABORT;
mysql_init_select(lex);
--- 1.60/sql/structs.h 2006-05-22 14:05:11 +04:00
+++ 1.61/sql/structs.h 2006-06-18 14:20:29 +04:00
@@ -54,7 +54,13 @@
Field *field;
uint offset; /* offset in record (from 0) */
uint null_offset; /* Offset to null_bit in record */
- uint16 length; /* Length of key_part */
+ uint16 length; /* Length of keypart value in bytes */
+ /*
+ Number of bytes required to store the keypart value. This may be
+ different from the "length" field as it also counts
+ - possible NULL-flag byte (see HA_KEY_NULL_LENGTH)
+ - possible HA_KEY_BLOB_LENGTH bytes needed to store actual value length.
+ */
uint16 store_length;
uint16 key_type;
uint16 fieldnr; /* Fieldnum in UNIREG */
--- 1.83/mysql-test/r/union.result 2006-03-08 00:06:47 +03:00
+++ 1.84/mysql-test/r/union.result 2006-06-18 14:20:26 +04:00
@@ -1306,3 +1306,48 @@
5
99
drop table t1;
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1)) union
+(select avg(1)) union (select avg(1)) union (select avg(1));
+avg(1)
+NULL
--- 1.89/mysql-test/r/ctype_utf8.result 2006-05-09 19:13:26 +04:00
+++ 1.90/mysql-test/r/ctype_utf8.result 2006-06-18 14:20:26 +04:00
@@ -1112,6 +1112,46 @@
Table Op Msg_type Msg_text
test.t1 check status OK
drop table t1;
+SET NAMES utf8;
+CREATE TABLE t1 (id int PRIMARY KEY,
+a varchar(16) collate utf8_unicode_ci NOT NULL default '',
+b int,
+f varchar(128) default 'XXX',
+INDEX (a(4))
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+INSERT INTO t1(id, a, b) VALUES
+(1, 'cccc', 50), (2, 'cccc', 70), (3, 'cccc', 30),
+(4, 'cccc', 30), (5, 'cccc', 20), (6, 'bbbbbb', 40),
+(7, 'dddd', 30), (8, 'aaaa', 10), (9, 'aaaa', 50),
+(10, 'eeeee', 40), (11, 'bbbbbb', 60);
+SELECT id, a, b FROM t1;
+id a b
+1 cccc 50
+2 cccc 70
+3 cccc 30
+4 cccc 30
+5 cccc 20
+6 bbbbbb 40
+7 dddd 30
+8 aaaa 10
+9 aaaa 50
+10 eeeee 40
+11 bbbbbb 60
+SELECT id, a, b FROM t1 WHERE a BETWEEN 'aaaa' AND 'bbbbbb';
+id a b
+8 aaaa 10
+9 aaaa 50
+6 bbbbbb 40
+11 bbbbbb 60
+SELECT id, a FROM t1 WHERE a='bbbbbb';
+id a
+6 bbbbbb
+11 bbbbbb
+SELECT id, a FROM t1 WHERE a='bbbbbb' ORDER BY b;
+id a
+6 bbbbbb
+11 bbbbbb
+DROP TABLE t1;
CREATE TABLE t1(id varchar(20) NOT NULL) DEFAULT CHARSET=utf8;
INSERT INTO t1 VALUES ('xxx'), ('aa'), ('yyy'), ('aa');
SELECT id FROM t1;
--- 1.21/mysql-test/r/archive.result 2006-05-15 21:31:03 +04:00
+++ 1.22/mysql-test/r/archive.result 2006-06-18 14:20:26 +04:00
@@ -6254,6 +6254,7 @@
3 011402 37 Romans scholastics jarring
4 011403 37 intercepted audiology tinily
DELETE FROM t2;
+ERROR HY000: Table storage engine for 't2' doesn't have this option
SELECT * FROM t2;
auto fld1 companynr fld3 fld4 fld5 fld6
1 000001 00 Omaha teethe neat
@@ -8685,6 +8686,7 @@
3 011402 37 Romans scholastics jarring
4 011403 37 intercepted audiology tinily
TRUNCATE TABLE t2;
+ERROR HY000: Table storage engine for 't2' doesn't have this option
SELECT * FROM t2;
auto fld1 companynr fld3 fld4 fld5 fld6
1 000001 00 Omaha teethe neat
--- 1.21/mysql-test/t/archive.test 2006-05-15 21:31:04 +04:00
+++ 1.22/mysql-test/t/archive.test 2006-06-18 14:20:26 +04:00
@@ -1330,12 +1330,14 @@
#
# For bug #12836
# Delete was allowing all rows to be removed
+--error 1031
DELETE FROM t2;
SELECT * FROM t2;
INSERT INTO t2 VALUES (2,011401,37,'breaking','dreaded','Steinberg','W');
INSERT INTO t2 VALUES (3,011402,37,'Romans','scholastics','jarring','');
INSERT INTO t2 VALUES (4,011403,37,'intercepted','audiology','tinily','');
SELECT * FROM t2;
+--error 1031
TRUNCATE TABLE t2;
SELECT * FROM t2;
--- 1.60.1.10/sql/ha_archive.cc 2006-06-17 03:35:06 +04:00
+++ 1.98/storage/archive/ha_archive.cc 2006-06-18 14:20:29 +04:00
@@ -19,11 +19,13 @@
#endif
#include "mysql_priv.h"
+#include <myisam.h>
-#if defined(HAVE_ARCHIVE_DB)
#include "ha_archive.h"
#include <my_dir.h>
+#include <mysql/plugin.h>
+
/*
First, if you want to understand storage engines you should look at
ha_example.cc and ha_example.h.
@@ -31,13 +33,13 @@
a storage engine without indexes that could compress data very well.
So, welcome to a completely compressed storage engine. This storage
engine only does inserts. No replace, deletes, or updates. All reads are
- complete table scans. Compression is done through gzip (bzip compresses
+ complete table scans. Compression is done through azip (bzip compresses
better, but only marginally, if someone asks I could add support for
- it too, but beaware that it costs a lot more in CPU time then gzip).
+ it too, but beaware that it costs a lot more in CPU time then azip).
We keep a file pointer open for each instance of ha_archive for each read
but for writes we keep one open file handle just for that. We flush it
- only if we have a read occur. gzip handles compressing lots of records
+ only if we have a read occur. azip handles compressing lots of records
at once much better then doing lots of little records between writes.
It is possible to not lock on writes but this would then mean we couldn't
handle bulk inserts as well (that is if someone was trying to read at
@@ -64,8 +66,7 @@
pool. For MyISAM its a question of how much the file system caches the
MyISAM file. With enough free memory MyISAM is faster. Its only when the OS
doesn't have enough memory to cache entire table that archive turns out
- to be any faster. For writes it is always a bit slower then MyISAM. It has no
- internal limits though for row length.
+ to be any faster.
Examples between MyISAM (packed) and Archive.
@@ -82,11 +83,8 @@
TODO:
Add bzip optional support.
Allow users to set compression level.
- Add truncate table command.
Implement versioning, should be easy.
Allow for errors, find a way to mark bad rows.
- Talk to the gzip guys, come up with a writable format so that updates are doable
- without switching to a block method.
Add optional feature so that rows can be flushed at interval (which will cause less
compression but may speed up ordered searches).
Checkpoint the meta file to allow for faster rebuilds.
@@ -105,6 +103,7 @@
rows - This is an unsigned long long which is the number of rows in the data
file.
check point - Reserved for future use
+ auto increment - MAX value for autoincrement
dirty - Status of the file, whether or not its values are the latest. This
flag is what causes a repair to occur
@@ -126,47 +125,32 @@
#define ARN ".ARN" // Files used during an optimize call
#define ARM ".ARM" // Meta file
/*
- uchar + uchar + ulonglong + ulonglong + uchar
+ uchar + uchar + ulonglong + ulonglong + ulonglong + ulonglong + FN_REFLEN
+ + uchar
*/
-#define META_BUFFER_SIZE 19 // Size of the data used in the meta file
+#define META_BUFFER_SIZE sizeof(uchar) + sizeof(uchar) + sizeof(ulonglong) \
+ + sizeof(ulonglong) + sizeof(ulonglong) + sizeof(ulonglong) + FN_REFLEN \
+ + sizeof(uchar)
+
/*
uchar + uchar
*/
#define DATA_BUFFER_SIZE 2 // Size of the data used in the data file
#define ARCHIVE_CHECK_HEADER 254 // The number we use to determine corruption
-/*
+/* Static declarations for handerton */
+static handler *archive_create_handler(TABLE_SHARE *table, MEM_ROOT *mem_root);
+/*
Number of rows that will force a bulk insert.
*/
#define ARCHIVE_MIN_ROWS_TO_USE_BULK_INSERT 2
+handlerton archive_hton;
-
-/* dummy handlerton - only to have something to return from archive_db_init */
-handlerton archive_hton = {
- "ARCHIVE",
- SHOW_OPTION_YES,
- "Archive storage engine",
- DB_TYPE_ARCHIVE_DB,
- archive_db_init,
- 0, /* slot */
- 0, /* savepoint size. */
- NULL, /* close_connection */
- NULL, /* savepoint */
- NULL, /* rollback to savepoint */
- NULL, /* releas savepoint */
- NULL, /* commit */
- NULL, /* rollback */
- NULL, /* prepare */
- NULL, /* recover */
- NULL, /* commit_by_xid */
- NULL, /* rollback_by_xid */
- NULL, /* create_cursor_read_view */
- NULL, /* set_cursor_read_view */
- NULL, /* close_cursor_read_view */
- HTON_NO_FLAGS
-};
-
+static handler *archive_create_handler(TABLE_SHARE *table, MEM_ROOT *mem_root)
+{
+ return new (mem_root) ha_archive(table);
+}
/*
Used for hash table that tracks open tables.
@@ -191,9 +175,18 @@
TRUE Error
*/
-bool archive_db_init()
+int archive_db_init()
{
DBUG_ENTER("archive_db_init");
+ if (archive_inited)
+ DBUG_RETURN(FALSE);
+
+ archive_hton.state=SHOW_OPTION_YES;
+ archive_hton.db_type=DB_TYPE_ARCHIVE_DB;
+ archive_hton.create=archive_create_handler;
+ archive_hton.panic=archive_db_end;
+ archive_hton.flags=HTON_NO_FLAGS;
+
if (pthread_mutex_init(&archive_mutex, MY_MUTEX_INIT_FAST))
goto error;
if (hash_init(&archive_open_tables, system_charset_info, 32, 0, 0,
@@ -207,7 +200,6 @@
DBUG_RETURN(FALSE);
}
error:
- have_archive_db= SHOW_OPTION_DISABLED; // If we couldn't use handler
DBUG_RETURN(TRUE);
}
@@ -215,14 +207,14 @@
Release the archive handler.
SYNOPSIS
- archive_db_end()
+ archive_db_done()
void
RETURN
FALSE OK
*/
-bool archive_db_end()
+int archive_db_done()
{
if (archive_inited)
{
@@ -230,32 +222,37 @@
VOID(pthread_mutex_destroy(&archive_mutex));
}
archive_inited= 0;
- return FALSE;
+ return 0;
+}
+
+
+int archive_db_end(ha_panic_function type)
+{
+ return archive_db_done();
}
-ha_archive::ha_archive(TABLE *table_arg)
+ha_archive::ha_archive(TABLE_SHARE *table_arg)
:handler(&archive_hton, table_arg), delayed_insert(0), bulk_insert(0)
{
/* Set our original buffer from pre-allocated memory */
buffer.set((char *)byte_buffer, IO_SIZE, system_charset_info);
/* The size of the offset value we will use for position() */
- ref_length = 2 << ((zlibCompileFlags() >> 6) & 3);
- DBUG_ASSERT(ref_length <= sizeof(z_off_t));
+ ref_length = sizeof(my_off_t);
}
/*
This method reads the header of a datafile and returns whether or not it was successful.
*/
-int ha_archive::read_data_header(gzFile file_to_read)
+int ha_archive::read_data_header(azio_stream *file_to_read)
{
uchar data_buffer[DATA_BUFFER_SIZE];
DBUG_ENTER("ha_archive::read_data_header");
- if (gzrewind(file_to_read) == -1)
+ if (azrewind(file_to_read) == -1)
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
- if (gzread(file_to_read, data_buffer, DATA_BUFFER_SIZE) != DATA_BUFFER_SIZE)
+ if (azread(file_to_read, data_buffer, DATA_BUFFER_SIZE) != DATA_BUFFER_SIZE)
DBUG_RETURN(errno ? errno : -1);
DBUG_PRINT("ha_archive::read_data_header", ("Check %u", data_buffer[0]));
@@ -271,7 +268,7 @@
/*
This method writes out the header of a datafile and returns whether or not it was successful.
*/
-int ha_archive::write_data_header(gzFile file_to_write)
+int ha_archive::write_data_header(azio_stream *file_to_write)
{
uchar data_buffer[DATA_BUFFER_SIZE];
DBUG_ENTER("ha_archive::write_data_header");
@@ -279,7 +276,7 @@
data_buffer[0]= (uchar)ARCHIVE_CHECK_HEADER;
data_buffer[1]= (uchar)ARCHIVE_VERSION;
- if (gzwrite(file_to_write, &data_buffer, DATA_BUFFER_SIZE) !=
+ if (azwrite(file_to_write, &data_buffer, DATA_BUFFER_SIZE) !=
DATA_BUFFER_SIZE)
goto error;
DBUG_PRINT("ha_archive::write_data_header", ("Check %u", (uint)data_buffer[0]));
@@ -294,9 +291,13 @@
This method reads the header of a meta file and returns whether or not it was successful.
*rows will contain the current number of rows in the data file upon success.
*/
-int ha_archive::read_meta_file(File meta_file, ha_rows *rows)
+int ha_archive::read_meta_file(File meta_file, ha_rows *rows,
+ ulonglong *auto_increment,
+ ulonglong *forced_flushes,
+ char *real_path)
{
uchar meta_buffer[META_BUFFER_SIZE];
+ uchar *ptr= meta_buffer;
ulonglong check_point;
DBUG_ENTER("ha_archive::read_meta_file");
@@ -308,17 +309,30 @@
/*
Parse out the meta data, we ignore version at the moment
*/
- *rows= (ha_rows)uint8korr(meta_buffer + 2);
- check_point= uint8korr(meta_buffer + 10);
+
+ ptr+= sizeof(uchar)*2; // Move past header
+ *rows= (ha_rows)uint8korr(ptr);
+ ptr+= sizeof(ulonglong); // Move past rows
+ check_point= uint8korr(ptr);
+ ptr+= sizeof(ulonglong); // Move past check_point
+ *auto_increment= uint8korr(ptr);
+ ptr+= sizeof(ulonglong); // Move past auto_increment
+ *forced_flushes= uint8korr(ptr);
+ ptr+= sizeof(ulonglong); // Move past forced_flush
+ memmove(real_path, ptr, FN_REFLEN);
+ ptr+= FN_REFLEN; // Move past the possible location of the file
DBUG_PRINT("ha_archive::read_meta_file", ("Check %d", (uint)meta_buffer[0]));
DBUG_PRINT("ha_archive::read_meta_file", ("Version %d", (uint)meta_buffer[1]));
- DBUG_PRINT("ha_archive::read_meta_file", ("Rows %lld", *rows));
- DBUG_PRINT("ha_archive::read_meta_file", ("Checkpoint %lld", check_point));
- DBUG_PRINT("ha_archive::read_meta_file", ("Dirty %d", (int)meta_buffer[18]));
+ DBUG_PRINT("ha_archive::read_meta_file", ("Rows %llu", *rows));
+ DBUG_PRINT("ha_archive::read_meta_file", ("Checkpoint %llu", check_point));
+ DBUG_PRINT("ha_archive::read_meta_file", ("Auto-Increment %llu", *auto_increment));
+ DBUG_PRINT("ha_archive::read_meta_file", ("Forced Flushes %llu", *forced_flushes));
+ DBUG_PRINT("ha_archive::read_meta_file", ("Real Path %s", real_path));
+ DBUG_PRINT("ha_archive::read_meta_file", ("Dirty %d", (int)(*ptr)));
if ((meta_buffer[0] != (uchar)ARCHIVE_CHECK_HEADER) ||
- ((bool)meta_buffer[18] == TRUE))
+ ((bool)(*ptr)== TRUE))
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
my_sync(meta_file, MYF(MY_WME));
@@ -331,22 +345,49 @@
By setting dirty you say whether or not the file represents the actual state of the data file.
Upon ::open() we set to dirty, and upon ::close() we set to clean.
*/
-int ha_archive::write_meta_file(File meta_file, ha_rows rows, bool dirty)
+int ha_archive::write_meta_file(File meta_file, ha_rows rows,
+ ulonglong auto_increment,
+ ulonglong forced_flushes,
+ char *real_path,
+ bool dirty)
{
uchar meta_buffer[META_BUFFER_SIZE];
+ uchar *ptr= meta_buffer;
ulonglong check_point= 0; //Reserved for the future
DBUG_ENTER("ha_archive::write_meta_file");
- meta_buffer[0]= (uchar)ARCHIVE_CHECK_HEADER;
- meta_buffer[1]= (uchar)ARCHIVE_VERSION;
- int8store(meta_buffer + 2, (ulonglong)rows);
- int8store(meta_buffer + 10, check_point);
- *(meta_buffer + 18)= (uchar)dirty;
- DBUG_PRINT("ha_archive::write_meta_file", ("Check %d", (uint)ARCHIVE_CHECK_HEADER));
- DBUG_PRINT("ha_archive::write_meta_file", ("Version %d", (uint)ARCHIVE_VERSION));
+ *ptr= (uchar)ARCHIVE_CHECK_HEADER;
+ ptr += sizeof(uchar);
+ *ptr= (uchar)ARCHIVE_VERSION;
+ ptr += sizeof(uchar);
+ int8store(ptr, (ulonglong)rows);
+ ptr += sizeof(ulonglong);
+ int8store(ptr, check_point);
+ ptr += sizeof(ulonglong);
+ int8store(ptr, auto_increment);
+ ptr += sizeof(ulonglong);
+ int8store(ptr, forced_flushes);
+ ptr += sizeof(ulonglong);
+ // No matter what, we pad with nulls
+ if (real_path)
+ strncpy((char *)ptr, real_path, FN_REFLEN);
+ else
+ bzero(ptr, FN_REFLEN);
+ ptr += FN_REFLEN;
+ *ptr= (uchar)dirty;
+ DBUG_PRINT("ha_archive::write_meta_file", ("Check %d",
+ (uint)ARCHIVE_CHECK_HEADER));
+ DBUG_PRINT("ha_archive::write_meta_file", ("Version %d",
+ (uint)ARCHIVE_VERSION));
DBUG_PRINT("ha_archive::write_meta_file", ("Rows %llu", (ulonglong)rows));
DBUG_PRINT("ha_archive::write_meta_file", ("Checkpoint %llu", check_point));
+ DBUG_PRINT("ha_archive::write_meta_file", ("Auto Increment %llu",
+ auto_increment));
+ DBUG_PRINT("ha_archive::write_meta_file", ("Forced Flushes %llu",
+ forced_flushes));
+ DBUG_PRINT("ha_archive::write_meta_file", ("Real path %s",
+ real_path));
DBUG_PRINT("ha_archive::write_meta_file", ("Dirty %d", (uint)dirty));
VOID(my_seek(meta_file, 0, MY_SEEK_SET, MYF(0)));
@@ -397,8 +438,10 @@
share->table_name= tmp_name;
share->crashed= FALSE;
share->archive_write_open= FALSE;
- fn_format(share->data_file_name,table_name,"",ARZ,MY_REPLACE_EXT|MY_UNPACK_FILENAME);
- fn_format(meta_file_name,table_name,"",ARM,MY_REPLACE_EXT|MY_UNPACK_FILENAME);
+ fn_format(share->data_file_name, table_name, "",
+ ARZ,MY_REPLACE_EXT|MY_UNPACK_FILENAME);
+ fn_format(meta_file_name, table_name, "", ARM,
+ MY_REPLACE_EXT|MY_UNPACK_FILENAME);
strmov(share->table_name,table_name);
/*
We will use this lock for rows.
@@ -406,15 +449,24 @@
VOID(pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST));
if ((share->meta_file= my_open(meta_file_name, O_RDWR, MYF(0))) == -1)
share->crashed= TRUE;
+ DBUG_PRINT("info", ("archive opening (1) up write at %s",
+ share->data_file_name));
/*
- After we read, we set the file to dirty. When we close, we will do the
- opposite. If the meta file will not open we assume it is crashed and
- leave it up to the user to fix.
+ We read the meta file, but do not mark it dirty unless we actually do
+ a write.
*/
- if (read_meta_file(share->meta_file, &share->rows_recorded))
+ if (read_meta_file(share->meta_file, &share->rows_recorded,
+ &share->auto_increment_value,
+ &share->forced_flushes,
+ share->real_path))
share->crashed= TRUE;
-
+ /*
+ Since we now possibly no real_path, we will use it instead if it exists.
+ */
+ if (*share->real_path)
+ fn_format(share->data_file_name, share->real_path, "", ARZ,
+ MY_REPLACE_EXT|MY_UNPACK_FILENAME);
VOID(my_hash_insert(&archive_open_tables, (byte*) share));
thr_lock_init(&share->lock);
}
@@ -448,12 +500,21 @@
hash_delete(&archive_open_tables, (byte*) share);
thr_lock_delete(&share->lock);
VOID(pthread_mutex_destroy(&share->mutex));
- if (share->crashed)
- (void)write_meta_file(share->meta_file, share->rows_recorded, TRUE);
- else
- (void)write_meta_file(share->meta_file, share->rows_recorded, FALSE);
+ /*
+ We need to make sure we don't reset the crashed state.
+ If we open a crashed file, wee need to close it as crashed unless
+ it has been repaired.
+ Since we will close the data down after this, we go on and count
+ the flush on close;
+ */
+ share->forced_flushes++;
+ (void)write_meta_file(share->meta_file, share->rows_recorded,
+ share->auto_increment_value,
+ share->forced_flushes,
+ share->real_path,
+ share->crashed ? TRUE :FALSE);
if (share->archive_write_open)
- if (gzclose(share->archive_write) == Z_ERRNO)
+ if (azclose(&(share->archive_write)))
rc= 1;
if (my_close(share->meta_file, MYF(0)))
rc= 1;
@@ -467,15 +528,21 @@
int ha_archive::init_archive_writer()
{
DBUG_ENTER("ha_archive::init_archive_writer");
- (void)write_meta_file(share->meta_file, share->rows_recorded, TRUE);
+ (void)write_meta_file(share->meta_file, share->rows_recorded,
+ share->auto_increment_value,
+ share->forced_flushes,
+ share->real_path,
+ TRUE);
/*
It is expensive to open and close the data files and since you can't have
a gzip file that can be both read and written we keep a writer open
that is shared amoung all open tables.
*/
- if ((share->archive_write= gzopen(share->data_file_name, "ab")) == NULL)
+ if (!(azopen(&(share->archive_write), share->data_file_name,
+ O_WRONLY|O_APPEND|O_BINARY)))
{
+ DBUG_PRINT("info", ("Could not open archive write file"));
share->crashed= TRUE;
DBUG_RETURN(1);
}
@@ -511,7 +578,7 @@
int rc= 0;
DBUG_ENTER("ha_archive::open");
- DBUG_PRINT("info", ("archive table was opened for crash %s",
+ DBUG_PRINT("info", ("archive table was opened for crash: %s",
(open_options & HA_OPEN_FOR_REPAIR) ? "yes" : "no"));
share= get_share(name, table, &rc);
@@ -527,7 +594,8 @@
thr_lock_data_init(&share->lock,&lock,NULL);
- if ((archive= gzopen(share->data_file_name, "rb")) == NULL)
+ DBUG_PRINT("info", ("archive data_file_name %s", share->data_file_name));
+ if (!(azopen(&archive, share->data_file_name, O_RDONLY|O_BINARY)))
{
if (errno == EROFS || errno == EACCES)
DBUG_RETURN(my_errno= errno);
@@ -568,7 +636,7 @@
DBUG_ENTER("ha_archive::close");
/* First close stream */
- if (gzclose(archive) == Z_ERRNO)
+ if (azclose(&archive))
rc= 1;
/* then also close share */
rc|= free_share(share);
@@ -594,6 +662,29 @@
int error;
DBUG_ENTER("ha_archive::create");
+ stats.auto_increment_value= (create_info->auto_increment_value ?
+ create_info->auto_increment_value -1 :
+ (ulonglong) 0);
+
+ for (uint key= 0; key < table_arg->s->keys; key++)
+ {
+ KEY *pos= table_arg->key_info+key;
+ KEY_PART_INFO *key_part= pos->key_part;
+ KEY_PART_INFO *key_part_end= key_part + pos->key_parts;
+
+ for (; key_part != key_part_end; key_part++)
+ {
+ Field *field= key_part->field;
+
+ if (!(field->flags & AUTO_INCREMENT_FLAG))
+ {
+ error= -1;
+ DBUG_PRINT("info", ("Index error in creating archive table"));
+ goto error;
+ }
+ }
+ }
+
if ((create_file= my_create(fn_format(name_buff,name,"",ARM,
MY_REPLACE_EXT|MY_UNPACK_FILENAME),0,
O_RDWR | O_TRUNC,MYF(MY_WME))) < 0)
@@ -601,43 +692,64 @@
error= my_errno;
goto error;
}
- write_meta_file(create_file, 0, FALSE);
+
+ write_meta_file(create_file, 0, stats.auto_increment_value, 0,
+ (char *)create_info->data_file_name,
+ FALSE);
my_close(create_file,MYF(0));
/*
We reuse name_buff since it is available.
*/
- if ((create_file= my_create(fn_format(name_buff,name,"",ARZ,
- MY_REPLACE_EXT|MY_UNPACK_FILENAME),0,
- O_RDWR | O_TRUNC,MYF(MY_WME))) < 0)
+ if (create_info->data_file_name)
{
- error= my_errno;
- goto error;
+ char linkname[FN_REFLEN];
+ DBUG_PRINT("info", ("archive will create stream file %s",
+ create_info->data_file_name));
+
+ fn_format(name_buff, create_info->data_file_name, "", ARZ,
+ MY_REPLACE_EXT|MY_UNPACK_FILENAME);
+ fn_format(linkname, name, "", ARZ,
+ MY_UNPACK_FILENAME | MY_APPEND_EXT);
+ if ((create_file= my_create_with_symlink(linkname, name_buff, 0,
+ O_RDWR | O_TRUNC,MYF(MY_WME))) < 0)
+ {
+ error= my_errno;
+ goto error;
+ }
+ }
+ else
+ {
+ if ((create_file= my_create(fn_format(name_buff, name,"", ARZ,
+ MY_REPLACE_EXT|MY_UNPACK_FILENAME),0,
+ O_RDWR | O_TRUNC,MYF(MY_WME))) < 0)
+ {
+ error= my_errno;
+ goto error;
+ }
}
- if ((archive= gzdopen(create_file, "wb")) == NULL)
+ if (!azdopen(&archive, create_file, O_WRONLY|O_BINARY))
{
error= errno;
goto error2;
}
- if (write_data_header(archive))
+ if (write_data_header(&archive))
{
error= errno;
goto error3;
}
- if (gzclose(archive))
+ if (azclose(&archive))
{
error= errno;
goto error2;
}
- my_close(create_file, MYF(0));
-
DBUG_RETURN(0);
error3:
- /* We already have an error, so ignore results of gzclose. */
- (void)gzclose(archive);
+ /* We already have an error, so ignore results of azclose. */
+ (void)azclose(&archive);
error2:
my_close(create_file, MYF(0));
delete_table(name);
@@ -649,18 +761,19 @@
/*
This is where the actual row is written out.
*/
-int ha_archive::real_write_row(byte *buf, gzFile writer)
+int ha_archive::real_write_row(byte *buf, azio_stream *writer)
{
- z_off_t written;
+ my_off_t written;
uint *ptr, *end;
DBUG_ENTER("ha_archive::real_write_row");
- written= gzwrite(writer, buf, table->s->reclength);
- DBUG_PRINT("ha_archive::real_write_row", ("Wrote %d bytes expected %d", written, table->s->reclength));
+ written= azwrite(writer, buf, table->s->reclength);
+ DBUG_PRINT("ha_archive::real_write_row", ("Wrote %d bytes expected %d",
+ written, table->s->reclength));
if (!delayed_insert || !bulk_insert)
share->dirty= TRUE;
- if (written != (z_off_t)table->s->reclength)
+ if (written != (my_off_t)table->s->reclength)
DBUG_RETURN(errno ? errno : -1);
/*
We should probably mark the table as damagaged if the record is written
@@ -676,8 +789,8 @@
if (size)
{
((Field_blob*) table->field[*ptr])->get_ptr(&data_ptr);
- written= gzwrite(writer, data_ptr, (unsigned)size);
- if (written != (z_off_t)size)
+ written= azwrite(writer, data_ptr, (unsigned)size);
+ if (written != (my_off_t)size)
DBUG_RETURN(errno ? errno : -1);
}
}
@@ -697,26 +810,206 @@
int ha_archive::write_row(byte *buf)
{
int rc;
+ byte *read_buf= NULL;
+ ulonglong temp_auto;
DBUG_ENTER("ha_archive::write_row");
if (share->crashed)
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
- statistic_increment(table->in_use->status_var.ha_write_count, &LOCK_status);
+ ha_statistic_increment(&SSV::ha_write_count);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
table->timestamp_field->set_time();
pthread_mutex_lock(&share->mutex);
+
+ if (table->next_number_field)
+ {
+ KEY *mkey= &table->s->key_info[0]; // We only support one key right now
+ update_auto_increment();
+ temp_auto= table->next_number_field->val_int();
+
+ /*
+ Bad news, this will cause a search for the unique value which is very
+ expensive since we will have to do a table scan which will lock up
+ all other writers during this period. This could perhaps be optimized
+ in the future.
+ */
+ if (temp_auto == share->auto_increment_value &&
+ mkey->flags & HA_NOSAME)
+ {
+ rc= HA_ERR_FOUND_DUPP_KEY;
+ goto error;
+ }
+
+ if (temp_auto < share->auto_increment_value &&
+ mkey->flags & HA_NOSAME)
+ {
+ /*
+ First we create a buffer that we can use for reading rows, and can pass
+ to get_row().
+ */
+ if (!(read_buf= (byte*) my_malloc(table->s->reclength, MYF(MY_WME))))
+ {
+ rc= HA_ERR_OUT_OF_MEM;
+ goto error;
+ }
+ /*
+ All of the buffer must be written out or we won't see all of the
+ data
+ */
+ azflush(&(share->archive_write), Z_SYNC_FLUSH);
+ share->forced_flushes++;
+ /*
+ Set the position of the local read thread to the beginning postion.
+ */
+ if (read_data_header(&archive))
+ {
+ rc= HA_ERR_CRASHED_ON_USAGE;
+ goto error;
+ }
+
+ /*
+ Now we read and check all of the rows.
+ if (!memcmp(table->next_number_field->ptr, mfield->ptr, mfield->max_length()))
+ if ((longlong)temp_auto ==
+ mfield->val_int((char*)(read_buf + mfield->offset())))
+ */
+ Field *mfield= table->next_number_field;
+
+ while (!(get_row(&archive, read_buf)))
+ {
+ if (!memcmp(read_buf + mfield->offset(), table->next_number_field->ptr,
+ mfield->max_length()))
+ {
+ rc= HA_ERR_FOUND_DUPP_KEY;
+ goto error;
+ }
+ }
+ }
+ else
+ {
+ if (temp_auto > share->auto_increment_value)
+ stats.auto_increment_value= share->auto_increment_value= temp_auto;
+ }
+ }
+
+ /*
+ Notice that the global auto_increment has been increased.
+ In case of a failed row write, we will never try to reuse the value.
+ */
if (!share->archive_write_open)
if (init_archive_writer())
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
share->rows_recorded++;
- rc= real_write_row(buf, share->archive_write);
+ rc= real_write_row(buf, &(share->archive_write));
+error:
pthread_mutex_unlock(&share->mutex);
+ if (read_buf)
+ my_free((gptr) read_buf, MYF(0));
DBUG_RETURN(rc);
}
+
+void ha_archive::get_auto_increment(ulonglong offset, ulonglong increment,
+ ulonglong nb_desired_values,
+ ulonglong *first_value,
+ ulonglong *nb_reserved_values)
+{
+ *nb_reserved_values= 1;
+ *first_value= share->auto_increment_value + 1;
+}
+
+/* Initialized at each key walk (called multiple times unlike rnd_init()) */
+int ha_archive::index_init(uint keynr, bool sorted)
+{
+ DBUG_ENTER("ha_archive::index_init");
+ active_index= keynr;
+ DBUG_RETURN(0);
+}
+
+
+/*
+ No indexes, so if we get a request for an index search since we tell
+ the optimizer that we have unique indexes, we scan
+*/
+int ha_archive::index_read(byte *buf, const byte *key,
+ uint key_len, enum ha_rkey_function find_flag)
+{
+ int rc;
+ DBUG_ENTER("ha_archive::index_read");
+ rc= index_read_idx(buf, active_index, key, key_len, find_flag);
+ DBUG_RETURN(rc);
+}
+
+
+int ha_archive::index_read_idx(byte *buf, uint index, const byte *key,
+ uint key_len, enum ha_rkey_function find_flag)
+{
+ int rc= 0;
+ bool found= 0;
+ KEY *mkey= &table->s->key_info[index];
+ current_k_offset= mkey->key_part->offset;
+ current_key= key;
+ current_key_len= key_len;
+
+
+ DBUG_ENTER("ha_archive::index_read_idx");
+
+ /*
+ All of the buffer must be written out or we won't see all of the
+ data
+ */
+ pthread_mutex_lock(&share->mutex);
+ azflush(&(share->archive_write), Z_SYNC_FLUSH);
+ share->forced_flushes++;
+ pthread_mutex_unlock(&share->mutex);
+
+ /*
+ Set the position of the local read thread to the beginning postion.
+ */
+ if (read_data_header(&archive))
+ {
+ rc= HA_ERR_CRASHED_ON_USAGE;
+ goto error;
+ }
+
+ while (!(get_row(&archive, buf)))
+ {
+ if (!memcmp(current_key, buf + current_k_offset, current_key_len))
+ {
+ found= 1;
+ break;
+ }
+ }
+
+ if (found)
+ DBUG_RETURN(0);
+
+error:
+ DBUG_RETURN(rc ? rc : HA_ERR_END_OF_FILE);
+}
+
+
+int ha_archive::index_next(byte * buf)
+{
+ bool found= 0;
+
+ DBUG_ENTER("ha_archive::index_next");
+
+ while (!(get_row(&archive, buf)))
+ {
+ if (!memcmp(current_key, buf+current_k_offset, current_key_len))
+ {
+ found= 1;
+ break;
+ }
+ }
+
+ DBUG_RETURN(found ? 0 : HA_ERR_END_OF_FILE);
+}
+
/*
All calls that need to scan the table start with this method. If we are told
that it is a table scan we rewind the file to the beginning, otherwise
@@ -735,11 +1028,11 @@
{
scan_rows= share->rows_recorded;
DBUG_PRINT("info", ("archive will retrieve %llu rows", scan_rows));
- records= 0;
+ stats.records= 0;
/*
If dirty, we lock, and then reset/flush the data.
- I found that just calling gzflush() doesn't always work.
+ I found that just calling azflush() doesn't always work.
*/
if (share->dirty == TRUE)
{
@@ -747,13 +1040,14 @@
if (share->dirty == TRUE)
{
DBUG_PRINT("info", ("archive flushing out rows for scan"));
- gzflush(share->archive_write, Z_SYNC_FLUSH);
+ azflush(&(share->archive_write), Z_SYNC_FLUSH);
+ share->forced_flushes++;
share->dirty= FALSE;
}
pthread_mutex_unlock(&share->mutex);
}
- if (read_data_header(archive))
+ if (read_data_header(&archive))
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
}
@@ -765,16 +1059,18 @@
This is the method that is used to read a row. It assumes that the row is
positioned where you want it.
*/
-int ha_archive::get_row(gzFile file_to_read, byte *buf)
+int ha_archive::get_row(azio_stream *file_to_read, byte *buf)
{
- int read; // Bytes read, gzread() returns int
+ int read; // Bytes read, azread() returns int
uint *ptr, *end;
char *last;
size_t total_blob_length= 0;
+ MY_BITMAP *read_set= table->read_set;
DBUG_ENTER("ha_archive::get_row");
- read= gzread(file_to_read, buf, table->s->reclength);
- DBUG_PRINT("ha_archive::get_row", ("Read %d bytes expected %d", read, table->s->reclength));
+ read= azread(file_to_read, buf, table->s->reclength);
+ DBUG_PRINT("ha_archive::get_row", ("Read %d bytes expected %d", read,
+ table->s->reclength));
if (read == Z_STREAM_ERROR)
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
@@ -794,7 +1090,11 @@
for (ptr= table->s->blob_field, end=ptr + table->s->blob_fields ;
ptr != end ;
ptr++)
- total_blob_length += ((Field_blob*) table->field[*ptr])->get_length();
+ {
+ if (bitmap_is_set(read_set,
+ (((Field_blob*) table->field[*ptr])->field_index)))
+ total_blob_length += ((Field_blob*) table->field[*ptr])->get_length();
+ }
/* Adjust our row buffer if we need be */
buffer.alloc(total_blob_length);
@@ -808,11 +1108,19 @@
size_t size= ((Field_blob*) table->field[*ptr])->get_length();
if (size)
{
- read= gzread(file_to_read, last, size);
- if ((size_t) read != size)
- DBUG_RETURN(HA_ERR_END_OF_FILE);
- ((Field_blob*) table->field[*ptr])->set_ptr(size, last);
- last += size;
+ if (bitmap_is_set(read_set,
+ ((Field_blob*) table->field[*ptr])->field_index))
+ {
+ read= azread(file_to_read, last, size);
+ if ((size_t) read != size)
+ DBUG_RETURN(HA_ERR_END_OF_FILE);
+ ((Field_blob*) table->field[*ptr])->set_ptr(size, last);
+ last += size;
+ }
+ else
+ {
+ (void)azseek(file_to_read, size, SEEK_CUR);
+ }
}
}
DBUG_RETURN(0);
@@ -836,14 +1144,13 @@
DBUG_RETURN(HA_ERR_END_OF_FILE);
scan_rows--;
- statistic_increment(table->in_use->status_var.ha_read_rnd_next_count,
- &LOCK_status);
- current_position= gztell(archive);
- rc= get_row(archive, buf);
+ ha_statistic_increment(&SSV::ha_read_rnd_next_count);
+ current_position= aztell(&archive);
+ rc= get_row(&archive, buf);
if (rc != HA_ERR_END_OF_FILE)
- records++;
+ stats.records++;
DBUG_RETURN(rc);
}
@@ -873,12 +1180,11 @@
int ha_archive::rnd_pos(byte * buf, byte *pos)
{
DBUG_ENTER("ha_archive::rnd_pos");
- statistic_increment(table->in_use->status_var.ha_read_rnd_next_count,
- &LOCK_status);
- current_position= (z_off_t)my_get_ptr(pos, ref_length);
- (void)gzseek(archive, current_position, SEEK_SET);
+ ha_statistic_increment(&SSV::ha_read_rnd_next_count);
+ current_position= (my_off_t)my_get_ptr(pos, ref_length);
+ (void)azseek(&archive, current_position, SEEK_SET);
- DBUG_RETURN(get_row(archive, buf));
+ DBUG_RETURN(get_row(&archive, buf));
}
/*
@@ -906,8 +1212,8 @@
int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
{
DBUG_ENTER("ha_archive::optimize");
- int rc;
- gzFile writer;
+ int rc= 0;
+ azio_stream writer;
char writer_filename[FN_REFLEN];
/* Open up the writer if we haven't yet */
@@ -915,13 +1221,14 @@
init_archive_writer();
/* Flush any waiting data */
- gzflush(share->archive_write, Z_SYNC_FLUSH);
+ azflush(&(share->archive_write), Z_SYNC_FLUSH);
+ share->forced_flushes++;
/* Lets create a file to contain the new data */
fn_format(writer_filename, share->table_name, "", ARN,
MY_REPLACE_EXT|MY_UNPACK_FILENAME);
- if ((writer= gzopen(writer_filename, "wb")) == NULL)
+ if (!(azopen(&writer, writer_filename, O_CREAT|O_WRONLY|O_TRUNC|O_BINARY)))
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
/*
@@ -931,6 +1238,7 @@
if (check_opt->flags == T_EXTEND)
{
+ DBUG_PRINT("info", ("archive extended rebuild"));
byte *buf;
/*
@@ -947,14 +1255,14 @@
Now we will rewind the archive file so that we are positioned at the
start of the file.
*/
- rc= read_data_header(archive);
+ rc= read_data_header(&archive);
/*
Assuming now error from rewinding the archive file, we now write out the
new header for out data file.
*/
if (!rc)
- rc= write_data_header(writer);
+ rc= write_data_header(&writer);
/*
On success of writing out the new header, we now fetch each row and
@@ -963,9 +1271,19 @@
if (!rc)
{
share->rows_recorded= 0;
- while (!(rc= get_row(archive, buf)))
+ stats.auto_increment_value= share->auto_increment_value= 0;
+ while (!(rc= get_row(&archive, buf)))
{
- real_write_row(buf, writer);
+ real_write_row(buf, &writer);
+ if (table->found_next_number_field)
+ {
+ Field *field= table->found_next_number_field;
+ ulonglong auto_value=
+ (ulonglong) field->val_int((char*)(buf + field->offset()));
+ if (share->auto_increment_value < auto_value)
+ stats.auto_increment_value= share->auto_increment_value=
+ auto_value;
+ }
share->rows_recorded++;
}
}
@@ -977,43 +1295,53 @@
}
else
{
+ DBUG_PRINT("info", ("archive quick rebuild"));
/*
The quick method is to just read the data raw, and then compress it directly.
*/
- int read; // Bytes read, gzread() returns int
+ int read; // Bytes read, azread() returns int
char block[IO_SIZE];
- if (gzrewind(archive) == -1)
+ if (azrewind(&archive) == -1)
{
rc= HA_ERR_CRASHED_ON_USAGE;
+ DBUG_PRINT("info", ("archive HA_ERR_CRASHED_ON_USAGE"));
goto error;
}
- while ((read= gzread(archive, block, IO_SIZE)))
- gzwrite(writer, block, read);
+ while ((read= azread(&archive, block, IO_SIZE)) > 0)
+ azwrite(&writer, block, read);
}
- gzflush(writer, Z_SYNC_FLUSH);
+ azclose(&writer);
share->dirty= FALSE;
- gzclose(share->archive_write);
- share->archive_write= writer;
+ share->forced_flushes= 0;
+
+ // now we close both our writer and our reader for the rename
+ azclose(&(share->archive_write));
+ azclose(&archive);
- my_rename(writer_filename,share->data_file_name,MYF(0));
+ // make the file we just wrote be our data file
+ rc = my_rename(writer_filename,share->data_file_name,MYF(0));
/*
- Now we need to reopen our read descriptor since it has changed.
+ now open the shared writer back up
+ we don't check rc here because we want to open the file back up even
+ if the optimize failed but we will return rc below so that we will
+ know it failed.
+ We also need to reopen our read descriptor since it has changed.
*/
- gzclose(archive);
- if ((archive= gzopen(share->data_file_name, "rb")) == NULL)
+ DBUG_PRINT("info", ("Reopening archive data file"));
+ if (!azopen(&(share->archive_write), share->data_file_name,
+ O_WRONLY|O_APPEND|O_BINARY) ||
+ !azopen(&archive, share->data_file_name, O_RDONLY|O_BINARY))
{
+ DBUG_PRINT("info", ("Could not open archive write file"));
rc= HA_ERR_CRASHED_ON_USAGE;
- goto error;
}
-
- DBUG_RETURN(0);
-
+ DBUG_RETURN(rc);
error:
- gzclose(writer);
+ azclose(&writer);
DBUG_RETURN(rc);
}
@@ -1040,8 +1368,8 @@
*/
if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
- lock_type <= TL_WRITE) && !thd->in_lock_tables
- && !thd->tablespace_op)
+ lock_type <= TL_WRITE) && !thd_in_lock_tables(thd)
+ && !thd_tablespace_op(thd))
lock_type = TL_WRITE_ALLOW_WRITE;
/*
@@ -1052,7 +1380,7 @@
concurrent inserts to t2.
*/
- if (lock_type == TL_READ_NO_INSERT && !thd->in_lock_tables)
+ if (lock_type == TL_READ_NO_INSERT && !thd_in_lock_tables(thd))
lock_type = TL_READ;
lock.type=lock_type;
@@ -1063,6 +1391,17 @@
return to;
}
+void ha_archive::update_create_info(HA_CREATE_INFO *create_info)
+{
+ ha_archive::info(HA_STATUS_AUTO | HA_STATUS_CONST);
+ if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
+ {
+ create_info->auto_increment_value= stats.auto_increment_value;
+ }
+ if (*share->real_path)
+ create_info->data_file_name= share->real_path;
+}
+
/*
Hints for optimizer, see ha_tina for more information
@@ -1074,8 +1413,8 @@
This should be an accurate number now, though bulk and delayed inserts can
cause the number to be inaccurate.
*/
- records= share->rows_recorded;
- deleted= 0;
+ stats.records= share->rows_recorded;
+ stats.deleted= 0;
/* Costs quite a bit more to get all information */
if (flag & HA_STATUS_TIME)
{
@@ -1083,14 +1422,17 @@
VOID(my_stat(share->data_file_name, &file_stat, MYF(MY_WME)));
- mean_rec_length= table->s->reclength + buffer.alloced_length();
- data_file_length= file_stat.st_size;
- create_time= file_stat.st_ctime;
- update_time= file_stat.st_mtime;
- max_data_file_length= share->rows_recorded * mean_rec_length;
+ stats.mean_rec_length= table->s->reclength + buffer.alloced_length();
+ stats.data_file_length= file_stat.st_size;
+ stats.create_time= file_stat.st_ctime;
+ stats.update_time= file_stat.st_mtime;
+ stats.max_data_file_length= share->rows_recorded * stats.mean_rec_length;
}
- delete_length= 0;
- index_file_length=0;
+ stats.delete_length= 0;
+ stats.index_file_length=0;
+
+ if (flag & HA_STATUS_AUTO)
+ stats.auto_increment_value= share->auto_increment_value;
DBUG_VOID_RETURN;
}
@@ -1151,13 +1493,14 @@
{
int rc= 0;
byte *buf;
- const char *old_proc_info=thd->proc_info;
+ const char *old_proc_info;
ha_rows count= share->rows_recorded;
DBUG_ENTER("ha_archive::check");
- thd->proc_info= "Checking table";
+ old_proc_info= thd_proc_info(thd, "Checking table");
/* Flush any waiting data */
- gzflush(share->archive_write, Z_SYNC_FLUSH);
+ azflush(&(share->archive_write), Z_SYNC_FLUSH);
+ share->forced_flushes++;
/*
First we create a buffer that we can use for reading rows, and can pass
@@ -1171,15 +1514,15 @@
start of the file.
*/
if (!rc)
- read_data_header(archive);
+ read_data_header(&archive);
if (!rc)
- while (!(rc= get_row(archive, buf)))
+ while (!(rc= get_row(&archive, buf)))
count--;
my_free((char*)buf, MYF(0));
- thd->proc_info= old_proc_info;
+ thd_proc_info(thd, old_proc_info);
if ((rc && rc != HA_ERR_END_OF_FILE) || count)
{
@@ -1204,4 +1547,21 @@
DBUG_RETURN(repair(thd, &check_opt));
}
-#endif /* HAVE_ARCHIVE_DB */
+
+struct st_mysql_storage_engine archive_storage_engine=
+{ MYSQL_HANDLERTON_INTERFACE_VERSION, &archive_hton };
+
+mysql_declare_plugin(archive)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &archive_storage_engine,
+ "ARCHIVE",
+ "Brian Aker, MySQL AB",
+ "Archive storage engine",
+ archive_db_init, /* Plugin Init */
+ archive_db_done, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ 0
+}
+mysql_declare_plugin_end;
+
--- 1.41/mysql-test/r/auto_increment.result 2006-05-18 11:42:31 +04:00
+++ 1.42/mysql-test/r/auto_increment.result 2006-06-18 14:20:26 +04:00
@@ -378,6 +378,28 @@
KEY `t1_name` (`t1_name`)
) ENGINE=MyISAM AUTO_INCREMENT=1003 DEFAULT CHARSET=latin1
DROP TABLE `t1`;
+create table t1(a int not null auto_increment primary key);
+create table t2(a int not null auto_increment primary key, t1a int);
+insert into t1 values(NULL);
+insert into t2 values (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID());
+insert into t1 values (NULL);
+insert into t2 values (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID()),
+(NULL, LAST_INSERT_ID());
+insert into t1 values (NULL);
+insert into t2 values (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID()),
+(NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID());
+select * from t2;
+a t1a
+1 1
+2 1
+3 2
+4 2
+5 2
+6 3
+7 3
+8 3
+9 3
+drop table t1, t2;
End of 4.1 tests
CREATE TABLE t1 ( `a` int(11) NOT NULL auto_increment, `b` int(11) default NULL,PRIMARY KEY (`a`),UNIQUE KEY `b` (`b`));
insert into t1 (b) values (1);
--- 1.49/mysql-test/r/func_group.result 2006-05-22 19:15:40 +04:00
+++ 1.50/mysql-test/r/func_group.result 2006-06-18 14:20:26 +04:00
@@ -821,6 +821,41 @@
MAX(id)
NULL
DROP TABLE t1;
+CREATE TABLE t1 (id int PRIMARY KEY, b char(3), INDEX(b));
+INSERT INTO t1 VALUES (1,'xx'), (2,'aa');
+SELECT * FROM t1;
+id b
+1 xx
+2 aa
+SELECT MAX(b) FROM t1 WHERE b < 'ppppp';
+MAX(b)
+aa
+SHOW WARNINGS;
+Level Code Message
+SELECT MAX(b) FROM t1 WHERE b < 'pp';
+MAX(b)
+aa
+DROP TABLE t1;
+CREATE TABLE t1 (id int PRIMARY KEY, b char(16), INDEX(b(4)));
+INSERT INTO t1 VALUES (1, 'xxxxbbbb'), (2, 'xxxxaaaa');
+SELECT MAX(b) FROM t1;
+MAX(b)
+xxxxbbbb
+EXPLAIN SELECT MAX(b) FROM t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+DROP TABLE t1;
+CREATE TABLE t1 (id int , b varchar(512), INDEX(b(250))) COLLATE latin1_bin;
+INSERT INTO t1 VALUES
+(1,CONCAT(REPEAT('_', 250), "qq")), (1,CONCAT(REPEAT('_', 250), "zz")),
+(1,CONCAT(REPEAT('_', 250), "aa")), (1,CONCAT(REPEAT('_', 250), "ff"));
+SELECT MAX(b) FROM t1;
+MAX(b)
+__________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________zz
+EXPLAIN SELECT MAX(b) FROM t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4
+DROP TABLE t1;
create table t2 (ff double);
insert into t2 values (2.2);
select cast(sum(distinct ff) as decimal(5,2)) from t2;
--- 1.54/mysql-test/r/func_time.result 2006-06-15 07:00:30 +04:00
+++ 1.55/mysql-test/r/func_time.result 2006-06-18 14:20:26 +04:00
@@ -751,6 +751,49 @@
monthname(str_to_date(1, '%m')), monthname(str_to_date(0, '%m'));
monthname(str_to_date(null, '%m')) monthname(str_to_date(null, '%m')) monthname(str_to_date(1, '%m')) monthname(str_to_date(0, '%m'))
NULL NULL January NULL
+create table t1(f1 date, f2 time, f3 datetime);
+insert into t1 values ("2006-01-01", "12:01:01", "2006-01-01 12:01:01");
+insert into t1 values ("2006-01-02", "12:01:02", "2006-01-02 12:01:02");
+select f1 from t1 where f1 between "2006-1-1" and 20060101;
+f1
+2006-01-01
+select f1 from t1 where f1 between "2006-1-1" and "2006.1.1";
+f1
+2006-01-01
+select f1 from t1 where date(f1) between "2006-1-1" and "2006.1.1";
+f1
+2006-01-01
+select f2 from t1 where f2 between "12:1:2" and "12:2:2";
+f2
+12:01:02
+select f2 from t1 where time(f2) between "12:1:2" and "12:2:2";
+f2
+12:01:02
+select f3 from t1 where f3 between "2006-1-1 12:1:1" and "2006-1-1 12:1:2";
+f3
+2006-01-01 12:01:01
+select f3 from t1 where timestamp(f3) between "2006-1-1 12:1:1" and "2006-1-1 12:1:2";
+f3
+2006-01-01 12:01:01
+select f1 from t1 where "2006-1-1" between f1 and f3;
+f1
+2006-01-01
+select f1 from t1 where "2006-1-1" between date(f1) and date(f3);
+f1
+2006-01-01
+select f1 from t1 where "2006-1-1" between f1 and 'zzz';
+f1
+Warnings:
+Warning 1292 Incorrect date value: 'zzz' for column 'f1' at row 1
+Warning 1292 Truncated incorrect INTEGER value: 'zzz'
+Warning 1292 Truncated incorrect INTEGER value: 'zzz'
+select f1 from t1 where makedate(2006,1) between date(f1) and date(f3);
+f1
+2006-01-01
+select f1 from t1 where makedate(2006,2) between date(f1) and date(f3);
+f1
+2006-01-02
+drop table t1;
select now() - now() + 0, curtime() - curtime() + 0,
sec_to_time(1) + 0, from_unixtime(1) + 0;
now() - now() + 0 curtime() - curtime() + 0 sec_to_time(1) + 0 from_unixtime(1) + 0
--- 1.128/mysql-test/r/select.result 2006-06-09 23:27:19 +04:00
+++ 1.129/mysql-test/r/select.result 2006-06-18 14:56:31 +04:00
@@ -2656,16 +2656,6 @@
select 123 as a from t1 where f1 is null;
a
drop table t1,t11;
-CREATE TABLE t1 (a INT, b INT);
-(SELECT a, b AS c FROM t1) ORDER BY c+1;
-a c
-(SELECT a, b AS c FROM t1) ORDER BY b+1;
-a c
-SELECT a, b AS c FROM t1 ORDER BY c+1;
-a c
-SELECT a, b AS c FROM t1 ORDER BY b+1;
-a c
-drop table t1;
CREATE TABLE t1 ( a INT NOT NULL, b INT NOT NULL, UNIQUE idx (a,b) );
INSERT INTO t1 VALUES (1,1),(1,2),(1,3),(1,4);
CREATE TABLE t2 ( a INT NOT NULL, b INT NOT NULL, e INT );
@@ -2716,14 +2706,37 @@
f1 f2
1 1
drop table t1,t2;
+CREATE TABLE t1(a int, b int, c int, KEY b(b), KEY c(c));
+insert into t1 values (1,0,0),(2,0,0);
+CREATE TABLE t2 (a int, b varchar(2), c varchar(2), PRIMARY KEY(a));
+insert into t2 values (1,'',''), (2,'','');
+CREATE TABLE t3 (a int, b int, PRIMARY KEY (a,b), KEY a (a), KEY b (b));
+insert into t3 values (1,1),(1,2);
+explain select straight_join DISTINCT t2.a,t2.b, t1.c from t1, t3, t2
+where (t1.c=t2.a or (t1.c=t3.a and t2.a=t3.b)) and t1.b=556476786 and
+t2.b like '%%' order by t2.b limit 0,1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref b,c b 5 const 1 Using where; Using temporary; Using filesort
+1 SIMPLE t3 index PRIMARY,a,b PRIMARY 8 NULL 2 Using index
+1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 2 Range checked for each record (index map: 0x1)
+DROP TABLE t1,t2,t3;
CREATE TABLE t1 (a int, INDEX idx(a));
INSERT INTO t1 VALUES (2), (3), (1);
EXPLAIN SELECT * FROM t1 IGNORE INDEX (idx);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
EXPLAIN SELECT * FROM t1 IGNORE INDEX (a);
-ERROR 42000: Key 'a' doesn't exist in table 't1'
+ERROR HY000: Key 'a' doesn't exist in table 't1'
EXPLAIN SELECT * FROM t1 FORCE INDEX (a);
+ERROR HY000: Key 'a' doesn't exist in table 't1'
+DROP TABLE t1;
+CREATE TABLE t1 (a int, INDEX idx(a));
+INSERT INTO t1 VALUES (2), (3), (1);
+EXPLAIN SELECT * FROM t1 IGNORE INDEX (idx);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3
+EXPLAIN SELECT * FROM t1 IGNORE INDEX (a);
+ERROR 42000: Key 'a' doesn't exist in table 't1'
ERROR 42000: Key 'a' doesn't exist in table 't1'
DROP TABLE t1;
CREATE TABLE t1 ( city char(30) );
@@ -2814,19 +2827,6 @@
WART 0200 1
WART 0300 3
DROP TABLE t1;
-CREATE TABLE t1 ( a BLOB, INDEX (a(20)) );
-CREATE TABLE t2 ( a BLOB, INDEX (a(20)) );
-INSERT INTO t1 VALUES ('one'),('two'),('three'),('four'),('five');
-INSERT INTO t2 VALUES ('one'),('two'),('three'),('four'),('five');
-EXPLAIN SELECT * FROM t1 LEFT JOIN t2 USE INDEX (a) ON t1.a=t2.a;
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 5
-1 SIMPLE t2 ref a a 23 test.t1.a 2
-EXPLAIN SELECT * FROM t1 LEFT JOIN t2 FORCE INDEX (a) ON t1.a=t2.a;
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 5
-1 SIMPLE t2 ref a a 23 test.t1.a 2
-DROP TABLE t1, t2;
create table t1 (a int, b int);
create table t2 like t1;
select t1.a from (t1 inner join t2 on t1.a=t2.a) where t2.a=1;
@@ -2857,29 +2857,6 @@
NULL
1.0000
drop table t1;
-create table t1 (a int(11));
-select all all * from t1;
-a
-select distinct distinct * from t1;
-a
-select all distinct * from t1;
-ERROR HY000: Incorrect usage of ALL and DISTINCT
-select distinct all * from t1;
-ERROR HY000: Incorrect usage of ALL and DISTINCT
-drop table t1;
-CREATE TABLE t1 ( a BLOB, INDEX (a(20)) );
-CREATE TABLE t2 ( a BLOB, INDEX (a(20)) );
-INSERT INTO t1 VALUES ('one'),('two'),('three'),('four'),('five');
-INSERT INTO t2 VALUES ('one'),('two'),('three'),('four'),('five');
-EXPLAIN SELECT * FROM t1 LEFT JOIN t2 USE INDEX (a) ON t1.a=t2.a;
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 5
-1 SIMPLE t2 ref a a 23 test.t1.a 2
-EXPLAIN SELECT * FROM t1 LEFT JOIN t2 FORCE INDEX (a) ON t1.a=t2.a;
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 5
-1 SIMPLE t2 ref a a 23 test.t1.a 2
-DROP TABLE t1, t2;
CREATE TABLE t1 (a int);
CREATE TABLE t2 (a int);
INSERT INTO t1 VALUES (1), (2), (3), (4), (5);
@@ -3456,3 +3433,23 @@
1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using where
1 SIMPLE t2 ref c c 5 test.t1.a 2 Using where
DROP TABLE t1, t2;
+create table t1 (
+a int unsigned not null auto_increment primary key,
+b bit not null,
+c bit not null
+);
+create table t2 (
+a int unsigned not null auto_increment primary key,
+b bit not null,
+c int unsigned not null,
+d varchar(50)
+);
+insert into t1 (b,c) values (0,1), (0,1);
+insert into t2 (b,c) values (0,1);
+select t1.a, t1.b + 0, t1.c + 0, t2.a, t2.b + 0, t2.c, t2.d
+from t1 left outer join t2 on t1.a = t2.c and t2.b <> 1
+where t1.b <> 1 order by t1.a;
+a t1.b + 0 t1.c + 0 a t2.b + 0 c d
+1 0 1 1 0 1 NULL
+2 0 1 NULL NULL NULL NULL
+drop table t1,t2;
--- 1.26/mysql-test/t/auto_increment.test 2006-05-12 17:00:46 +04:00
+++ 1.27/mysql-test/t/auto_increment.test 2006-06-18 14:20:26 +04:00
@@ -238,6 +238,23 @@
DROP TABLE `t1`;
+#
+# Bug #6880: LAST_INSERT_ID() within a statement
+#
+
+create table t1(a int not null auto_increment primary key);
+create table t2(a int not null auto_increment primary key, t1a int);
+insert into t1 values(NULL);
+insert into t2 values (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID());
+insert into t1 values (NULL);
+insert into t2 values (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID()),
+(NULL, LAST_INSERT_ID());
+insert into t1 values (NULL);
+insert into t2 values (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID()),
+(NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID());
+select * from t2;
+drop table t1, t2;
+
--echo End of 4.1 tests
#
--- 1.13/mysql-test/t/delayed.test 2006-02-25 21:35:06 +03:00
+++ 1.14/mysql-test/t/delayed.test 2006-06-18 14:20:26 +04:00
@@ -50,3 +50,52 @@
insert delayed into t1 values (1);
select * from t1;
drop table t1;
+
+#
+# Bug #20195: INSERT DELAYED with auto_increment is assigned wrong values
+#
+CREATE TABLE t1 ( a int(10) NOT NULL auto_increment, PRIMARY KEY (a));
+
+# Make one delayed insert to start the separate thread
+insert delayed into t1 values(null);
+
+# Do some normal inserts
+insert into t1 values(null);
+insert into t1 values(null);
+
+# Discarded, since the delayed-counter is 2, which is already used
+insert delayed into t1 values(null);
+
+# Discarded, since the delayed-counter is 3, which is already used
+insert delayed into t1 values(null);
+
+# Works, since the delayed-counter is 4, which is unused
+insert delayed into t1 values(null);
+
+# Do some more inserts
+insert into t1 values(null);
+insert into t1 values(null);
+insert into t1 values(null);
+
+# Delete one of the above to make a hole
+delete from t1 where a=6;
+
+# Discarded, since the delayed-counter is 5, which is already used
+insert delayed into t1 values(null);
+
+# Works, since the delayed-counter is 6, which is unused (the row we deleted)
+insert delayed into t1 values(null);
+
+# Discarded, since the delayed-counter is 7, which is already used
+insert delayed into t1 values(null);
+
+# Works, since the delayed-counter is 8, which is unused
+insert delayed into t1 values(null);
+
+# Check what we have now
+# must wait so that the delayed thread finishes
+# Note: this must be increased if the test fails
+--sleep 1
+select * from t1 order by a;
+
+DROP TABLE t1;
--- 1.44/mysql-test/t/func_time.test 2006-06-15 07:00:30 +04:00
+++ 1.45/mysql-test/t/func_time.test 2006-06-18 14:20:26 +04:00
@@ -368,6 +368,27 @@
monthname(str_to_date(1, '%m')), monthname(str_to_date(0, '%m'));
#
+# Bug#16377 result of DATE/TIME functions were compared as strings which
+# can lead to a wrong result.
+#
+create table t1(f1 date, f2 time, f3 datetime);
+insert into t1 values ("2006-01-01", "12:01:01", "2006-01-01 12:01:01");
+insert into t1 values ("2006-01-02", "12:01:02", "2006-01-02 12:01:02");
+select f1 from t1 where f1 between "2006-1-1" and 20060101;
+select f1 from t1 where f1 between "2006-1-1" and "2006.1.1";
+select f1 from t1 where date(f1) between "2006-1-1" and "2006.1.1";
+select f2 from t1 where f2 between "12:1:2" and "12:2:2";
+select f2 from t1 where time(f2) between "12:1:2" and "12:2:2";
+select f3 from t1 where f3 between "2006-1-1 12:1:1" and "2006-1-1 12:1:2";
+select f3 from t1 where timestamp(f3) between "2006-1-1 12:1:1" and "2006-1-1 12:1:2";
+select f1 from t1 where "2006-1-1" between f1 and f3;
+select f1 from t1 where "2006-1-1" between date(f1) and date(f3);
+select f1 from t1 where "2006-1-1" between f1 and 'zzz';
+select f1 from t1 where makedate(2006,1) between date(f1) and date(f3);
+select f1 from t1 where makedate(2006,2) between date(f1) and date(f3);
+drop table t1;
+
+#
# Bug #16546
#
--- 1.103/mysql-test/t/select.test 2006-06-09 11:23:52 +04:00
+++ 1.104/mysql-test/t/select.test 2006-06-18 14:20:26 +04:00
@@ -2217,15 +2217,6 @@
select 123 as a from t1 where f1 is null;
drop table t1,t11;
-# Bug 7672 Unknown column error in order clause
-#
-CREATE TABLE t1 (a INT, b INT);
-(SELECT a, b AS c FROM t1) ORDER BY c+1;
-(SELECT a, b AS c FROM t1) ORDER BY b+1;
-SELECT a, b AS c FROM t1 ORDER BY c+1;
-SELECT a, b AS c FROM t1 ORDER BY b+1;
-drop table t1;
-
#
# Bug #3874 (function in GROUP and LEFT JOIN)
#
@@ -2265,6 +2256,21 @@
drop table t1,t2;
#
+# Bug #4981: 4.x and 5.x produce non-optimal execution path, 3.23 regression test failure
+#
+CREATE TABLE t1(a int, b int, c int, KEY b(b), KEY c(c));
+insert into t1 values (1,0,0),(2,0,0);
+CREATE TABLE t2 (a int, b varchar(2), c varchar(2), PRIMARY KEY(a));
+insert into t2 values (1,'',''), (2,'','');
+CREATE TABLE t3 (a int, b int, PRIMARY KEY (a,b), KEY a (a), KEY b (b));
+insert into t3 values (1,1),(1,2);
+# must have "range checked" for t2
+explain select straight_join DISTINCT t2.a,t2.b, t1.c from t1, t3, t2
+ where (t1.c=t2.a or (t1.c=t3.a and t2.a=t3.b)) and t1.b=556476786 and
+ t2.b like '%%' order by t2.b limit 0,1;
+DROP TABLE t1,t2,t3;
+
+#
# Bug #17873: confusing error message when IGNORE INDEX refers a column name
#
@@ -2282,48 +2288,6 @@
# End of 4.1 tests
#
-# Test case for bug 7098: substitution of a constant for a string field
-#
-
-CREATE TABLE t1 ( city char(30) );
-INSERT INTO t1 VALUES ('London');
-INSERT INTO t1 VALUES ('Paris');
-
-SELECT * FROM t1 WHERE city='London';
-SELECT * FROM t1 WHERE city='london';
-EXPLAIN SELECT * FROM t1 WHERE city='London' AND city='london';
-SELECT * FROM t1 WHERE city='London' AND city='london';
-EXPLAIN SELECT * FROM t1 WHERE city LIKE '%london%' AND city='London';
-SELECT * FROM t1 WHERE city LIKE '%london%' AND city='London';
-
-DROP TABLE t1;
-
-#
-# Bug#7425 inconsistent sort order on unsigned columns result of substraction
-#
-
-create table t1 (a int(11) unsigned, b int(11) unsigned);
-insert into t1 values (1,0), (1,1), (1,2);
-select a-b from t1 order by 1;
-select a-b , (a-b < 0) from t1 order by 1;
-select a-b as d, (a-b >= 0), b from t1 group by b having d >= 0;
-select cast((a - b) as unsigned) from t1 order by 1;
-drop table t1;
-
-
-#
-# Bug#8733 server accepts malformed query (multiply mentioned distinct)
-#
-create table t1 (a int(11));
-select all all * from t1;
-select distinct distinct * from t1;
---error 1221
-select all distinct * from t1;
---error 1221
-select distinct all * from t1;
-drop table t1;
-
-#
# Test for bug #6474
#
@@ -2358,21 +2322,6 @@
DROP TABLE t1;
#
-# Test case for bug 7520: a wrong cost of the index for a BLOB field
-#
-
-CREATE TABLE t1 ( a BLOB, INDEX (a(20)) );
-CREATE TABLE t2 ( a BLOB, INDEX (a(20)) );
-
-INSERT INTO t1 VALUES ('one'),('two'),('three'),('four'),('five');
-INSERT INTO t2 VALUES ('one'),('two'),('three'),('four'),('five');
-
-EXPLAIN SELECT * FROM t1 LEFT JOIN t2 USE INDEX (a) ON t1.a=t2.a;
-EXPLAIN SELECT * FROM t1 LEFT JOIN t2 FORCE INDEX (a) ON t1.a=t2.a;
-
-DROP TABLE t1, t2;
-
-#
# Bug#8670
#
create table t1 (a int, b int);
@@ -2411,34 +2360,6 @@
#
-# Bug#8733 server accepts malformed query (multiply mentioned distinct)
-#
-create table t1 (a int(11));
-select all all * from t1;
-select distinct distinct * from t1;
---error 1221
-select all distinct * from t1;
---error 1221
-select distinct all * from t1;
-drop table t1;
-
-
-#
-# Test case for bug 7520: a wrong cost of the index for a BLOB field
-#
-
-CREATE TABLE t1 ( a BLOB, INDEX (a(20)) );
-CREATE TABLE t2 ( a BLOB, INDEX (a(20)) );
-
-INSERT INTO t1 VALUES ('one'),('two'),('three'),('four'),('five');
-INSERT INTO t2 VALUES ('one'),('two'),('three'),('four'),('five');
-
-EXPLAIN SELECT * FROM t1 LEFT JOIN t2 USE INDEX (a) ON t1.a=t2.a;
-EXPLAIN SELECT * FROM t1 LEFT JOIN t2 FORCE INDEX (a) ON t1.a=t2.a;
-
-DROP TABLE t1, t2;
-
-#
# Test for bug #10084: STRAIGHT_JOIN with ON expression
#
@@ -2935,3 +2856,29 @@
SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6 AND a > 0;
DROP TABLE t1, t2;
+
+#
+# Bug #18895: BIT values cause joins to fail
+#
+create table t1 (
+ a int unsigned not null auto_increment primary key,
+ b bit not null,
+ c bit not null
+);
+
+create table t2 (
+ a int unsigned not null auto_increment primary key,
+ b bit not null,
+ c int unsigned not null,
+ d varchar(50)
+);
+
+insert into t1 (b,c) values (0,1), (0,1);
+insert into t2 (b,c) values (0,1);
+
+-- Row 1 should succeed. Row 2 should fail. Both fail.
+select t1.a, t1.b + 0, t1.c + 0, t2.a, t2.b + 0, t2.c, t2.d
+from t1 left outer join t2 on t1.a = t2.c and t2.b <> 1
+where t1.b <> 1 order by t1.a;
+
+drop table t1,t2;
--- 1.116/mysql-test/r/func_str.result 2006-05-20 06:00:54 +04:00
+++ 1.117/mysql-test/r/func_str.result 2006-06-18 14:20:26 +04:00
@@ -1023,6 +1023,21 @@
select ifnull(load_file("lkjlkj"),"it's null");
ifnull(load_file("lkjlkj"),"it's null")
it's null
+create table t1 (f1 varchar(4), f2 varchar(64), unique key k1 (f1,f2));
+insert into t1 values ( 'test',md5('test')), ('test', sha('test'));
+select * from t1 where f1='test' and (f2= md5("test") or f2= md5("TEST"));
+f1 f2
+test 098f6bcd4621d373cade4e832627b4f6
+select * from t1 where f1='test' and (f2= md5("TEST") or f2= md5("test"));
+f1 f2
+test 098f6bcd4621d373cade4e832627b4f6
+select * from t1 where f1='test' and (f2= sha("test") or f2= sha("TEST"));
+f1 f2
+test a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
+select * from t1 where f1='test' and (f2= sha("TEST") or f2= sha("test"));
+f1 f2
+test a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
+drop table t1;
End of 4.1 tests
create table t1 (d decimal default null);
insert into t1 values (null);
--- 1.44/mysql-test/r/multi_update.result 2006-05-30 23:04:34 +04:00
+++ 1.45/mysql-test/r/multi_update.result 2006-06-18 14:20:26 +04:00
@@ -524,3 +524,83 @@
30
drop view v1;
drop table t1, t2;
+create table t1 (i1 int, i2 int, i3 int);
+create table t2 (id int, c1 varchar(20), c2 varchar(20));
+insert into t1 values (1,5,10),(3,7,12),(4,5,2),(9,10,15),(2,2,2);
+insert into t2 values (9,"abc","def"),(5,"opq","lmn"),(2,"test t","t test");
+select * from t1 order by i1;
+i1 i2 i3
+1 5 10
+2 2 2
+3 7 12
+4 5 2
+9 10 15
+select * from t2;
+id c1 c2
+9 abc def
+5 opq lmn
+2 test t t test
+update t1,t2 set t1.i2=15, t2.c2="ppc" where t1.i1=t2.id;
+select * from t1 order by i1;
+i1 i2 i3
+1 5 10
+2 15 2
+3 7 12
+4 5 2
+9 15 15
+select * from t2 order by id;
+id c1 c2
+2 test t ppc
+5 opq lmn
+9 abc ppc
+delete t1.*,t2.* from t1,t2 where t1.i2=t2.id;
+select * from t1 order by i1;
+i1 i2 i3
+2 15 2
+3 7 12
+9 15 15
+select * from t2 order by id;
+id c1 c2
+2 test t ppc
+9 abc ppc
+drop table t1, t2;
+create table t1 (i1 int auto_increment not null, i2 int, i3 int, primary key (i1));
+create table t2 (id int auto_increment not null, c1 varchar(20), c2 varchar(20), primary key(id));
+insert into t1 values (1,5,10),(3,7,12),(4,5,2),(9,10,15),(2,2,2);
+insert into t2 values (9,"abc","def"),(5,"opq","lmn"),(2,"test t","t test");
+select * from t1 order by i1;
+i1 i2 i3
+1 5 10
+2 2 2
+3 7 12
+4 5 2
+9 10 15
+select * from t2 order by id;
+id c1 c2
+2 test t t test
+5 opq lmn
+9 abc def
+update t1,t2 set t1.i2=15, t2.c2="ppc" where t1.i1=t2.id;
+select * from t1 order by i1;
+i1 i2 i3
+1 5 10
+2 15 2
+3 7 12
+4 5 2
+9 15 15
+select * from t2 order by id;
+id c1 c2
+2 test t ppc
+5 opq lmn
+9 abc ppc
+delete t1.*,t2.* from t1,t2 where t1.i2=t2.id;
+select * from t1 order by i1;
+i1 i2 i3
+2 15 2
+3 7 12
+9 15 15
+select * from t2 order by id;
+id c1 c2
+2 test t ppc
+9 abc ppc
+drop table t1, t2;
--- 1.62.2.3/mysql-test/r/rpl_log.result 2006-06-17 03:35:06 +04:00
+++ 1.69/mysql-test/r/rpl_stm_log.result 2006-06-18 14:56:31 +04:00
@@ -8,97 +8,91 @@
reset master;
reset slave;
reset master;
-create table t1(n int not null auto_increment primary key);
+create table t1(n int not null auto_increment primary key)ENGINE=MyISAM;
insert into t1 values (NULL);
drop table t1;
-create table t1 (word char(20) not null);
+create table t1 (word char(20) not null)ENGINE=MyISAM;
load data infile '../std_data_ln/words.dat' into table t1 ignore 1 lines;
select count(*) from t1;
count(*)
69
-drop table t1;
show binlog events;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 4 Format_desc 1 98 Server ver: VERSION, Binlog ver: 4
-master-bin.000001 98 Query 1 219 use `test`; create table t1(n int not null auto_increment primary key)
-master-bin.000001 219 Intvar 1 247 INSERT_ID=1
-master-bin.000001 247 Query 1 338 use `test`; insert into t1 values (NULL)
-master-bin.000001 338 Query 1 414 use `test`; drop table t1
-master-bin.000001 414 Query 1 517 use `test`; create table t1 (word char(20) not null)
-master-bin.000001 517 Begin_load_query 1 1121 ;file_id=1;block_len=581
-master-bin.000001 1121 Execute_load_query 1 1269 use `test`; load data infile '../std_data_ln/words.dat' into table t1 ignore 1 lines ;file_id=1
-master-bin.000001 1269 Query 1 1345 use `test`; drop table t1
-show binlog events from 98 limit 1;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 98 Query 1 219 use `test`; create table t1(n int not null auto_increment primary key)
-show binlog events from 98 limit 2;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 98 Query 1 219 use `test`; create table t1(n int not null auto_increment primary key)
-master-bin.000001 219 Intvar 1 247 INSERT_ID=1
-show binlog events from 98 limit 2,1;
+master-bin.000001 # Format_desc 1 # Server ver: VERSION, Binlog ver: 4
+master-bin.000001 # Query 1 # use `test`; create table t1(n int not null auto_increment primary key)ENGINE=MyISAM
+master-bin.000001 # Intvar 1 # INSERT_ID=1
+master-bin.000001 # Query 1 # use `test`; insert into t1 values (NULL)
+master-bin.000001 # Query 1 # use `test`; drop table t1
+master-bin.000001 # Query 1 # use `test`; create table t1 (word char(20) not null)ENGINE=MyISAM
+master-bin.000001 # Begin_load_query 1 # ;file_id=1;block_len=581
+master-bin.000001 # Execute_load_query 1 # use `test`; load data infile '../std_data_ln/words.dat' into table t1 ignore 1 lines ;file_id=1
+show binlog events from 102 limit 1;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # use `test`; create table t1(n int not null auto_increment primary key)ENGINE=MyISAM
+show binlog events from 102 limit 2;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # use `test`; create table t1(n int not null auto_increment primary key)ENGINE=MyISAM
+master-bin.000001 # Intvar 1 # INSERT_ID=1
+show binlog events from 102 limit 2,1;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 247 Query 1 338 use `test`; insert into t1 values (NULL)
+master-bin.000001 # Query 1 # use `test`; insert into t1 values (NULL)
flush logs;
-create table t5 (a int);
-drop table t5;
+create table t3 (a int)ENGINE=MyISAM;
start slave;
+
+let $result_pattern= '%127.0.0.1%root%master-bin.000002%slave-relay-bin.000005%Yes%Yes%0%0%None%' ;
+
+--source include/wait_slave_status.inc
flush logs;
stop slave;
-create table t1 (n int);
-insert into t1 values (1);
-drop table t1;
+create table t2 (n int)ENGINE=MyISAM;
+insert into t2 values (1);
show binlog events;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 4 Format_desc 1 98 Server ver: VERSION, Binlog ver: 4
-master-bin.000001 98 Query 1 219 use `test`; create table t1(n int not null auto_increment primary key)
-master-bin.000001 219 Intvar 1 247 INSERT_ID=1
-master-bin.000001 247 Query 1 338 use `test`; insert into t1 values (NULL)
-master-bin.000001 338 Query 1 414 use `test`; drop table t1
-master-bin.000001 414 Query 1 517 use `test`; create table t1 (word char(20) not null)
-master-bin.000001 517 Begin_load_query 1 1121 ;file_id=1;block_len=581
-master-bin.000001 1121 Execute_load_query 1 1269 use `test`; load data infile '../std_data_ln/words.dat' into table t1 ignore 1 lines ;file_id=1
-master-bin.000001 1269 Query 1 1345 use `test`; drop table t1
-master-bin.000001 1345 Rotate 1 1389 master-bin.000002;pos=4
+master-bin.000001 # Format_desc 1 # Server ver: VERSION, Binlog ver: 4
+master-bin.000001 # Query 1 # use `test`; create table t1(n int not null auto_increment primary key)ENGINE=MyISAM
+master-bin.000001 # Intvar 1 # INSERT_ID=1
+master-bin.000001 # Query 1 # use `test`; insert into t1 values (NULL)
+master-bin.000001 # Query 1 # use `test`; drop table t1
+master-bin.000001 # Query 1 # use `test`; create table t1 (word char(20) not null)ENGINE=MyISAM
+master-bin.000001 # Begin_load_query 1 # ;file_id=1;block_len=581
+master-bin.000001 # Execute_load_query 1 # use `test`; load data infile '../std_data_ln/words.dat' into table t1 ignore 1 lines ;file_id=1
+master-bin.000001 # Rotate 1 # master-bin.000002;pos=4
show binlog events in 'master-bin.000002';
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000002 4 Format_desc 1 98 Server ver: VERSION, Binlog ver: 4
-master-bin.000002 98 Query 1 184 use `test`; create table t5 (a int)
-master-bin.000002 184 Query 1 260 use `test`; drop table t5
-master-bin.000002 260 Query 1 346 use `test`; create table t1 (n int)
-master-bin.000002 346 Query 1 434 use `test`; insert into t1 values (1)
-master-bin.000002 434 Query 1 510 use `test`; drop table t1
+master-bin.000002 # Format_desc 1 # Server ver: VERSION, Binlog ver: 4
+master-bin.000002 # Query 1 # use `test`; create table t3 (a int)ENGINE=MyISAM
+master-bin.000002 # Query 1 # use `test`; create table t2 (n int)ENGINE=MyISAM
+master-bin.000002 # Query 1 # use `test`; insert into t2 values (1)
show binary logs;
Log_name File_size
-master-bin.000001 1389
-master-bin.000002 510
+master-bin.000001 1343
+master-bin.000002 388
start slave;
show binary logs;
Log_name File_size
-slave-bin.000001 1552
-slave-bin.000002 348
+slave-bin.000001 1443
+slave-bin.000002 289
show binlog events in 'slave-bin.000001' from 4;
Log_name Pos Event_type Server_id End_log_pos Info
-slave-bin.000001 4 Format_desc 2 98 Server ver: VERSION, Binlog ver: 4
-slave-bin.000001 98 Query 1 219 use `test`; create table t1(n int not null auto_increment primary key)
-slave-bin.000001 219 Intvar 1 247 INSERT_ID=1
-slave-bin.000001 247 Query 1 338 use `test`; insert into t1 values (NULL)
-slave-bin.000001 338 Query 1 414 use `test`; drop table t1
-slave-bin.000001 414 Query 1 517 use `test`; create table t1 (word char(20) not null)
-slave-bin.000001 517 Begin_load_query 1 1121 ;file_id=1;block_len=581
-slave-bin.000001 1121 Execute_load_query 1 1271 use `test`; load data INFILE '../tmp/SQL_LOAD-2-1-1.data' INTO table t1 ignore 1 lines ;file_id=1
-slave-bin.000001 1271 Query 1 1347 use `test`; drop table t1
-slave-bin.000001 1347 Query 1 1433 use `test`; create table t5 (a int)
-slave-bin.000001 1433 Query 1 1509 use `test`; drop table t5
-slave-bin.000001 1509 Rotate 2 1552 slave-bin.000002;pos=4
+slave-bin.000001 # Format_desc 2 # Server ver: VERSION, Binlog ver: 4
+slave-bin.000001 # Query 1 # use `test`; create table t1(n int not null auto_increment primary key)ENGINE=MyISAM
+slave-bin.000001 # Intvar 1 # INSERT_ID=1
+slave-bin.000001 # Query 1 # use `test`; insert into t1 values (NULL)
+slave-bin.000001 # Query 1 # use `test`; drop table t1
+slave-bin.000001 # Query 1 # use `test`; create table t1 (word char(20) not null)ENGINE=MyISAM
+slave-bin.000001 # Begin_load_query 1 # ;file_id=1;block_len=581
+slave-bin.000001 # Execute_load_query 1 # use `test`; load data INFILE '../tmp/SQL_LOAD-2-1-1.data' INTO table t1 ignore 1 lines ;file_id=1
+slave-bin.000001 # Query 1 # use `test`; create table t3 (a int)ENGINE=MyISAM
+slave-bin.000001 # Rotate 2 # slave-bin.000002;pos=4
show binlog events in 'slave-bin.000002' from 4;
Log_name Pos Event_type Server_id End_log_pos Info
-slave-bin.000002 4 Format_desc 2 98 Server ver: VERSION, Binlog ver: 4
-slave-bin.000002 98 Query 1 184 use `test`; create table t1 (n int)
-slave-bin.000002 184 Query 1 272 use `test`; insert into t1 values (1)
-slave-bin.000002 272 Query 1 348 use `test`; drop table t1
+slave-bin.000002 # Format_desc 2 # Server ver: VERSION, Binlog ver: 4
+slave-bin.000002 # Query 1 # use `test`; create table t2 (n int)ENGINE=MyISAM
+slave-bin.000002 # Query 1 # use `test`; insert into t2 values (1)
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_PORT 1 master-bin.000002 510 # # master-bin.000002 Yes Yes 0 0 510 # None 0 No #
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000002 388 # # master-bin.000002 Yes Yes # 0 0 388 # None 0 No #
show binlog events in 'slave-bin.000005' from 4;
ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Could not find target log
create table t1(a int auto_increment primary key, b int);
@@ -118,3 +112,6 @@
5 1
6 1
drop table t1;
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
--- 1.50/mysql-test/t/multi_update.test 2006-06-04 19:52:06 +04:00
+++ 1.51/mysql-test/t/multi_update.test 2006-06-18 14:20:26 +04:00
@@ -452,6 +452,14 @@
delete t2, t1 from t2 left join t1 on (t2.aclid=t1.aclid) where t2.refid='1';
drop table t1, t2;
+#
+# Bug#19225: unchecked error leads to server crash
+#
+create table t1(a int);
+create table t2(a int);
+--error 1093
+delete from t1,t2 using t1,t2 where t1.a=(select a from t1);
+drop table t1, t2;
# End of 4.1 tests
#
--- 1.27.2.2/mysql-test/t/rpl_log.test 2006-06-17 03:35:06 +04:00
+++ 1.38/mysql-test/extra/rpl_tests/rpl_log.test 2006-06-18 14:56:31 +04:00
@@ -1,4 +1,5 @@
-source include/master-slave.inc;
+# Requires statement logging
+-- source include/master-slave.inc
# Clean up old slave's binlogs.
# The slave is started with --log-slave-updates
@@ -29,18 +30,25 @@
connection master;
reset master;
-create table t1(n int not null auto_increment primary key);
+eval create table t1(n int not null auto_increment primary key)ENGINE=$engine_type;
insert into t1 values (NULL);
drop table t1;
-create table t1 (word char(20) not null);
+eval create table t1 (word char(20) not null)ENGINE=$engine_type;
load data infile '../std_data_ln/words.dat' into table t1 ignore 1 lines;
select count(*) from t1;
-drop table t1;
--replace_result $VERSION VERSION
+--replace_column 2 # 5 #
+--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/
show binlog events;
-show binlog events from 98 limit 1;
-show binlog events from 98 limit 2;
-show binlog events from 98 limit 2,1;
+--replace_column 2 # 5 #
+--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/
+show binlog events from 102 limit 1;
+--replace_column 2 # 5 #
+--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/
+show binlog events from 102 limit 2;
+--replace_column 2 # 5 #
+--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/
+show binlog events from 102 limit 2,1;
flush logs;
# We need an extra update before doing save_master_pos.
@@ -59,8 +67,7 @@
# To make it predictable, we do a useless update now, but which has the
# interest of making the slave catch both rotate events.
-create table t5 (a int);
-drop table t5;
+eval create table t3 (a int)ENGINE=$engine_type;
# Sync slave and force it to start on another binary log
@@ -70,6 +77,8 @@
# to go into the relay log (the master always sends a fake one when replication
# starts).
start slave;
+let $result_pattern= '%127.0.0.1%root%master-bin.000002%slave-relay-bin.000005%Yes%Yes%0%0%None%';
+--source include/wait_slave_status.inc
sync_with_master;
flush logs;
stop slave;
@@ -77,12 +86,15 @@
# Create some entries for second log
-create table t1 (n int);
-insert into t1 values (1);
-drop table t1;
+eval create table t2 (n int)ENGINE=$engine_type;
+insert into t2 values (1);
--replace_result $VERSION VERSION
+--replace_column 2 # 5 #
+--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/
show binlog events;
--replace_result $VERSION VERSION
+--replace_column 2 # 5 #
+--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/
show binlog events in 'master-bin.000002';
show binary logs;
save_master_pos;
@@ -91,11 +103,15 @@
sync_with_master;
show binary logs;
--replace_result $MASTER_MYPORT MASTER_PORT $VERSION VERSION
+--replace_column 2 # 5 #
+--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/
show binlog events in 'slave-bin.000001' from 4;
--replace_result $MASTER_MYPORT MASTER_PORT $VERSION VERSION
+--replace_column 2 # 5 #
+--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/
show binlog events in 'slave-bin.000002' from 4;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 8 # 9 # 23 # 33 #
+--replace_column 1 # 8 # 9 # 16 # 23 # 33 #
show slave status;
# Need to recode the following
@@ -124,4 +140,8 @@
drop table t1;
# End of 4.1 tests
-# Adding comment for force manual merge 5.0 -> wl1012: Delete me
+# The table drops caused Cluster Replication wrapper to fail as event ID would never be the same.# Moving drops here.
+
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
--- 1.10/mysql-test/r/replace.result 2006-01-23 14:16:58 +03:00
+++ 1.11/mysql-test/r/replace.result 2006-06-18 14:20:26 +04:00
@@ -24,3 +24,9 @@
63 default_value
127 last
drop table t1;
+CREATE TABLE t1 (f1 INT);
+CREATE VIEW v1 AS SELECT f1 FROM t1 WHERE f1 = 0 WITH CHECK OPTION;
+REPLACE INTO v1 (f1) VALUES (1);
+ERROR HY000: CHECK OPTION failed 'test.v1'
+DROP TABLE t1;
+DROP VIEW v1;
| Thread |
|---|
| • bk commit into 5.1 tree (evgen:1.2218) | eugene | 19 Jun |