summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMichael Widenius <monty@askmonty.org>2009-02-15 12:58:34 +0200
committerMichael Widenius <monty@askmonty.org>2009-02-15 12:58:34 +0200
commita8fdaa6f2c5b2e302bffb069be3475772ca20f48 (patch)
treeb5c9560ec7346f7af6a5904ad344fdbb8020849c /sql
parent115efe100dbc1393bce964fa1370e50cfef71d18 (diff)
parentf7a24d72dc7a86341da4634f6d1a71f1ea77000b (diff)
downloadmariadb-git-a8fdaa6f2c5b2e302bffb069be3475772ca20f48.tar.gz
Merge with base MySQL 5.1
Contains fixes for test cases Changed release tag to beta configure.in: change release tag to beta
Diffstat (limited to 'sql')
-rw-r--r--sql/event_db_repository.cc2
-rw-r--r--sql/event_parse_data.cc2
-rw-r--r--sql/event_parse_data.h2
-rw-r--r--sql/field.cc4
-rw-r--r--sql/field.h2
-rw-r--r--sql/filesort.cc3
-rw-r--r--sql/gen_lex_hash.cc2
-rw-r--r--sql/ha_ndbcluster.cc10
-rw-r--r--sql/ha_ndbcluster_binlog.cc19
-rw-r--r--sql/ha_partition.cc40
-rw-r--r--sql/ha_partition.h8
-rw-r--r--sql/handler.cc2
-rw-r--r--sql/handler.h2
-rw-r--r--sql/item.cc5
-rw-r--r--sql/item.h2
-rw-r--r--sql/item_cmpfunc.cc28
-rw-r--r--sql/item_func.cc2
-rw-r--r--sql/item_func.h7
-rw-r--r--sql/item_strfunc.cc13
-rw-r--r--sql/item_sum.cc3
-rw-r--r--sql/item_timefunc.cc41
-rw-r--r--sql/item_timefunc.h18
-rw-r--r--sql/lock.cc2
-rw-r--r--sql/log.cc321
-rw-r--r--sql/log.h11
-rw-r--r--sql/log_event.cc119
-rw-r--r--sql/log_event.h69
-rw-r--r--sql/mysql_priv.h12
-rw-r--r--sql/mysqld.cc67
-rw-r--r--sql/opt_range.cc31
-rw-r--r--sql/partition_info.cc1
-rw-r--r--sql/partition_info.h2
-rw-r--r--sql/repl_failsafe.cc10
-rw-r--r--sql/rpl_constants.h4
-rw-r--r--sql/rpl_rli.cc1
-rw-r--r--sql/set_var.cc14
-rw-r--r--sql/slave.cc39
-rw-r--r--sql/sp_head.cc2
-rw-r--r--sql/sql_acl.cc123
-rw-r--r--sql/sql_base.cc25
-rw-r--r--sql/sql_binlog.cc5
-rw-r--r--sql/sql_cache.cc2
-rw-r--r--sql/sql_class.cc3
-rw-r--r--sql/sql_class.h22
-rw-r--r--sql/sql_cursor.cc18
-rw-r--r--sql/sql_db.cc1
-rw-r--r--sql/sql_delete.cc43
-rw-r--r--sql/sql_insert.cc2
-rw-r--r--sql/sql_lex.cc2
-rw-r--r--sql/sql_lex.h11
-rw-r--r--sql/sql_locale.cc436
-rw-r--r--sql/sql_parse.cc24
-rw-r--r--sql/sql_partition.cc35
-rw-r--r--sql/sql_plugin.cc42
-rw-r--r--sql/sql_plugin.h1
-rw-r--r--sql/sql_profile.cc4
-rw-r--r--sql/sql_repl.cc125
-rw-r--r--sql/sql_select.cc19
-rw-r--r--sql/sql_select.h6
-rw-r--r--sql/sql_show.cc85
-rw-r--r--sql/sql_show.h2
-rw-r--r--sql/sql_table.cc50
-rw-r--r--sql/sql_test.cc2
-rw-r--r--sql/sql_trigger.cc88
-rw-r--r--sql/sql_trigger.h6
-rw-r--r--sql/sql_union.cc2
-rw-r--r--sql/sql_update.cc2
-rw-r--r--sql/sql_yacc.yy2
-rw-r--r--sql/table.cc29
-rw-r--r--sql/table.h32
-rw-r--r--sql/unireg.cc26
71 files changed, 1526 insertions, 671 deletions
diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc
index 868e59a8777..8faab5023da 100644
--- a/sql/event_db_repository.cc
+++ b/sql/event_db_repository.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004-2006 MySQL AB
+/* Copyright 2004-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/event_parse_data.cc b/sql/event_parse_data.cc
index df419e92d0d..63ecc3006dd 100644
--- a/sql/event_parse_data.cc
+++ b/sql/event_parse_data.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2003 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/event_parse_data.h b/sql/event_parse_data.h
index 87a800c2078..8b42eb23937 100644
--- a/sql/event_parse_data.h
+++ b/sql/event_parse_data.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2003 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/field.cc b/sql/field.cc
index 75f2fc7ac47..a278c125df2 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2006 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -3836,7 +3836,7 @@ int Field_longlong::store(double nr)
error= 1;
}
else
- res=(longlong) (ulonglong) nr;
+ res=(longlong) double2ulonglong(nr);
}
else
{
diff --git a/sql/field.h b/sql/field.h
index 364d8fd22db..ac8e7dae3c5 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2006 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/filesort.cc b/sql/filesort.cc
index 0ddb9ae5b10..dc59f1c8fcd 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -562,10 +562,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
if (quick_select)
{
if ((error= select->quick->get_next()))
- {
- error= HA_ERR_END_OF_FILE;
break;
- }
file->position(sort_form->record[0]);
DBUG_EXECUTE_IF("debug_filesort", dbug_print_record(sort_form, TRUE););
}
diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc
index 7b2395673eb..214ee4c99d2 100644
--- a/sql/gen_lex_hash.cc
+++ b/sql/gen_lex_hash.cc
@@ -451,7 +451,7 @@ int main(int argc,char **argv)
printf("/*\n\n Do " "not " "edit " "this " "file " "directly!\n\n*/\n");
printf("\
-/* Copyright (C) 2001-2004 MySQL AB\n\
+/* Copyright 2001-2008 MySQL AB, 2008 Sun Microsystems, Inc.\n\
\n\
This program is free software; you can redistribute it and/or modify\n\
it under the terms of the GNU General Public License as published by\n\
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 6fb16912f3a..9be4bfba9ab 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -5211,6 +5211,7 @@ int ha_ndbcluster::create(const char *name,
strcmp(m_tabname, NDB_SCHEMA_TABLE) == 0))
{
DBUG_PRINT("info", ("Schema distribution table not setup"));
+ DBUG_ASSERT(ndb_schema_share);
DBUG_RETURN(HA_ERR_NO_CONNECTION);
}
single_user_mode = NdbDictionary::Table::SingleUserModeReadWrite;
@@ -6038,6 +6039,7 @@ ha_ndbcluster::delete_table(ha_ndbcluster *h, Ndb *ndb,
if (!ndb_schema_share)
{
DBUG_PRINT("info", ("Schema distribution table not setup"));
+ DBUG_ASSERT(ndb_schema_share);
DBUG_RETURN(HA_ERR_NO_CONNECTION);
}
/* ndb_share reference temporary */
@@ -6219,6 +6221,7 @@ int ha_ndbcluster::delete_table(const char *name)
if (!ndb_schema_share)
{
DBUG_PRINT("info", ("Schema distribution table not setup"));
+ DBUG_ASSERT(ndb_schema_share);
DBUG_RETURN(HA_ERR_NO_CONNECTION);
}
#endif
@@ -6506,8 +6509,11 @@ int ha_ndbcluster::open(const char *name, int mode, uint test_if_locked)
DBUG_RETURN(res);
}
#ifdef HAVE_NDB_BINLOG
- if (!ndb_binlog_tables_inited && ndb_binlog_running)
+ if (!ndb_binlog_tables_inited)
+ {
table->db_stat|= HA_READ_ONLY;
+ sql_print_information("table '%s' opened read only", name);
+ }
#endif
DBUG_RETURN(0);
}
@@ -6871,8 +6877,8 @@ static void ndbcluster_drop_database(handlerton *hton, char *path)
if (!ndb_schema_share)
{
DBUG_PRINT("info", ("Schema distribution table not setup"));
+ DBUG_ASSERT(ndb_schema_share);
DBUG_VOID_RETURN;
- //DBUG_RETURN(HA_ERR_NO_CONNECTION);
}
#endif
ndbcluster_drop_database_impl(path);
diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc
index 1788fed26b1..4f25068feb8 100644
--- a/sql/ha_ndbcluster_binlog.cc
+++ b/sql/ha_ndbcluster_binlog.cc
@@ -815,9 +815,10 @@ static int ndbcluster_create_ndb_apply_status_table(THD *thd)
" end_pos BIGINT UNSIGNED NOT NULL, "
" PRIMARY KEY USING HASH (server_id) ) ENGINE=NDB CHARACTER SET latin1");
- const int no_print_error[5]= {ER_TABLE_EXISTS_ERROR,
+ const int no_print_error[6]= {ER_TABLE_EXISTS_ERROR,
701,
702,
+ 721, // Table already exist
4009,
0}; // do not print error 701 etc
run_query(thd, buf, end, no_print_error, TRUE);
@@ -876,9 +877,10 @@ static int ndbcluster_create_schema_table(THD *thd)
" type INT UNSIGNED NOT NULL,"
" PRIMARY KEY USING HASH (db,name) ) ENGINE=NDB CHARACTER SET latin1");
- const int no_print_error[5]= {ER_TABLE_EXISTS_ERROR,
+ const int no_print_error[6]= {ER_TABLE_EXISTS_ERROR,
701,
702,
+ 721, // Table already exist
4009,
0}; // do not print error 701 etc
run_query(thd, buf, end, no_print_error, TRUE);
@@ -919,12 +921,9 @@ int ndbcluster_setup_binlog_table_shares(THD *thd)
{
pthread_mutex_lock(&LOCK_open);
ndb_binlog_tables_inited= TRUE;
- if (ndb_binlog_running)
- {
- if (ndb_extra_logging)
- sql_print_information("NDB Binlog: ndb tables writable");
- close_cached_tables(NULL, NULL, TRUE, FALSE, FALSE);
- }
+ if (ndb_extra_logging)
+ sql_print_information("NDB Binlog: ndb tables writable");
+ close_cached_tables(NULL, NULL, TRUE, FALSE, FALSE);
pthread_mutex_unlock(&LOCK_open);
/* Signal injector thread that all is setup */
pthread_cond_signal(&injector_cond);
@@ -2071,6 +2070,7 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb,
ndb_schema_share->use_count));
free_share(&ndb_schema_share);
ndb_schema_share= 0;
+ ndb_binlog_tables_inited= 0;
pthread_mutex_unlock(&ndb_schema_share_mutex);
/* end protect ndb_schema_share */
@@ -3271,6 +3271,7 @@ ndb_binlog_thread_handle_non_data_event(THD *thd, Ndb *ndb,
share->key, share->use_count));
free_share(&ndb_apply_status_share);
ndb_apply_status_share= 0;
+ ndb_binlog_tables_inited= 0;
}
DBUG_PRINT("error", ("CLUSTER FAILURE EVENT: "
"%s received share: 0x%lx op: 0x%lx share op: 0x%lx "
@@ -3290,6 +3291,7 @@ ndb_binlog_thread_handle_non_data_event(THD *thd, Ndb *ndb,
share->key, share->use_count));
free_share(&ndb_apply_status_share);
ndb_apply_status_share= 0;
+ ndb_binlog_tables_inited= 0;
}
/* ToDo: remove printout */
if (ndb_extra_logging)
@@ -4313,6 +4315,7 @@ err:
ndb_schema_share->use_count));
free_share(&ndb_schema_share);
ndb_schema_share= 0;
+ ndb_binlog_tables_inited= 0;
pthread_mutex_unlock(&ndb_schema_share_mutex);
/* end protect ndb_schema_share */
}
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index fb24d1d57db..40c363f0182 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005 MySQL AB
+/* Copyright 2005-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -2818,6 +2818,36 @@ void ha_partition::unlock_row()
DBUG_VOID_RETURN;
}
+/**
+ Check if semi consistent read was used
+
+ SYNOPSIS
+ was_semi_consistent_read()
+
+ RETURN VALUE
+ TRUE Previous read was a semi consistent read
+ FALSE Previous read was not a semi consistent read
+
+ DESCRIPTION
+ See handler.h:
+ In an UPDATE or DELETE, if the row under the cursor was locked by another
+ transaction, and the engine used an optimistic read of the last
+ committed row value under the cursor, then the engine returns 1 from this
+ function. MySQL must NOT try to update this optimistic value. If the
+ optimistic value does not match the WHERE condition, MySQL can decide to
+ skip over this row. Currently only works for InnoDB. This can be used to
+ avoid unnecessary lock waits.
+
+ If this method returns nonzero, it will also signal the storage
+ engine that the next read will be a locking re-read of the row.
+*/
+bool ha_partition::was_semi_consistent_read()
+{
+ DBUG_ENTER("ha_partition::was_semi_consistent_read");
+ DBUG_ASSERT(m_last_part < m_tot_parts &&
+ bitmap_is_set(&(m_part_info->used_partitions), m_last_part));
+ DBUG_RETURN(m_file[m_last_part]->was_semi_consistent_read());
+}
/**
Use semi consistent read if possible
@@ -3432,7 +3462,7 @@ int ha_partition::rnd_next(uchar *buf)
while (TRUE)
{
- int result= file->rnd_next(buf);
+ result= file->rnd_next(buf);
if (!result)
{
m_last_part= part_id;
@@ -4786,7 +4816,7 @@ int ha_partition::info(uint flag)
/*
Calculates statistical variables
records: Estimate of number records in table
- We report sum (always at least 2)
+ We report sum (always at least 2 if not empty)
deleted: Estimate of number holes in the table due to
deletes
We report sum
@@ -4825,13 +4855,13 @@ int ha_partition::info(uint flag)
stats.check_time= file->stats.check_time;
}
} while (*(++file_array));
- if (stats.records < 2 &&
+ if (stats.records && stats.records < 2 &&
!(m_file[0]->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT))
stats.records= 2;
if (stats.records > 0)
stats.mean_rec_length= (ulong) (stats.data_file_length / stats.records);
else
- stats.mean_rec_length= 1; //? What should we set here
+ stats.mean_rec_length= 0;
}
if (flag & HA_STATUS_CONST)
{
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index b22e7bd1801..3a7084c87ed 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005 MySQL AB
+/* Copyright 2005-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -112,7 +112,7 @@ private:
uint m_reorged_parts; // Number of reorganised parts
uint m_tot_parts; // Total number of partitions;
uint m_no_locks; // For engines like ha_blackhole, which needs no locks
- uint m_last_part; // Last file that we update,write
+ uint m_last_part; // Last file that we update,write,read
int m_lock_type; // Remembers type of last
// external_lock
part_id_range m_part_spec; // Which parts to scan
@@ -326,6 +326,10 @@ public:
*/
virtual void unlock_row();
/*
+ Check if semi consistent read
+ */
+ virtual bool was_semi_consistent_read();
+ /*
Call to hint about semi consistent read
*/
virtual void try_semi_consistent_read(bool);
diff --git a/sql/handler.cc b/sql/handler.cc
index 044e47b3f6d..4291bc02dcc 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2006 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/handler.h b/sql/handler.h
index 68bb894a5d2..02fef2760f1 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2006 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/item.cc b/sql/item.cc
index 2882c3cc28a..be62ebb4688 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2006 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -5110,6 +5110,9 @@ int Item_hex_string::save_in_field(Field *field, bool no_conversions)
ulonglong nr;
uint32 length= str_value.length();
+ if (!length)
+ return 1;
+
if (length > 8)
{
nr= field->flags & UNSIGNED_FLAG ? ULONGLONG_MAX : LONGLONG_MAX;
diff --git a/sql/item.h b/sql/item.h
index c46a3322d94..8327f938a8f 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2006 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index adcc2e352db..0d4ae3539c5 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -394,19 +394,16 @@ static bool convert_constant_item(THD *thd, Item_field *field_item,
TABLE *table= field->table;
ulong orig_sql_mode= thd->variables.sql_mode;
enum_check_fields orig_count_cuted_fields= thd->count_cuted_fields;
- my_bitmap_map *old_write_map;
- my_bitmap_map *old_read_map;
+ my_bitmap_map *old_maps[2];
ulonglong orig_field_val; /* original field value if valid */
- LINT_INIT(old_write_map);
- LINT_INIT(old_read_map);
+ LINT_INIT(old_maps[0]);
+ LINT_INIT(old_maps[1]);
LINT_INIT(orig_field_val);
if (table)
- {
- old_write_map= dbug_tmp_use_all_columns(table, table->write_set);
- old_read_map= dbug_tmp_use_all_columns(table, table->read_set);
- }
+ dbug_tmp_use_all_columns(table, old_maps,
+ table->read_set, table->write_set);
/* For comparison purposes allow invalid dates like 2000-01-32 */
thd->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) |
MODE_INVALID_DATES;
@@ -441,10 +438,7 @@ static bool convert_constant_item(THD *thd, Item_field *field_item,
thd->variables.sql_mode= orig_sql_mode;
thd->count_cuted_fields= orig_count_cuted_fields;
if (table)
- {
- dbug_tmp_restore_column_map(table->write_set, old_write_map);
- dbug_tmp_restore_column_map(table->read_set, old_read_map);
- }
+ dbug_tmp_restore_column_maps(table->read_set, table->write_set, old_maps);
}
return result;
}
@@ -2718,6 +2712,16 @@ void Item_func_case::fix_length_and_dec()
nagg++;
if (!(found_types= collect_cmp_types(agg, nagg)))
return;
+ if (with_sum_func || current_thd->lex->current_select->group_list.elements)
+ {
+ /*
+ See TODO commentary in the setup_copy_fields function:
+ item in a group may be wrapped with an Item_copy_string item.
+ That item has a STRING_RESULT result type, so we need
+ to take this type into account.
+ */
+ found_types |= (1 << item_cmp_type(left_result_type, STRING_RESULT));
+ }
for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
{
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 1f3af312321..ee00d45ecb8 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2003 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/item_func.h b/sql/item_func.h
index 070f24d343c..322128598e6 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2006 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -362,7 +362,10 @@ public:
Item_func_unsigned(Item *a) :Item_func_signed(a) {}
const char *func_name() const { return "cast_as_unsigned"; }
void fix_length_and_dec()
- { max_length=args[0]->max_length; unsigned_flag=1; }
+ {
+ max_length= min(args[0]->max_length, DECIMAL_MAX_PRECISION + 2);
+ unsigned_flag=1;
+ }
longlong val_int();
virtual void print(String *str, enum_query_type query_type);
};
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 5f70bff595a..cf2453e13ec 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1782,6 +1782,12 @@ Item *Item_func_sysconst::safe_charset_converter(CHARSET_INFO *tocs)
Item_string *conv;
uint conv_errors;
String tmp, cstr, *ostr= val_str(&tmp);
+ if (null_value)
+ {
+ Item *null_item= new Item_null((char *) fully_qualified_func_name());
+ null_item->collation.set (tocs);
+ return null_item;
+ }
cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors);
if (conv_errors ||
!(conv= new Item_static_string_func(fully_qualified_func_name(),
@@ -2033,10 +2039,11 @@ Item_func_format::Item_func_format(Item *org, Item *dec)
void Item_func_format::fix_length_and_dec()
{
- collation.set(default_charset());
uint char_length= args[0]->max_length/args[0]->collation.collation->mbmaxlen;
- max_length= ((char_length + (char_length-args[0]->decimals)/3) *
- collation.collation->mbmaxlen);
+ uint max_sep_count= char_length/3 + (decimals ? 1 : 0) + /*sign*/1;
+ collation.set(default_charset());
+ max_length= (char_length + max_sep_count + decimals) *
+ collation.collation->mbmaxlen;
}
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 1b399ede327..bae01542d5c 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -654,8 +654,7 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
return TRUE;
// 'item' can be changed during fix_fields
- if ((!item->fixed &&
- item->fix_fields(thd, args)) ||
+ if ((!item->fixed && item->fix_fields(thd, args)) ||
(item= args[0])->check_cols(1))
return TRUE;
decimals=item->decimals;
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index a584f983516..deffb0d56ca 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -1034,12 +1034,25 @@ longlong Item_func_month::val_int()
}
+void Item_func_monthname::fix_length_and_dec()
+{
+ THD* thd= current_thd;
+ CHARSET_INFO *cs= thd->variables.collation_connection;
+ uint32 repertoire= my_charset_repertoire(cs);
+ locale= thd->variables.lc_time_names;
+ collation.set(cs, DERIVATION_COERCIBLE, repertoire);
+ decimals=0;
+ max_length= locale->max_month_name_length * collation.collation->mbmaxlen;
+ maybe_null=1;
+}
+
+
String* Item_func_monthname::val_str(String* str)
{
DBUG_ASSERT(fixed == 1);
const char *month_name;
- uint month= (uint) val_int();
- THD *thd= current_thd;
+ uint month= (uint) val_int();
+ uint err;
if (null_value || !month)
{
@@ -1047,8 +1060,9 @@ String* Item_func_monthname::val_str(String* str)
return (String*) 0;
}
null_value=0;
- month_name= thd->variables.lc_time_names->month_names->type_names[month-1];
- str->set(month_name, strlen(month_name), system_charset_info);
+ month_name= locale->month_names->type_names[month-1];
+ str->copy(month_name, strlen(month_name), &my_charset_utf8_bin,
+ collation.collation, &err);
return str;
}
@@ -1173,19 +1187,32 @@ longlong Item_func_weekday::val_int()
odbc_type) + test(odbc_type);
}
+void Item_func_dayname::fix_length_and_dec()
+{
+ THD* thd= current_thd;
+ CHARSET_INFO *cs= thd->variables.collation_connection;
+ uint32 repertoire= my_charset_repertoire(cs);
+ locale= thd->variables.lc_time_names;
+ collation.set(cs, DERIVATION_COERCIBLE, repertoire);
+ decimals=0;
+ max_length= locale->max_day_name_length * collation.collation->mbmaxlen;
+ maybe_null=1;
+}
+
String* Item_func_dayname::val_str(String* str)
{
DBUG_ASSERT(fixed == 1);
uint weekday=(uint) val_int(); // Always Item_func_daynr()
const char *day_name;
- THD *thd= current_thd;
+ uint err;
if (null_value)
return (String*) 0;
- day_name= thd->variables.lc_time_names->day_names->type_names[weekday];
- str->set(day_name, strlen(day_name), system_charset_info);
+ day_name= locale->day_names->type_names[weekday];
+ str->copy(day_name, strlen(day_name), &my_charset_utf8_bin,
+ collation.collation, &err);
return str;
}
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 99240b1c759..94b02d1eaf6 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -116,18 +116,13 @@ public:
class Item_func_monthname :public Item_func_month
{
+ MY_LOCALE *locale;
public:
Item_func_monthname(Item *a) :Item_func_month(a) {}
const char *func_name() const { return "monthname"; }
String *val_str(String *str);
enum Item_result result_type () const { return STRING_RESULT; }
- void fix_length_and_dec()
- {
- collation.set(&my_charset_bin);
- decimals=0;
- max_length=10*my_charset_bin.mbmaxlen;
- maybe_null=1;
- }
+ void fix_length_and_dec();
bool check_partition_func_processor(uchar *int_arg) {return TRUE;}
};
@@ -291,18 +286,13 @@ public:
class Item_func_dayname :public Item_func_weekday
{
+ MY_LOCALE *locale;
public:
Item_func_dayname(Item *a) :Item_func_weekday(a,0) {}
const char *func_name() const { return "dayname"; }
String *val_str(String *str);
enum Item_result result_type () const { return STRING_RESULT; }
- void fix_length_and_dec()
- {
- collation.set(&my_charset_bin);
- decimals=0;
- max_length=9*MY_CHARSET_BIN_MB_MAXLEN;
- maybe_null=1;
- }
+ void fix_length_and_dec();
bool check_partition_func_processor(uchar *int_arg) {return TRUE;}
};
diff --git a/sql/lock.cc b/sql/lock.cc
index 21255fb24b0..8f58dd6ee86 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2006 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/log.cc b/sql/log.cc
index aa027108490..91fe42b4412 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2003 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -207,6 +207,7 @@ public:
truncate(0);
before_stmt_pos= MY_OFF_T_UNDEF;
trans_log.end_of_file= max_binlog_cache_size;
+ DBUG_ASSERT(empty());
}
Rows_log_event *pending() const
@@ -1377,8 +1378,6 @@ binlog_end_trans(THD *thd, binlog_trx_data *trx_data,
FLAGSTR(thd->options, OPTION_NOT_AUTOCOMMIT),
FLAGSTR(thd->options, OPTION_BEGIN)));
- thd->binlog_flush_pending_rows_event(TRUE);
-
/*
NULL denotes ROLLBACK with nothing to replicate: i.e., rollback of
only transactional tables. If the transaction contain changes to
@@ -1387,6 +1386,7 @@ binlog_end_trans(THD *thd, binlog_trx_data *trx_data,
*/
if (end_ev != NULL)
{
+ thd->binlog_flush_pending_rows_event(TRUE);
/*
Doing a commit or a rollback including non-transactional tables,
i.e., ending a transaction where we might write the transaction
@@ -1435,6 +1435,7 @@ binlog_end_trans(THD *thd, binlog_trx_data *trx_data,
mysql_bin_log.update_table_map_version();
}
+ DBUG_ASSERT(thd->binlog_get_pending_rows_event() == NULL);
DBUG_RETURN(error);
}
@@ -1449,8 +1450,6 @@ static int binlog_prepare(handlerton *hton, THD *thd, bool all)
return 0;
}
-#define YESNO(X) ((X) ? "yes" : "no")
-
/**
This function is called once after each statement.
@@ -1466,6 +1465,7 @@ static int binlog_prepare(handlerton *hton, THD *thd, bool all)
*/
static int binlog_commit(handlerton *hton, THD *thd, bool all)
{
+ int error= 0;
DBUG_ENTER("binlog_commit");
binlog_trx_data *const trx_data=
(binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
@@ -1478,60 +1478,11 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all)
}
/*
- Decision table for committing a transaction. The top part, the
- *conditions* represent different cases that can occur, and hte
- bottom part, the *actions*, represent what should be done in that
- particular case.
-
- Real transaction 'all' was true
-
- Statement in cache There were at least one statement in the
- transaction cache
-
- In transaction We are inside a transaction
-
- Stmt modified non-trans The statement being committed modified a
- non-transactional table
-
- All modified non-trans Some statement before this one in the
- transaction modified a non-transactional
- table
-
-
- ============================= = = = = = = = = = = = = = = = =
- Real transaction N N N N N N N N N N N N N N N N
- Statement in cache N N N N N N N N Y Y Y Y Y Y Y Y
- In transaction N N N N Y Y Y Y N N N N Y Y Y Y
- Stmt modified non-trans N N Y Y N N Y Y N N Y Y N N Y Y
- All modified non-trans N Y N Y N Y N Y N Y N Y N Y N Y
-
- Action: (C)ommit/(A)ccumulate C C - C A C - C - - - - A A - A
- ============================= = = = = = = = = = = = = = = = =
+ We commit the transaction if:
+ - We are not in a transaction and committing a statement, or
- ============================= = = = = = = = = = = = = = = = =
- Real transaction Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
- Statement in cache N N N N N N N N Y Y Y Y Y Y Y Y
- In transaction N N N N Y Y Y Y N N N N Y Y Y Y
- Stmt modified non-trans N N Y Y N N Y Y N N Y Y N N Y Y
- All modified non-trans N Y N Y N Y N Y N Y N Y N Y N Y
-
- (C)ommit/(A)ccumulate/(-) - - - - C C - C - - - - C C - C
- ============================= = = = = = = = = = = = = = = = =
-
- In other words, we commit the transaction if and only if both of
- the following are true:
- - We are not in a transaction and committing a statement
-
- - We are in a transaction and one (or more) of the following are
- true:
-
- - A full transaction is committed
-
- OR
-
- - A non-transactional statement is committed and there is
- no statement cached
+ - We are in a transaction and a full transaction is committed
Otherwise, we accumulate the statement
*/
@@ -1544,25 +1495,18 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all)
YESNO(in_transaction),
YESNO(thd->transaction.all.modified_non_trans_table),
YESNO(thd->transaction.stmt.modified_non_trans_table)));
- if (thd->options & OPTION_BIN_LOG)
+ if (!in_transaction || all)
{
- if ((in_transaction &&
- (all ||
- (!trx_data->at_least_one_stmt &&
- thd->transaction.stmt.modified_non_trans_table))) ||
- (!in_transaction && !all))
- {
- Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, FALSE);
- qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE)
- int error= binlog_end_trans(thd, trx_data, &qev, all);
- DBUG_RETURN(error);
- }
- }
- else
- {
- trx_data->reset();
+ Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, FALSE);
+ qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE)
+ error= binlog_end_trans(thd, trx_data, &qev, all);
+ goto end;
}
- DBUG_RETURN(0);
+
+end:
+ if (!all)
+ trx_data->before_stmt_pos = MY_OFF_T_UNDEF; // part of the stmt commit
+ DBUG_RETURN(error);
}
/**
@@ -1622,6 +1566,8 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all)
*/
error= binlog_end_trans(thd, trx_data, 0, all);
}
+ if (!all)
+ trx_data->before_stmt_pos = MY_OFF_T_UNDEF; // part of the stmt rollback
DBUG_RETURN(error);
}
@@ -2356,6 +2302,7 @@ const char *MYSQL_LOG::generate_name(const char *log_name,
MYSQL_BIN_LOG::MYSQL_BIN_LOG()
:bytes_written(0), prepared_xids(0), file_id(1), open_count(1),
need_start_event(TRUE), m_table_map_version(0),
+ is_relay_log(0),
description_event_for_exec(0), description_event_for_queue(0)
{
/*
@@ -2366,6 +2313,7 @@ MYSQL_BIN_LOG::MYSQL_BIN_LOG()
*/
index_file_name[0] = 0;
bzero((char*) &index_file, sizeof(index_file));
+ bzero((char*) &purge_temp, sizeof(purge_temp));
}
/* this is called only once */
@@ -2558,7 +2506,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
*/
description_event_for_queue->created= 0;
/* Don't set log_pos in event header */
- description_event_for_queue->artificial_event=1;
+ description_event_for_queue->set_artificial_event();
if (description_event_for_queue->write(&log_file))
goto err;
@@ -2965,6 +2913,7 @@ err:
int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included)
{
int error;
+ char *to_purge_if_included= NULL;
DBUG_ENTER("purge_first_log");
DBUG_ASSERT(is_open());
@@ -2972,36 +2921,20 @@ int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included)
DBUG_ASSERT(!strcmp(rli->linfo.log_file_name,rli->event_relay_log_name));
pthread_mutex_lock(&LOCK_index);
- pthread_mutex_lock(&rli->log_space_lock);
- rli->relay_log.purge_logs(rli->group_relay_log_name, included,
- 0, 0, &rli->log_space_total);
- // Tell the I/O thread to take the relay_log_space_limit into account
- rli->ignore_log_space_limit= 0;
- pthread_mutex_unlock(&rli->log_space_lock);
+ to_purge_if_included= my_strdup(rli->group_relay_log_name, MYF(0));
/*
- Ok to broadcast after the critical region as there is no risk of
- the mutex being destroyed by this thread later - this helps save
- context switches
- */
- pthread_cond_broadcast(&rli->log_space_cond);
-
- /*
Read the next log file name from the index file and pass it back to
- the caller
- If included is true, we want the first relay log;
- otherwise we want the one after event_relay_log_name.
+ the caller.
*/
- if ((included && (error=find_log_pos(&rli->linfo, NullS, 0))) ||
- (!included &&
- ((error=find_log_pos(&rli->linfo, rli->event_relay_log_name, 0)) ||
- (error=find_next_log(&rli->linfo, 0)))))
+ if((error=find_log_pos(&rli->linfo, rli->event_relay_log_name, 0)) ||
+ (error=find_next_log(&rli->linfo, 0)))
{
char buff[22];
sql_print_error("next log error: %d offset: %s log: %s included: %d",
error,
llstr(rli->linfo.index_file_offset,buff),
- rli->group_relay_log_name,
+ rli->event_relay_log_name,
included);
goto err;
}
@@ -3029,7 +2962,42 @@ int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included)
/* Store where we are in the new file for the execution thread */
flush_relay_log_info(rli);
+ DBUG_EXECUTE_IF("crash_before_purge_logs", abort(););
+
+ pthread_mutex_lock(&rli->log_space_lock);
+ rli->relay_log.purge_logs(to_purge_if_included, included,
+ 0, 0, &rli->log_space_total);
+ // Tell the I/O thread to take the relay_log_space_limit into account
+ rli->ignore_log_space_limit= 0;
+ pthread_mutex_unlock(&rli->log_space_lock);
+
+ /*
+ Ok to broadcast after the critical region as there is no risk of
+ the mutex being destroyed by this thread later - this helps save
+ context switches
+ */
+ pthread_cond_broadcast(&rli->log_space_cond);
+
+ /*
+ * Need to update the log pos because purge logs has been called
+ * after fetching initially the log pos at the begining of the method.
+ */
+ if((error=find_log_pos(&rli->linfo, rli->event_relay_log_name, 0)))
+ {
+ char buff[22];
+ sql_print_error("next log error: %d offset: %s log: %s included: %d",
+ error,
+ llstr(rli->linfo.index_file_offset,buff),
+ rli->group_relay_log_name,
+ included);
+ goto err;
+ }
+
+ /* If included was passed, rli->linfo should be the first entry. */
+ DBUG_ASSERT(!included || rli->linfo.index_file_start_offset == 0);
+
err:
+ my_free(to_purge_if_included, MYF(0));
pthread_mutex_unlock(&LOCK_index);
DBUG_RETURN(error);
}
@@ -3080,7 +3048,6 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log,
ulonglong *decrease_log_space)
{
int error;
- int ret = 0;
bool exit_loop= 0;
LOG_INFO log_info;
THD *thd= current_thd;
@@ -3089,8 +3056,36 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log,
if (need_mutex)
pthread_mutex_lock(&LOCK_index);
- if ((error=find_log_pos(&log_info, to_log, 0 /*no mutex*/)))
+ if ((error=find_log_pos(&log_info, to_log, 0 /*no mutex*/)))
+ {
+ sql_print_error("MYSQL_LOG::purge_logs was called with file %s not "
+ "listed in the index.", to_log);
goto err;
+ }
+
+ /*
+ For crash recovery reasons the index needs to be updated before
+ any files are deleted. Move files to be deleted into a temp file
+ to be processed after the index is updated.
+ */
+ if (!my_b_inited(&purge_temp))
+ {
+ if ((error=open_cached_file(&purge_temp, mysql_tmpdir, TEMP_PREFIX,
+ DISK_BUFFER_SIZE, MYF(MY_WME))))
+ {
+ sql_print_error("MYSQL_LOG::purge_logs failed to open purge_temp");
+ goto err;
+ }
+ }
+ else
+ {
+ if ((error=reinit_io_cache(&purge_temp, WRITE_CACHE, 0, 0, 1)))
+ {
+ sql_print_error("MYSQL_LOG::purge_logs failed to reinit purge_temp "
+ "for write");
+ goto err;
+ }
+ }
/*
File name exists in index file; delete until we find this file
@@ -3101,6 +3096,61 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log,
while ((strcmp(to_log,log_info.log_file_name) || (exit_loop=included)) &&
!log_in_use(log_info.log_file_name))
{
+ if ((error=my_b_write(&purge_temp, (const uchar*)log_info.log_file_name,
+ strlen(log_info.log_file_name))) ||
+ (error=my_b_write(&purge_temp, (const uchar*)"\n", 1)))
+ {
+ sql_print_error("MYSQL_LOG::purge_logs failed to copy %s to purge_temp",
+ log_info.log_file_name);
+ goto err;
+ }
+
+ if (find_next_log(&log_info, 0) || exit_loop)
+ break;
+ }
+
+ /* We know how many files to delete. Update index file. */
+ if ((error=update_log_index(&log_info, need_update_threads)))
+ {
+ sql_print_error("MSYQL_LOG::purge_logs failed to update the index file");
+ goto err;
+ }
+
+ DBUG_EXECUTE_IF("crash_after_update_index", abort(););
+
+ /* Switch purge_temp for read. */
+ if ((error=reinit_io_cache(&purge_temp, READ_CACHE, 0, 0, 0)))
+ {
+ sql_print_error("MSYQL_LOG::purge_logs failed to reinit purge_temp "
+ "for read");
+ goto err;
+ }
+
+ /* Read each entry from purge_temp and delete the file. */
+ for (;;)
+ {
+ uint length;
+
+ if ((length=my_b_gets(&purge_temp, log_info.log_file_name,
+ FN_REFLEN)) <= 1)
+ {
+ if (purge_temp.error)
+ {
+ error= purge_temp.error;
+ sql_print_error("MSYQL_LOG::purge_logs error %d reading from "
+ "purge_temp", error);
+ goto err;
+ }
+
+ /* Reached EOF */
+ break;
+ }
+
+ /* Get rid of the trailing '\n' */
+ log_info.log_file_name[length-1]= 0;
+
+ ha_binlog_index_purge_file(current_thd, log_info.log_file_name);
+
MY_STAT s;
if (!my_stat(log_info.log_file_name, &s, MYF(0)))
{
@@ -3201,23 +3251,10 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log,
}
}
}
-
- ha_binlog_index_purge_file(current_thd, log_info.log_file_name);
-
- if (find_next_log(&log_info, 0) || exit_loop)
- break;
- }
-
- /*
- If we get killed -9 here, the sysadmin would have to edit
- the log index file after restart - otherwise, this should be safe
- */
- error= update_log_index(&log_info, need_update_threads);
- if (error == 0) {
- error = ret;
}
err:
+ close_cached_file(&purge_temp);
if (need_mutex)
pthread_mutex_unlock(&LOCK_index);
DBUG_RETURN(error);
@@ -3228,7 +3265,7 @@ err:
index file.
@param thd Thread pointer
- @param before_date Delete all log files before given date.
+ @param purge_time Delete all log files before given date.
@note
If any of the logs before the deleted one is in use,
@@ -3245,6 +3282,7 @@ err:
int MYSQL_BIN_LOG::purge_logs_before_date(time_t purge_time)
{
int error;
+ char to_log[FN_REFLEN];
LOG_INFO log_info;
MY_STAT stat_area;
THD *thd= current_thd;
@@ -3252,12 +3290,8 @@ int MYSQL_BIN_LOG::purge_logs_before_date(time_t purge_time)
DBUG_ENTER("purge_logs_before_date");
pthread_mutex_lock(&LOCK_index);
+ to_log[0]= 0;
- /*
- Delete until we find curren file
- or a file that is used or a file
- that is older than purge_time.
- */
if ((error=find_log_pos(&log_info, NullS, 0 /*no mutex*/)))
goto err;
@@ -3307,55 +3341,18 @@ int MYSQL_BIN_LOG::purge_logs_before_date(time_t purge_time)
}
else
{
- if (stat_area.st_mtime >= purge_time)
+ if (stat_area.st_mtime < purge_time)
+ strmake(to_log,
+ log_info.log_file_name,
+ sizeof(log_info.log_file_name));
+ else
break;
- if (my_delete(log_info.log_file_name, MYF(0)))
- {
- if (my_errno == ENOENT)
- {
- /* It's not fatal even if we can't delete a log file */
- if (thd)
- {
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
- log_info.log_file_name);
- }
- sql_print_information("Failed to delete file '%s'",
- log_info.log_file_name);
- my_errno= 0;
- }
- else
- {
- if (thd)
- {
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
- ER_BINLOG_PURGE_FATAL_ERR,
- "a problem with deleting %s; "
- "consider examining correspondence "
- "of your binlog index file "
- "to the actual binlog files",
- log_info.log_file_name);
- }
- else
- {
- sql_print_information("Failed to delete log file '%s'",
- log_info.log_file_name);
- }
- error= LOG_INFO_FATAL;
- goto err;
- }
- }
- ha_binlog_index_purge_file(current_thd, log_info.log_file_name);
}
if (find_next_log(&log_info, 0))
break;
}
- /*
- If we get killed -9 here, the sysadmin would have to edit
- the log index file after restart - otherwise, this should be safe
- */
- error= update_log_index(&log_info, 1);
+ error= (to_log[0] ? purge_logs(to_log, 1, 0, 1, (ulonglong *) 0) : 0);
err:
pthread_mutex_unlock(&LOCK_index);
@@ -3481,7 +3478,7 @@ void MYSQL_BIN_LOG::new_file_impl(bool need_lock)
to change base names at some point.
*/
Rotate_log_event r(new_name+dirname_length(new_name),
- 0, LOG_EVENT_OFFSET, 0);
+ 0, LOG_EVENT_OFFSET, is_relay_log ? Rotate_log_event::RELAY_LOG : 0);
r.write(&log_file);
bytes_written += r.data_written;
}
diff --git a/sql/log.h b/sql/log.h
index 891134a9762..d54df8add3b 100644
--- a/sql/log.h
+++ b/sql/log.h
@@ -233,6 +233,13 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG
pthread_cond_t update_cond;
ulonglong bytes_written;
IO_CACHE index_file;
+ /*
+ purge_temp is a temp file used in purge_logs so that the index file
+ can be updated before deleting files from disk, yielding better crash
+ recovery. It is created on demand the first time purge_logs is called
+ and then reused for subsequent calls. It is cleaned up in cleanup().
+ */
+ IO_CACHE purge_temp;
char index_file_name[FN_REFLEN];
/*
The max size before rotation (usable only if log_type == LOG_BIN: binary
@@ -274,6 +281,10 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG
public:
MYSQL_LOG::generate_name;
MYSQL_LOG::is_open;
+
+ /* This is relay log */
+ bool is_relay_log;
+
/*
These describe the log's format. This is used only for relay logs.
_for_exec is used by the SQL thread, _for_queue by the I/O thread. It's
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 87fe707ac09..28398709a9f 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2004 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -809,9 +809,8 @@ bool Log_event::write_header(IO_CACHE* file, ulong event_data_length)
if (is_artificial_event())
{
/*
- We should not do any cleanup on slave when reading this. We
- mark this by setting log_pos to 0. Start_log_event_v3() will
- detect this on reading and set artificial_event=1 for the event.
+ Artificial events are automatically generated and do not exist
+ in master's binary log, so log_pos should be set to 0.
*/
log_pos= 0;
}
@@ -2679,7 +2678,7 @@ void Query_log_event::print_query_header(IO_CACHE* file,
if (!(flags & LOG_EVENT_SUPPRESS_USE_F) && db)
{
- if (different_db= memcmp(print_event_info->db, db, db_len + 1))
+ if ((different_db= memcmp(print_event_info->db, db, db_len + 1)))
memcpy(print_event_info->db, db, db_len + 1);
if (db[0] && different_db)
my_b_printf(file, "use %s%s\n", db, print_event_info->delimiter);
@@ -2723,11 +2722,13 @@ void Query_log_event::print_query_header(IO_CACHE* file,
bool need_comma= 0;
my_b_printf(file, "SET ");
print_set_option(file, tmp, OPTION_NO_FOREIGN_KEY_CHECKS, ~flags2,
- "@@session.foreign_key_checks", &need_comma);
+ "@@session.foreign_key_checks", &need_comma);
print_set_option(file, tmp, OPTION_AUTO_IS_NULL, flags2,
- "@@session.sql_auto_is_null", &need_comma);
+ "@@session.sql_auto_is_null", &need_comma);
print_set_option(file, tmp, OPTION_RELAXED_UNIQUE_CHECKS, ~flags2,
- "@@session.unique_checks", &need_comma);
+ "@@session.unique_checks", &need_comma);
+ print_set_option(file, tmp, OPTION_NOT_AUTOCOMMIT, ~flags2,
+ "@@session.autocommit", &need_comma);
my_b_printf(file,"%s\n", print_event_info->delimiter);
print_event_info->flags2= flags2;
}
@@ -3195,7 +3196,7 @@ Query_log_event::do_shall_skip(Relay_log_info *rli)
#ifndef MYSQL_CLIENT
Start_log_event_v3::Start_log_event_v3()
:Log_event(), created(0), binlog_version(BINLOG_VERSION),
- artificial_event(0), dont_set_created(0)
+ dont_set_created(0)
{
memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
}
@@ -3243,7 +3244,7 @@ void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
my_b_printf(&cache, "# Warning: this binlog was not closed properly. "
"Most probably mysqld crashed writing it.\n");
}
- if (!artificial_event && created)
+ if (!is_artificial_event() && created)
{
#ifdef WHEN_WE_HAVE_THE_RESET_CONNECTION_SQL_COMMAND
/*
@@ -3286,8 +3287,6 @@ Start_log_event_v3::Start_log_event_v3(const char* buf,
// prevent overrun if log is corrupted on disk
server_version[ST_SERVER_VER_LEN-1]= 0;
created= uint4korr(buf+ST_CREATED_OFFSET);
- /* We use log_pos to mark if this was an artificial event or not */
- artificial_event= (log_pos == 0);
dont_set_created= 1;
}
@@ -3424,7 +3423,8 @@ Format_description_log_event(uint8 binlog_ver, const char* server_ver)
number_of_event_types= LOG_EVENT_TYPES;
/* we'll catch my_malloc() error in is_valid() */
post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8),
- MYF(MY_ZEROFILL));
+ MYF(0));
+
/*
This long list of assignments is not beautiful, but I see no way to
make it nicer, as the right members are #defines, not array members, so
@@ -3432,16 +3432,40 @@ Format_description_log_event(uint8 binlog_ver, const char* server_ver)
*/
if (post_header_len)
{
+ // Allows us to sanity-check that all events initialized their
+ // events (see the end of this 'if' block).
+ IF_DBUG(memset(post_header_len, 255,
+ number_of_event_types*sizeof(uint8)););
+
+ /* Note: all event types must explicitly fill in their lengths here. */
post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN;
post_header_len[QUERY_EVENT-1]= QUERY_HEADER_LEN;
+ post_header_len[STOP_EVENT-1]= STOP_HEADER_LEN;
post_header_len[ROTATE_EVENT-1]= ROTATE_HEADER_LEN;
+ post_header_len[INTVAR_EVENT-1]= INTVAR_HEADER_LEN;
post_header_len[LOAD_EVENT-1]= LOAD_HEADER_LEN;
+ post_header_len[SLAVE_EVENT-1]= SLAVE_HEADER_LEN;
post_header_len[CREATE_FILE_EVENT-1]= CREATE_FILE_HEADER_LEN;
post_header_len[APPEND_BLOCK_EVENT-1]= APPEND_BLOCK_HEADER_LEN;
post_header_len[EXEC_LOAD_EVENT-1]= EXEC_LOAD_HEADER_LEN;
post_header_len[DELETE_FILE_EVENT-1]= DELETE_FILE_HEADER_LEN;
- post_header_len[NEW_LOAD_EVENT-1]= post_header_len[LOAD_EVENT-1];
+ post_header_len[NEW_LOAD_EVENT-1]= NEW_LOAD_HEADER_LEN;
+ post_header_len[RAND_EVENT-1]= RAND_HEADER_LEN;
+ post_header_len[USER_VAR_EVENT-1]= USER_VAR_HEADER_LEN;
post_header_len[FORMAT_DESCRIPTION_EVENT-1]= FORMAT_DESCRIPTION_HEADER_LEN;
+ post_header_len[XID_EVENT-1]= XID_HEADER_LEN;
+ post_header_len[BEGIN_LOAD_QUERY_EVENT-1]= BEGIN_LOAD_QUERY_HEADER_LEN;
+ post_header_len[EXECUTE_LOAD_QUERY_EVENT-1]= EXECUTE_LOAD_QUERY_HEADER_LEN;
+ /*
+ The PRE_GA events are never be written to any binlog, but
+ their lengths are included in Format_description_log_event.
+ Hence, we need to be assign some value here, to avoid reading
+ uninitialized memory when the array is written to disk.
+ */
+ post_header_len[PRE_GA_WRITE_ROWS_EVENT-1] = 0;
+ post_header_len[PRE_GA_UPDATE_ROWS_EVENT-1] = 0;
+ post_header_len[PRE_GA_DELETE_ROWS_EVENT-1] = 0;
+
post_header_len[TABLE_MAP_EVENT-1]= TABLE_MAP_HEADER_LEN;
post_header_len[WRITE_ROWS_EVENT-1]= ROWS_HEADER_LEN;
post_header_len[UPDATE_ROWS_EVENT-1]= ROWS_HEADER_LEN;
@@ -3461,9 +3485,14 @@ Format_description_log_event(uint8 binlog_ver, const char* server_ver)
post_header_len[WRITE_ROWS_EVENT-1]=
post_header_len[UPDATE_ROWS_EVENT-1]=
post_header_len[DELETE_ROWS_EVENT-1]= 6;);
- post_header_len[BEGIN_LOAD_QUERY_EVENT-1]= post_header_len[APPEND_BLOCK_EVENT-1];
- post_header_len[EXECUTE_LOAD_QUERY_EVENT-1]= EXECUTE_LOAD_QUERY_HEADER_LEN;
post_header_len[INCIDENT_EVENT-1]= INCIDENT_HEADER_LEN;
+
+ // Sanity-check that all post header lengths are initialized.
+ IF_DBUG({
+ int i;
+ for (i=0; i<number_of_event_types; i++)
+ assert(post_header_len[i] != 255);
+ });
}
break;
@@ -3699,7 +3728,7 @@ int Format_description_log_event::do_apply_event(Relay_log_info const *rli)
original place when it comes to us; we'll know this by checking
log_pos ("artificial" events have log_pos == 0).
*/
- if (!artificial_event && created && thd->transaction.all.ha_list)
+ if (!is_artificial_event() && created && thd->transaction.all.ha_list)
{
/* This is not an error (XA is safe), just an information */
rli->report(INFORMATION_LEVEL, 0,
@@ -4636,6 +4665,8 @@ Rotate_log_event::Rotate_log_event(const char* new_log_ident_arg,
#endif
if (flags & DUP_NAME)
new_log_ident= my_strndup(new_log_ident_arg, ident_len, MYF(MY_WME));
+ if (flags & RELAY_LOG)
+ set_relay_log_event();
DBUG_VOID_RETURN;
}
#endif
@@ -4707,8 +4738,6 @@ int Rotate_log_event::do_update_pos(Relay_log_info *rli)
DBUG_PRINT("info", ("new_log_ident: %s", this->new_log_ident));
DBUG_PRINT("info", ("pos: %s", llstr(this->pos, buf)));
- pthread_mutex_lock(&rli->data_lock);
- rli->event_relay_log_pos= my_b_tell(rli->cur_log);
/*
If we are in a transaction or in a group: the only normal case is
when the I/O thread was copying a big transaction, then it was
@@ -4726,23 +4755,24 @@ int Rotate_log_event::do_update_pos(Relay_log_info *rli)
relay log, which shall not change the group positions.
*/
if ((server_id != ::server_id || rli->replicate_same_server_id) &&
+ !is_relay_log_event() &&
!rli->is_in_group())
{
+ pthread_mutex_lock(&rli->data_lock);
DBUG_PRINT("info", ("old group_master_log_name: '%s' "
"old group_master_log_pos: %lu",
rli->group_master_log_name,
(ulong) rli->group_master_log_pos));
memcpy(rli->group_master_log_name, new_log_ident, ident_len+1);
rli->notify_group_master_log_name_update();
- rli->group_master_log_pos= pos;
- strmake(rli->group_relay_log_name, rli->event_relay_log_name,
- sizeof(rli->group_relay_log_name) - 1);
- rli->notify_group_relay_log_name_update();
- rli->group_relay_log_pos= rli->event_relay_log_pos;
+ rli->inc_group_relay_log_pos(pos, TRUE /* skip_lock */);
DBUG_PRINT("info", ("new group_master_log_name: '%s' "
"new group_master_log_pos: %lu",
rli->group_master_log_name,
(ulong) rli->group_master_log_pos));
+ pthread_mutex_unlock(&rli->data_lock);
+ flush_relay_log_info(rli);
+
/*
Reset thd->options and sql_mode etc, because this could be the signal of
a master's downgrade from 5.0 to 4.0.
@@ -4756,9 +4786,9 @@ int Rotate_log_event::do_update_pos(Relay_log_info *rli)
thd->variables.auto_increment_increment=
thd->variables.auto_increment_offset= 1;
}
- pthread_mutex_unlock(&rli->data_lock);
- pthread_cond_broadcast(&rli->data_cond);
- flush_relay_log_info(rli);
+ else
+ rli->inc_event_relay_log_pos();
+
DBUG_RETURN(0);
}
@@ -4812,7 +4842,9 @@ Intvar_log_event::Intvar_log_event(const char* buf,
const Format_description_log_event* description_event)
:Log_event(buf, description_event)
{
- buf+= description_event->common_header_len;
+ /* The Post-Header is empty. The Varible Data part begins immediately. */
+ buf+= description_event->common_header_len +
+ description_event->post_header_len[INTVAR_EVENT-1];
type= buf[I_TYPE_OFFSET];
val= uint8korr(buf+I_VAL_OFFSET);
}
@@ -4956,7 +4988,9 @@ Rand_log_event::Rand_log_event(const char* buf,
const Format_description_log_event* description_event)
:Log_event(buf, description_event)
{
- buf+= description_event->common_header_len;
+ /* The Post-Header is empty. The Variable Data part begins immediately. */
+ buf+= description_event->common_header_len +
+ description_event->post_header_len[RAND_EVENT-1];
seed1= uint8korr(buf+RAND_SEED1_OFFSET);
seed2= uint8korr(buf+RAND_SEED2_OFFSET);
}
@@ -5060,7 +5094,9 @@ Xid_log_event(const char* buf,
const Format_description_log_event *description_event)
:Log_event(buf, description_event)
{
- buf+= description_event->common_header_len;
+ /* The Post-Header is empty. The Variable Data part begins immediately. */
+ buf+= description_event->common_header_len +
+ description_event->post_header_len[XID_EVENT-1];
memcpy((char*) &xid, buf, sizeof(xid));
}
@@ -5207,7 +5243,9 @@ User_var_log_event(const char* buf,
const Format_description_log_event* description_event)
:Log_event(buf, description_event)
{
- buf+= description_event->common_header_len;
+ /* The Post-Header is empty. The Variable Data part begins immediately. */
+ buf+= description_event->common_header_len +
+ description_event->post_header_len[USER_VAR_EVENT-1];
name_len= uint4korr(buf);
name= (char *) buf + UV_NAME_LEN_SIZE;
buf+= UV_NAME_LEN_SIZE + name_len;
@@ -8093,6 +8131,9 @@ Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability
analyze if explicit data is provided for slave's TIMESTAMP columns).
*/
m_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
+
+ /* Honor next number column if present */
+ m_table->next_number_field= m_table->found_next_number_field;
return error;
}
@@ -8101,6 +8142,7 @@ Write_rows_log_event::do_after_row_operations(const Slave_reporting_capability *
int error)
{
int local_error= 0;
+ m_table->next_number_field=0;
if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1 ||
m_table->s->db_type()->db_type == DB_TYPE_NDBCLUSTER)
{
@@ -9059,7 +9101,17 @@ Incident_log_event::Incident_log_event(const char *buf, uint event_len,
DBUG_PRINT("info",("event_len: %u; common_header_len: %d; post_header_len: %d",
event_len, common_header_len, post_header_len));
- m_incident= static_cast<Incident>(uint2korr(buf + common_header_len));
+ int incident_number= uint2korr(buf + common_header_len);
+ if (incident_number >= INCIDENT_COUNT ||
+ incident_number <= INCIDENT_NONE)
+ {
+ // If the incident is not recognized, this binlog event is
+ // invalid. If we set incident_number to INCIDENT_NONE, the
+ // invalidity will be detected by is_valid().
+ incident_number= INCIDENT_NONE;
+ DBUG_VOID_RETURN;
+ }
+ m_incident= static_cast<Incident>(incident_number);
char const *ptr= buf + common_header_len + post_header_len;
char const *const str_end= buf + event_len;
uint8 len= 0; // Assignment to keep compiler happy
@@ -9086,9 +9138,6 @@ Incident_log_event::description() const
};
DBUG_PRINT("info", ("m_incident: %d", m_incident));
-
- DBUG_ASSERT((size_t) m_incident <= sizeof(description)/sizeof(*description));
-
return description[m_incident];
}
diff --git a/sql/log_event.h b/sql/log_event.h
index 3c109b798d3..1d11d7e2d5f 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -227,14 +227,22 @@ struct sql_ex_info
#define QUERY_HEADER_MINIMAL_LEN (4 + 4 + 1 + 2)
// where 5.0 differs: 2 for len of N-bytes vars.
#define QUERY_HEADER_LEN (QUERY_HEADER_MINIMAL_LEN + 2)
+#define STOP_HEADER_LEN 0
#define LOAD_HEADER_LEN (4 + 4 + 4 + 1 +1 + 4)
+#define SLAVE_HEADER_LEN 0
#define START_V3_HEADER_LEN (2 + ST_SERVER_VER_LEN + 4)
#define ROTATE_HEADER_LEN 8 // this is FROZEN (the Rotate post-header is frozen)
+#define INTVAR_HEADER_LEN 0
#define CREATE_FILE_HEADER_LEN 4
#define APPEND_BLOCK_HEADER_LEN 4
#define EXEC_LOAD_HEADER_LEN 4
#define DELETE_FILE_HEADER_LEN 4
+#define NEW_LOAD_HEADER_LEN LOAD_HEADER_LEN
+#define RAND_HEADER_LEN 0
+#define USER_VAR_HEADER_LEN 0
#define FORMAT_DESCRIPTION_HEADER_LEN (START_V3_HEADER_LEN+1+LOG_EVENT_TYPES)
+#define XID_HEADER_LEN 0
+#define BEGIN_LOAD_QUERY_HEADER_LEN APPEND_BLOCK_HEADER_LEN
#define ROWS_HEADER_LEN 8
#define TABLE_MAP_HEADER_LEN 8
#define EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN (4 + 4 + 4 + 1)
@@ -319,18 +327,16 @@ struct sql_ex_info
#define Q_CHARSET_DATABASE_CODE 8
#define Q_TABLE_MAP_FOR_UPDATE_CODE 9
-/* Intvar event post-header */
+/* Intvar event data */
#define I_TYPE_OFFSET 0
#define I_VAL_OFFSET 1
-/* Rand event post-header */
-
+/* Rand event data */
#define RAND_SEED1_OFFSET 0
#define RAND_SEED2_OFFSET 8
-/* User_var event post-header */
-
+/* User_var event data */
#define UV_VAL_LEN_SIZE 4
#define UV_VAL_IS_NULL 1
#define UV_VAL_TYPE_SIZE 1
@@ -338,7 +344,6 @@ struct sql_ex_info
#define UV_CHARSET_NUMBER_SIZE 4
/* Load event post-header */
-
#define L_THREAD_ID_OFFSET 0
#define L_EXEC_TIME_OFFSET 4
#define L_SKIP_LINES_OFFSET 8
@@ -349,7 +354,6 @@ struct sql_ex_info
#define L_DATA_OFFSET LOAD_HEADER_LEN
/* Rotate event post-header */
-
#define R_POS_OFFSET 0
#define R_IDENT_OFFSET 8
@@ -458,6 +462,25 @@ struct sql_ex_info
#define LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F 0x10
/**
+ @def LOG_EVENT_ARTIFICIAL_F
+
+ Artificial events are created arbitarily and not written to binary
+ log
+
+ These events should not update the master log position when slave
+ SQL thread executes them.
+*/
+#define LOG_EVENT_ARTIFICIAL_F 0x20
+
+/**
+ @def LOG_EVENT_RELAY_LOG_F
+
+ Events with this flag set are created by slave IO thread and written
+ to relay log
+*/
+#define LOG_EVENT_RELAY_LOG_F 0x40
+
+/**
@def OPTIONS_WRITTEN_TO_BIN_LOG
OPTIONS_WRITTEN_TO_BIN_LOG are the bits of thd->options which must
@@ -980,7 +1003,10 @@ public:
#endif
virtual Log_event_type get_type_code() = 0;
virtual bool is_valid() const = 0;
- virtual bool is_artificial_event() { return 0; }
+ void set_artificial_event() { flags |= LOG_EVENT_ARTIFICIAL_F; }
+ void set_relay_log_event() { flags |= LOG_EVENT_RELAY_LOG_F; }
+ bool is_artificial_event() const { return flags & LOG_EVENT_ARTIFICIAL_F; }
+ bool is_relay_log_event() const { return flags & LOG_EVENT_RELAY_LOG_F; }
inline bool get_cache_stmt() const { return cache_stmt; }
Log_event(const char* buf, const Format_description_log_event
*description_event);
@@ -2079,12 +2105,6 @@ public:
uint16 binlog_version;
char server_version[ST_SERVER_VER_LEN];
/*
- artifical_event is 1 in the case where this is a generated event that
- should not case any cleanup actions. We handle this in the log by
- setting log_event == 0 (for now).
- */
- bool artificial_event;
- /*
We set this to 1 if we don't want to have the created time in the log,
which is the case when we rollover to a new log.
*/
@@ -2112,7 +2132,6 @@ public:
{
return START_V3_HEADER_LEN; //no variable-sized part
}
- virtual bool is_artificial_event() { return artificial_event; }
protected:
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
@@ -2206,10 +2225,11 @@ protected:
@section Intvar_log_event_binary_format Binary Format
- The Post-Header has two components:
+ The Post-Header for this event type is empty. The Body has two
+ components:
<table>
- <caption>Post-Header for Intvar_log_event</caption>
+ <caption>Body for Intvar_log_event</caption>
<tr>
<th>Name</th>
@@ -2283,11 +2303,12 @@ private:
which are stored internally as two 64-bit numbers.
@section Rand_log_event_binary_format Binary Format
- This event type has no Post-Header. The Body of this event type has
- two components:
+
+ The Post-Header for this event type is empty. The Body has two
+ components:
<table>
- <caption>Post-Header for Intvar_log_event</caption>
+ <caption>Body for Rand_log_event</caption>
<tr>
<th>Name</th>
@@ -2532,7 +2553,8 @@ class Rotate_log_event: public Log_event
{
public:
enum {
- DUP_NAME= 2 // if constructor should dup the string argument
+ DUP_NAME= 2, // if constructor should dup the string argument
+ RELAY_LOG=4 // rotate event for relay log
};
const char* new_log_ident;
ulonglong pos;
@@ -3870,7 +3892,10 @@ public:
virtual Log_event_type get_type_code() { return INCIDENT_EVENT; }
- virtual bool is_valid() const { return 1; }
+ virtual bool is_valid() const
+ {
+ return m_incident > INCIDENT_NONE && m_incident < INCIDENT_COUNT;
+ }
virtual int get_data_size() {
return INCIDENT_HEADER_LEN + 1 + m_message.length;
}
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 46a63969faf..b19294c5676 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2003 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -148,15 +148,20 @@ typedef struct my_locale_st
TYPELIB *ab_month_names;
TYPELIB *day_names;
TYPELIB *ab_day_names;
+ uint max_month_name_length;
+ uint max_day_name_length;
#ifdef __cplusplus
my_locale_st(uint number_par,
const char *name_par, const char *descr_par, bool is_ascii_par,
TYPELIB *month_names_par, TYPELIB *ab_month_names_par,
- TYPELIB *day_names_par, TYPELIB *ab_day_names_par) :
+ TYPELIB *day_names_par, TYPELIB *ab_day_names_par,
+ uint max_month_name_length_par, uint max_day_name_length_par) :
number(number_par),
name(name_par), description(descr_par), is_ascii(is_ascii_par),
month_names(month_names_par), ab_month_names(ab_month_names_par),
- day_names(day_names_par), ab_day_names(ab_day_names_par)
+ day_names(day_names_par), ab_day_names(ab_day_names_par),
+ max_month_name_length(max_month_name_length_par),
+ max_day_name_length(max_day_name_length_par)
{}
#endif
} MY_LOCALE;
@@ -2231,6 +2236,7 @@ uint strconvert(CHARSET_INFO *from_cs, const char *from,
CHARSET_INFO *to_cs, char *to, uint to_length, uint *errors);
uint filename_to_tablename(const char *from, char *to, uint to_length);
uint tablename_to_filename(const char *from, char *to, uint to_length);
+uint check_n_cut_mysql50_prefix(const char *from, char *to, uint to_length);
#endif /* MYSQL_SERVER || INNODB_COMPATIBILITY_HOOKS */
#ifdef MYSQL_SERVER
uint build_table_filename(char *buff, size_t bufflen, const char *db,
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index dbbb6faaa7d..b77d8ad233e 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -228,6 +228,12 @@ extern "C" int gethostname(char *name, int namelen);
extern "C" sig_handler handle_segfault(int sig);
+#if defined(__linux__)
+#define ENABLE_TEMP_POOL 1
+#else
+#define ENABLE_TEMP_POOL 0
+#endif
+
/* Constants */
const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"};
@@ -3462,8 +3468,13 @@ static int init_common_variables(const char *conf_file_name, int argc,
sys_var_slow_log_path.value= my_strdup(s, MYF(0));
sys_var_slow_log_path.value_length= strlen(s);
+#if (ENABLE_TEMP_POOL)
if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1))
return 1;
+#else
+ use_temp_pool= 0;
+#endif
+
if (my_database_names_init())
return 1;
@@ -4198,6 +4209,44 @@ void decrement_handler_count()
#ifndef EMBEDDED_LIBRARY
+#ifndef DBUG_OFF
+/*
+ Debugging helper function to keep the locale database
+ (see sql_locale.cc) and max_month_name_length and
+ max_day_name_length variable values in consistent state.
+*/
+static void test_lc_time_sz()
+{
+ DBUG_ENTER("test_lc_time_sz");
+ for (MY_LOCALE **loc= my_locales; *loc; loc++)
+ {
+ uint max_month_len= 0;
+ uint max_day_len = 0;
+ for (const char **month= (*loc)->month_names->type_names; *month; month++)
+ {
+ set_if_bigger(max_month_len,
+ my_numchars_mb(&my_charset_utf8_general_ci,
+ *month, *month + strlen(*month)));
+ }
+ for (const char **day= (*loc)->day_names->type_names; *day; day++)
+ {
+ set_if_bigger(max_day_len,
+ my_numchars_mb(&my_charset_utf8_general_ci,
+ *day, *day + strlen(*day)));
+ }
+ if ((*loc)->max_month_name_length != max_month_len ||
+ (*loc)->max_day_name_length != max_day_len)
+ {
+ DBUG_PRINT("Wrong max day name(or month name) length for locale:",
+ ("%s", (*loc)->name));
+ DBUG_ASSERT(0);
+ }
+ }
+ DBUG_VOID_RETURN;
+}
+#endif//DBUG_OFF
+
+
#ifdef __WIN__
int win_main(int argc, char **argv)
#else
@@ -4291,6 +4340,10 @@ int main(int argc, char **argv)
openlog(libwrapName, LOG_PID, LOG_AUTH);
#endif
+#ifndef DBUG_OFF
+ test_lc_time_sz();
+#endif
+
/*
We have enough space for fiddling with the argv, continue
*/
@@ -6410,9 +6463,14 @@ log and this option does nothing anymore.",
(uchar**) &opt_tc_heuristic_recover, (uchar**) &opt_tc_heuristic_recover,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"temp-pool", OPT_TEMP_POOL,
+#if (ENABLE_TEMP_POOL)
"Using this option will cause most temporary files created to use a small set of names, rather than a unique name for each new file.",
+#else
+ "This option is ignored on this OS.",
+#endif
(uchar**) &use_temp_pool, (uchar**) &use_temp_pool, 0, GET_BOOL, NO_ARG, 1,
0, 0, 0, 0, 0},
+
{"timed_mutexes", OPT_TIMED_MUTEXES,
"Specify whether to time mutexes (only InnoDB mutexes are currently supported)",
(uchar**) &timed_mutexes, (uchar**) &timed_mutexes, 0, GET_BOOL, NO_ARG, 0,
@@ -6963,13 +7021,15 @@ The minimum value for this variable is 4096.",
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
-static int show_question(THD *thd, SHOW_VAR *var, char *buff)
+
+static int show_queries(THD *thd, SHOW_VAR *var, char *buff)
{
var->type= SHOW_LONGLONG;
var->value= (char *)&thd->query_id;
return 0;
}
+
static int show_net_compression(THD *thd, SHOW_VAR *var, char *buff)
{
var->type= SHOW_MY_BOOL;
@@ -7385,7 +7445,8 @@ SHOW_VAR status_vars[]= {
{"Qcache_queries_in_cache", (char*) &query_cache.queries_in_cache, SHOW_LONG_NOFLUSH},
{"Qcache_total_blocks", (char*) &query_cache.total_blocks, SHOW_LONG_NOFLUSH},
#endif /*HAVE_QUERY_CACHE*/
- {"Questions", (char*) &show_question, SHOW_FUNC},
+ {"Queries", (char*) &show_queries, SHOW_FUNC},
+ {"Questions", (char*) offsetof(STATUS_VAR, questions), SHOW_LONG_STATUS},
#ifdef HAVE_REPLICATION
{"Rpl_status", (char*) &show_rpl_status, SHOW_FUNC},
#endif
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index c9311cdf398..37cc0b1ee7b 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2006 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1245,6 +1245,9 @@ QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT()
quick->file= NULL;
quick_selects.delete_elements();
delete pk_quick_select;
+ /* It's ok to call the next two even if they are already deinitialized */
+ end_read_record(&read_record);
+ free_io_cache(head);
free_root(&alloc,MYF(0));
DBUG_VOID_RETURN;
}
@@ -2668,7 +2671,7 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond)
PART_PRUNE_PARAM prune_param;
MEM_ROOT alloc;
RANGE_OPT_PARAM *range_par= &prune_param.range_param;
- my_bitmap_map *old_read_set, *old_write_set;
+ my_bitmap_map *old_sets[2];
prune_param.part_info= part_info;
init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
@@ -2682,8 +2685,8 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond)
DBUG_RETURN(FALSE);
}
- old_write_set= dbug_tmp_use_all_columns(table, table->write_set);
- old_read_set= dbug_tmp_use_all_columns(table, table->read_set);
+ dbug_tmp_use_all_columns(table, old_sets,
+ table->read_set, table->write_set);
range_par->thd= thd;
range_par->table= table;
/* range_par->cond doesn't need initialization */
@@ -2773,8 +2776,7 @@ all_used:
retval= FALSE; // some partitions are used
mark_all_partitions_as_used(prune_param.part_info);
end:
- dbug_tmp_restore_column_map(table->write_set, old_write_set);
- dbug_tmp_restore_column_map(table->read_set, old_read_set);
+ dbug_tmp_restore_column_maps(table->read_set, table->write_set, old_sets);
thd->no_errors=0;
thd->mem_root= range_par->old_root;
free_root(&alloc,MYF(0)); // Return memory & allocator
@@ -11146,9 +11148,9 @@ print_key(KEY_PART *key_part, const uchar *key, uint used_length)
String tmp(buff,sizeof(buff),&my_charset_bin);
uint store_length;
TABLE *table= key_part->field->table;
- my_bitmap_map *old_write_set, *old_read_set;
- old_write_set= dbug_tmp_use_all_columns(table, table->write_set);
- old_read_set= dbug_tmp_use_all_columns(table, table->read_set);
+ my_bitmap_map *old_sets[2];
+
+ dbug_tmp_use_all_columns(table, old_sets, table->read_set, table->write_set);
for (; key < key_end; key+=store_length, key_part++)
{
@@ -11174,8 +11176,7 @@ print_key(KEY_PART *key_part, const uchar *key, uint used_length)
if (key+store_length < key_end)
fputc('/',DBUG_FILE);
}
- dbug_tmp_restore_column_map(table->write_set, old_write_set);
- dbug_tmp_restore_column_map(table->read_set, old_read_set);
+ dbug_tmp_restore_column_maps(table->read_set, table->write_set, old_sets);
}
@@ -11183,18 +11184,16 @@ static void print_quick(QUICK_SELECT_I *quick, const key_map *needed_reg)
{
char buf[MAX_KEY/8+1];
TABLE *table;
- my_bitmap_map *old_read_map, *old_write_map;
+ my_bitmap_map *old_sets[2];
DBUG_ENTER("print_quick");
if (!quick)
DBUG_VOID_RETURN;
DBUG_LOCK_FILE;
table= quick->head;
- old_read_map= dbug_tmp_use_all_columns(table, table->read_set);
- old_write_map= dbug_tmp_use_all_columns(table, table->write_set);
+ dbug_tmp_use_all_columns(table, old_sets, table->read_set, table->write_set);
quick->dbug_dump(0, TRUE);
- dbug_tmp_restore_column_map(table->read_set, old_read_map);
- dbug_tmp_restore_column_map(table->write_set, old_write_map);
+ dbug_tmp_restore_column_maps(table->read_set, table->write_set, old_sets);
fprintf(DBUG_FILE,"other_keys: 0x%s:\n", needed_reg->print(buf));
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index dfdd29975ac..8fc9e584789 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -867,6 +867,7 @@ bool partition_info::check_partition_info(THD *thd, handlerton **eng_type,
if (part_type != HASH_PARTITION || !list_of_part_fields)
{
+ DBUG_ASSERT(part_expr);
err= part_expr->walk(&Item::check_partition_func_processor, 0,
NULL);
if (!err && is_sub_partitioned() && !list_of_subpart_fields)
diff --git a/sql/partition_info.h b/sql/partition_info.h
index 703b92305b1..415f955d5d4 100644
--- a/sql/partition_info.h
+++ b/sql/partition_info.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 MySQL AB
+/* Copyright 2006-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc
index d7e783f534f..582348608de 100644
--- a/sql/repl_failsafe.cc
+++ b/sql/repl_failsafe.cc
@@ -644,6 +644,16 @@ err:
}
#endif
+
+/**
+ Execute a SHOW SLAVE HOSTS statement.
+
+ @param thd Pointer to THD object for the client thread executing the
+ statement.
+
+ @retval FALSE success
+ @retval TRUE failure
+*/
bool show_slave_hosts(THD* thd)
{
List<Item> field_list;
diff --git a/sql/rpl_constants.h b/sql/rpl_constants.h
index 426e80a328d..32fb4b8a7f2 100644
--- a/sql/rpl_constants.h
+++ b/sql/rpl_constants.h
@@ -6,10 +6,10 @@
*/
enum Incident {
/** No incident */
- INCIDENT_NONE,
+ INCIDENT_NONE = 0,
/** There are possibly lost events in the replication stream */
- INCIDENT_LOST_EVENTS,
+ INCIDENT_LOST_EVENTS = 1,
/** Shall be last event of the enumeration */
INCIDENT_COUNT
diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc
index 8a977ad66af..fe8e17dc1c7 100644
--- a/sql/rpl_rli.cc
+++ b/sql/rpl_rli.cc
@@ -155,6 +155,7 @@ int init_relay_log_info(Relay_log_info* rli,
sql_print_error("Failed in open_log() called from init_relay_log_info()");
DBUG_RETURN(1);
}
+ rli->relay_log.is_relay_log= TRUE;
}
/* if file does not exist */
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 640c0fe7291..468e6776996 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2003 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1540,14 +1540,14 @@ bool sys_var_thd_ulong::update(THD *thd, set_var *var)
ulonglong tmp= var->save_result.ulonglong_value;
/* Don't use bigger value than given with --maximum-variable-name=.. */
- if ((ulong) tmp > max_system_variables.*offset)
+ if (tmp > max_system_variables.*offset)
{
throw_bounds_warning(thd, TRUE, TRUE, name, (longlong) tmp);
tmp= max_system_variables.*offset;
}
if (option_limits)
- tmp= (ulong) fix_unsigned(thd, tmp, option_limits);
+ tmp= fix_unsigned(thd, tmp, option_limits);
#if SIZEOF_LONG < SIZEOF_LONG_LONG
else if (tmp > ULONG_MAX)
{
@@ -1556,6 +1556,7 @@ bool sys_var_thd_ulong::update(THD *thd, set_var *var)
}
#endif
+ DBUG_ASSERT(tmp <= ULONG_MAX);
if (var->type == OPT_GLOBAL)
global_system_variables.*offset= (ulong) tmp;
else
@@ -3554,6 +3555,7 @@ int set_var_password::check(THD *thd)
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (!user->host.str)
{
+ DBUG_ASSERT(thd->security_ctx->priv_host);
if (*thd->security_ctx->priv_host != 0)
{
user->host.str= (char *) thd->security_ctx->priv_host;
@@ -3565,6 +3567,12 @@ int set_var_password::check(THD *thd)
user->host.length= 1;
}
}
+ if (!user->user.str)
+ {
+ DBUG_ASSERT(thd->security_ctx->priv_user);
+ user->user.str= (char *) thd->security_ctx->priv_user;
+ user->user.length= strlen(thd->security_ctx->priv_user);
+ }
/* Returns 1 as the function sends error to client */
return check_change_password(thd, user->host.str, user->user.str,
password, strlen(password)) ? 1 : 0;
diff --git a/sql/slave.cc b/sql/slave.cc
index 62aeec03ebb..6d48e57d298 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -1358,6 +1358,17 @@ int register_slave_on_master(MYSQL* mysql, Master_info *mi,
}
+/**
+ Execute a SHOW SLAVE STATUS statement.
+
+ @param thd Pointer to THD object for the client thread executing the
+ statement.
+
+ @param mi Pointer to Master_info object for the IO thread.
+
+ @retval FALSE success
+ @retval TRUE failure
+*/
bool show_master_info(THD* thd, Master_info* mi)
{
// TODO: fix this for multi-master
@@ -2063,7 +2074,7 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli,
fewer times, 0 is returned.
- init_master_info or init_relay_log_pos failed. (These are called
- if a failure occurs when applying the event.)</li>
+ if a failure occurs when applying the event.)
- An error occurred when updating the binlog position.
@@ -2308,8 +2319,14 @@ static int try_to_reconnect(THD *thd, MYSQL *mysql, Master_info *mi,
}
-/* Slave I/O Thread entry point */
+/**
+ Slave IO thread entry point.
+
+ @param arg Pointer to Master_info struct that holds information for
+ the IO thread.
+ @return Always 0.
+*/
pthread_handler_t handle_slave_io(void *arg)
{
THD *thd; // needs to be first for thread_stack
@@ -2617,8 +2634,14 @@ err:
}
-/* Slave SQL Thread entry point */
+/**
+ Slave SQL thread entry point.
+
+ @param arg Pointer to Relay_log_info object that holds information
+ for the SQL thread.
+ @return Always 0.
+*/
pthread_handler_t handle_slave_sql(void *arg)
{
THD *thd; /* needs to be first for thread_stack */
@@ -3711,6 +3734,16 @@ static IO_CACHE *reopen_relay_log(Relay_log_info *rli, const char **errmsg)
}
+/**
+ Reads next event from the relay log. Should be called from the
+ slave IO thread.
+
+ @param rli Relay_log_info structure for the slave IO thread.
+
+ @return The event read, or NULL on error. If an error occurs, the
+ error is reported through the sql_print_information() or
+ sql_print_error() functions.
+*/
static Log_event* next_event(Relay_log_info* rli)
{
Log_event* ev;
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 534cd0a7ca1..ef6cb556f4c 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 MySQL AB
+/* Copyright 2002-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index ed41ff90cbc..d8d43fbd878 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -6301,10 +6301,12 @@ int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr)
}
-void update_schema_privilege(TABLE *table, char *buff, const char* db,
- const char* t_name, const char* column,
- uint col_length, const char *priv,
- uint priv_length, const char* is_grantable)
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+static bool update_schema_privilege(THD *thd, TABLE *table, char *buff,
+ const char* db, const char* t_name,
+ const char* column, uint col_length,
+ const char *priv, uint priv_length,
+ const char* is_grantable)
{
int i= 2;
CHARSET_INFO *cs= system_charset_info;
@@ -6317,14 +6319,16 @@ void update_schema_privilege(TABLE *table, char *buff, const char* db,
if (column)
table->field[i++]->store(column, col_length, cs);
table->field[i++]->store(priv, priv_length, cs);
- table->field[i]->store(is_grantable, (uint) strlen(is_grantable), cs);
- table->file->ha_write_row(table->record[0]);
+ table->field[i]->store(is_grantable, strlen(is_grantable), cs);
+ return schema_table_store_record(thd, table);
}
+#endif
int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
{
#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ int error= 0;
uint counter;
ACL_USER *acl_user;
ulong want_access;
@@ -6358,8 +6362,14 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
strxmov(buff,"'",user,"'@'",host,"'",NullS);
if (!(want_access & ~GRANT_ACL))
- update_schema_privilege(table, buff, 0, 0, 0, 0,
- STRING_WITH_LEN("USAGE"), is_grantable);
+ {
+ if (update_schema_privilege(thd, table, buff, 0, 0, 0, 0,
+ STRING_WITH_LEN("USAGE"), is_grantable))
+ {
+ error= 1;
+ goto err;
+ }
+ }
else
{
uint priv_id;
@@ -6367,16 +6377,22 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
for (priv_id=0, j = SELECT_ACL;j <= GLOBAL_ACLS; priv_id++,j <<= 1)
{
if (test_access & j)
- update_schema_privilege(table, buff, 0, 0, 0, 0,
- command_array[priv_id],
- command_lengths[priv_id], is_grantable);
+ {
+ if (update_schema_privilege(thd, table, buff, 0, 0, 0, 0,
+ command_array[priv_id],
+ command_lengths[priv_id], is_grantable))
+ {
+ error= 1;
+ goto err;
+ }
+ }
}
}
}
-
+err:
pthread_mutex_unlock(&acl_cache->lock);
- DBUG_RETURN(0);
+ DBUG_RETURN(error);
#else
return(0);
#endif
@@ -6386,6 +6402,7 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
{
#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ int error= 0;
uint counter;
ACL_DB *acl_db;
ulong want_access;
@@ -6423,24 +6440,36 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
}
strxmov(buff,"'",user,"'@'",host,"'",NullS);
if (!(want_access & ~GRANT_ACL))
- update_schema_privilege(table, buff, acl_db->db, 0, 0,
- 0, STRING_WITH_LEN("USAGE"), is_grantable);
+ {
+ if (update_schema_privilege(thd, table, buff, acl_db->db, 0, 0,
+ 0, STRING_WITH_LEN("USAGE"), is_grantable))
+ {
+ error= 1;
+ goto err;
+ }
+ }
else
{
int cnt;
ulong j,test_access= want_access & ~GRANT_ACL;
for (cnt=0, j = SELECT_ACL; j <= DB_ACLS; cnt++,j <<= 1)
if (test_access & j)
- update_schema_privilege(table, buff, acl_db->db, 0, 0, 0,
- command_array[cnt], command_lengths[cnt],
- is_grantable);
+ {
+ if (update_schema_privilege(thd, table, buff, acl_db->db, 0, 0, 0,
+ command_array[cnt], command_lengths[cnt],
+ is_grantable))
+ {
+ error= 1;
+ goto err;
+ }
+ }
}
}
}
-
+err:
pthread_mutex_unlock(&acl_cache->lock);
- DBUG_RETURN(0);
+ DBUG_RETURN(error);
#else
return (0);
#endif
@@ -6450,6 +6479,7 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
{
#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ int error= 0;
uint index;
char buff[100];
TABLE *table= tables->table;
@@ -6489,8 +6519,15 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
strxmov(buff, "'", user, "'@'", host, "'", NullS);
if (!test_access)
- update_schema_privilege(table, buff, grant_table->db, grant_table->tname,
- 0, 0, STRING_WITH_LEN("USAGE"), is_grantable);
+ {
+ if (update_schema_privilege(thd, table, buff, grant_table->db,
+ grant_table->tname, 0, 0,
+ STRING_WITH_LEN("USAGE"), is_grantable))
+ {
+ error= 1;
+ goto err;
+ }
+ }
else
{
ulong j;
@@ -6498,17 +6535,24 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
for (cnt= 0, j= SELECT_ACL; j <= TABLE_ACLS; cnt++, j<<= 1)
{
if (test_access & j)
- update_schema_privilege(table, buff, grant_table->db,
- grant_table->tname, 0, 0, command_array[cnt],
- command_lengths[cnt], is_grantable);
+ {
+ if (update_schema_privilege(thd, table, buff, grant_table->db,
+ grant_table->tname, 0, 0,
+ command_array[cnt],
+ command_lengths[cnt], is_grantable))
+ {
+ error= 1;
+ goto err;
+ }
+ }
}
}
- }
+ }
}
-
+err:
rw_unlock(&LOCK_grant);
- DBUG_RETURN(0);
+ DBUG_RETURN(error);
#else
return (0);
#endif
@@ -6518,6 +6562,7 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
{
#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ int error= 0;
uint index;
char buff[100];
TABLE *table= tables->table;
@@ -6567,22 +6612,28 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
GRANT_COLUMN *grant_column = (GRANT_COLUMN*)
hash_element(&grant_table->hash_columns,col_index);
if ((grant_column->rights & j) && (table_access & j))
- update_schema_privilege(table, buff, grant_table->db,
- grant_table->tname,
- grant_column->column,
- grant_column->key_length,
- command_array[cnt],
- command_lengths[cnt], is_grantable);
+ {
+ if (update_schema_privilege(thd, table, buff, grant_table->db,
+ grant_table->tname,
+ grant_column->column,
+ grant_column->key_length,
+ command_array[cnt],
+ command_lengths[cnt], is_grantable))
+ {
+ error= 1;
+ goto err;
+ }
+ }
}
}
}
}
}
}
-
+err:
rw_unlock(&LOCK_grant);
- DBUG_RETURN(0);
+ DBUG_RETURN(error);
#else
return (0);
#endif
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index bf45bb648bd..1f086683aa2 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2006 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1111,6 +1111,27 @@ static void mark_temp_tables_as_free_for_reuse(THD *thd)
*/
if (table->child_l || table->parent)
detach_merge_children(table, TRUE);
+ /*
+ Reset temporary table lock type to it's default value (TL_WRITE).
+
+ Statements such as INSERT INTO .. SELECT FROM tmp, CREATE TABLE
+ .. SELECT FROM tmp and UPDATE may under some circumstances modify
+ the lock type of the tables participating in the statement. This
+ isn't a problem for non-temporary tables since their lock type is
+ reset at every open, but the same does not occur for temporary
+ tables for historical reasons.
+
+ Furthermore, the lock type of temporary tables is not really that
+ important because they can only be used by one query at a time and
+ not even twice in a query -- a temporary table is represented by
+ only one TABLE object. Nonetheless, it's safer from a maintenance
+ point of view to reset the lock type of this singleton TABLE object
+ as to not cause problems when the table is reused.
+
+ Even under LOCK TABLES mode its okay to reset the lock type as
+ LOCK TABLES is allowed (but ignored) for a temporary table.
+ */
+ table->reginfo.lock_type= TL_WRITE;
}
}
}
@@ -4699,7 +4720,7 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
else if (tables->lock_type == TL_READ_DEFAULT)
tables->table->reginfo.lock_type=
read_lock_type_for_table(thd, tables->table);
- else if (tables->table->s->tmp_table == NO_TMP_TABLE)
+ else
tables->table->reginfo.lock_type= tables->lock_type;
}
tables->table->grant= tables->grant;
diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc
index 7ca7bef3a56..96e99b57e3c 100644
--- a/sql/sql_binlog.cc
+++ b/sql/sql_binlog.cc
@@ -18,7 +18,7 @@
#include "base64.h"
/**
- Execute a BINLOG statement
+ Execute a BINLOG statement.
To execute the BINLOG command properly the server needs to know
which format the BINLOG command's event is in. Therefore, the first
@@ -26,6 +26,9 @@
Format_description_log_event, as outputted by mysqlbinlog. This
Format_description_log_event is cached in
rli->description_event_for_exec.
+
+ @param thd Pointer to THD object for the client thread executing the
+ statement.
*/
void mysql_client_binlog_statement(THD* thd)
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 1748a737b07..6e9079d4e98 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 6f068074641..45478ab66e8 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -3590,7 +3590,6 @@ show_query_type(THD::enum_binlog_query_type qtype)
default:
DBUG_ASSERT(0 <= qtype && qtype < THD::QUERY_TYPE_COUNT);
}
-
static char buf[64];
sprintf(buf, "UNKNOWN#%d", qtype);
return buf;
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 01f5c9eb1e9..612a49f03ab 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -462,8 +462,15 @@ typedef struct system_status_var
ulong com_stmt_fetch;
ulong com_stmt_reset;
ulong com_stmt_close;
-
/*
+ Number of statements sent from the client
+ */
+ ulong questions;
+ /*
+ IMPORTANT!
+ SEE last_system_status_var DEFINITION BELOW.
+ Below 'last_system_status_var' are all variables which doesn't make any
+ sense to add to the /global/ status variable counter.
Status variables which it does not make sense to add to
global status variable counter
*/
@@ -476,7 +483,7 @@ typedef struct system_status_var
counter
*/
-#define last_system_status_var com_stmt_close
+#define last_system_status_var questions
void mark_transaction_to_rollback(THD *thd, bool all);
@@ -1009,6 +1016,7 @@ show_system_thread(enum_thread_type thread)
{
#define RETURN_NAME_AS_STRING(NAME) case (NAME): return #NAME
switch (thread) {
+ static char buf[64];
RETURN_NAME_AS_STRING(NON_SYSTEM_THREAD);
RETURN_NAME_AS_STRING(SYSTEM_THREAD_DELAYED_INSERT);
RETURN_NAME_AS_STRING(SYSTEM_THREAD_SLAVE_IO);
@@ -1016,9 +1024,11 @@ show_system_thread(enum_thread_type thread)
RETURN_NAME_AS_STRING(SYSTEM_THREAD_NDBCLUSTER_BINLOG);
RETURN_NAME_AS_STRING(SYSTEM_THREAD_EVENT_SCHEDULER);
RETURN_NAME_AS_STRING(SYSTEM_THREAD_EVENT_WORKER);
+ default:
+ sprintf(buf, "<UNKNOWN SYSTEM THREAD: %d>", thread);
+ return buf;
}
#undef RETURN_NAME_AS_STRING
- return "UNKNOWN"; /* keep gcc happy */
}
/**
@@ -2118,8 +2128,8 @@ public:
Don't reset binlog format for NDB binlog injector thread.
*/
DBUG_PRINT("debug",
- ("temporary_tables: %p, in_sub_stmt: %d, system_thread: %s",
- temporary_tables, in_sub_stmt,
+ ("temporary_tables: %s, in_sub_stmt: %s, system_thread: %s",
+ YESNO(temporary_tables), YESNO(in_sub_stmt),
show_system_thread(system_thread)));
if ((temporary_tables == NULL) && (in_sub_stmt == 0) &&
(system_thread != SYSTEM_THREAD_NDBCLUSTER_BINLOG))
diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc
index 7c530cb9013..6f61dc40f66 100644
--- a/sql/sql_cursor.cc
+++ b/sql/sql_cursor.cc
@@ -85,6 +85,7 @@ class Materialized_cursor: public Server_side_cursor
List<Item> item_list;
ulong fetch_limit;
ulong fetch_count;
+ bool is_rnd_inited;
public:
Materialized_cursor(select_result *result, TABLE *table);
@@ -190,7 +191,11 @@ int mysql_open_cursor(THD *thd, uint flags, select_result *result,
such command is SHOW VARIABLES or SHOW STATUS.
*/
if (rc)
+ {
+ if (result_materialize->materialized_cursor)
+ delete result_materialize->materialized_cursor;
goto err_open;
+ }
if (sensitive_cursor->is_open())
{
@@ -542,7 +547,8 @@ Materialized_cursor::Materialized_cursor(select_result *result_arg,
:Server_side_cursor(&table_arg->mem_root, result_arg),
table(table_arg),
fetch_limit(0),
- fetch_count(0)
+ fetch_count(0),
+ is_rnd_inited(0)
{
fake_unit.init_query();
fake_unit.thd= table->in_use;
@@ -599,11 +605,12 @@ int Materialized_cursor::open(JOIN *join __attribute__((unused)))
THD *thd= fake_unit.thd;
int rc;
Query_arena backup_arena;
-
thd->set_n_backup_active_arena(this, &backup_arena);
/* Create a list of fields and start sequential scan */
- rc= (result->prepare(item_list, &fake_unit) ||
- table->file->ha_rnd_init(TRUE));
+ rc= result->prepare(item_list, &fake_unit);
+ if (!rc && !(rc= table->file->ha_rnd_init(TRUE)))
+ is_rnd_inited= 1;
+
thd->restore_active_arena(this, &backup_arena);
if (rc == 0)
{
@@ -678,7 +685,8 @@ void Materialized_cursor::close()
{
/* Free item_list items */
free_items();
- (void) table->file->ha_rnd_end();
+ if (is_rnd_inited)
+ (void) table->file->ha_rnd_end();
/*
We need to grab table->mem_root to prevent free_tmp_table from freeing:
the cursor object was allocated in this memory.
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 83d78ab9852..8a891f88057 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -907,7 +907,6 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
remove_db_from_cache(db);
pthread_mutex_unlock(&LOCK_open);
-
error= -1;
/*
We temporarily disable the binary log while dropping the objects
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 6a400a4f197..a0abb9c2118 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -951,6 +951,26 @@ bool multi_delete::send_eof()
****************************************************************************/
/*
+ Row-by-row truncation if the engine does not support table recreation.
+ Probably a InnoDB table.
+*/
+
+static bool mysql_truncate_by_delete(THD *thd, TABLE_LIST *table_list)
+{
+ bool error, save_binlog_row_based= thd->current_stmt_binlog_row_based;
+ DBUG_ENTER("mysql_truncate_by_delete");
+ table_list->lock_type= TL_WRITE;
+ mysql_init_select(thd->lex);
+ thd->clear_current_stmt_binlog_row_based();
+ error= mysql_delete(thd, table_list, NULL, NULL, HA_POS_ERROR, LL(0), TRUE);
+ ha_autocommit_or_rollback(thd, error);
+ end_trans(thd, error ? ROLLBACK : COMMIT);
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
+ DBUG_RETURN(error);
+}
+
+
+/*
Optimize delete of all rows by doing a full generate of the table
This will work even if the .ISM and .ISD tables are destroyed
@@ -1060,27 +1080,6 @@ end:
DBUG_RETURN(error);
trunc_by_del:
- /* Probably InnoDB table */
- ulonglong save_options= thd->options;
- bool save_binlog_row_based= thd->current_stmt_binlog_row_based;
-
- table_list->lock_type= TL_WRITE;
- thd->options&= ~(OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
- ha_enable_transaction(thd, FALSE);
- mysql_init_select(thd->lex);
- thd->clear_current_stmt_binlog_row_based();
-
- /* Delete all rows from table */
- error= mysql_delete(thd, table_list, (COND*) 0, (SQL_LIST*) 0,
- HA_POS_ERROR, LL(0), TRUE);
- ha_enable_transaction(thd, TRUE);
- /*
- Safety, in case the engine ignored ha_enable_transaction(FALSE)
- above. Also clears thd->transaction.*.
- */
- error= ha_autocommit_or_rollback(thd, error);
- ha_commit(thd);
- thd->options= save_options;
- thd->current_stmt_binlog_row_based= save_binlog_row_based;
+ error= mysql_truncate_by_delete(thd, table_list);
DBUG_RETURN(error);
}
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 0c3ea8bd731..a64429fb7bc 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2006 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 82b4481200b..272c74917ad 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2006 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 24731b600e9..ed6b9e7d8df 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2006 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -190,6 +190,15 @@ typedef struct st_lex_server_options
char *server_name, *host, *db, *username, *password, *scheme, *socket, *owner;
} LEX_SERVER_OPTIONS;
+
+/**
+ Structure to hold parameters for CHANGE MASTER or START/STOP SLAVE
+ or SHOW NEW MASTER.
+
+ Remark: this should not be confused with Master_info (and perhaps
+ would better be renamed to st_lex_replication_info). Some fields,
+ e.g., delay, are saved in Relay_log_info, not in Master_info.
+*/
typedef struct st_lex_master_info
{
char *host, *user, *password, *log_file_name;
diff --git a/sql/sql_locale.cc b/sql/sql_locale.cc
index 4e61c664106..3def9864c29 100644
--- a/sql/sql_locale.cc
+++ b/sql/sql_locale.cc
@@ -49,7 +49,9 @@ MY_LOCALE my_locale_ar_AE
&my_locale_typelib_month_names_ar_AE,
&my_locale_typelib_ab_month_names_ar_AE,
&my_locale_typelib_day_names_ar_AE,
- &my_locale_typelib_ab_day_names_ar_AE
+ &my_locale_typelib_ab_day_names_ar_AE,
+ 6,
+ 8
);
/***** LOCALE END ar_AE *****/
@@ -79,7 +81,9 @@ MY_LOCALE my_locale_ar_BH
&my_locale_typelib_month_names_ar_BH,
&my_locale_typelib_ab_month_names_ar_BH,
&my_locale_typelib_day_names_ar_BH,
- &my_locale_typelib_ab_day_names_ar_BH
+ &my_locale_typelib_ab_day_names_ar_BH,
+ 6,
+ 8
);
/***** LOCALE END ar_BH *****/
@@ -109,7 +113,9 @@ MY_LOCALE my_locale_ar_JO
&my_locale_typelib_month_names_ar_JO,
&my_locale_typelib_ab_month_names_ar_JO,
&my_locale_typelib_day_names_ar_JO,
- &my_locale_typelib_ab_day_names_ar_JO
+ &my_locale_typelib_ab_day_names_ar_JO,
+ 12,
+ 8
);
/***** LOCALE END ar_JO *****/
@@ -139,7 +145,9 @@ MY_LOCALE my_locale_ar_SA
&my_locale_typelib_month_names_ar_SA,
&my_locale_typelib_ab_month_names_ar_SA,
&my_locale_typelib_day_names_ar_SA,
- &my_locale_typelib_ab_day_names_ar_SA
+ &my_locale_typelib_ab_day_names_ar_SA,
+ 12,
+ 8
);
/***** LOCALE END ar_SA *****/
@@ -169,7 +177,9 @@ MY_LOCALE my_locale_ar_SY
&my_locale_typelib_month_names_ar_SY,
&my_locale_typelib_ab_month_names_ar_SY,
&my_locale_typelib_day_names_ar_SY,
- &my_locale_typelib_ab_day_names_ar_SY
+ &my_locale_typelib_ab_day_names_ar_SY,
+ 12,
+ 8
);
/***** LOCALE END ar_SY *****/
@@ -199,7 +209,9 @@ MY_LOCALE my_locale_be_BY
&my_locale_typelib_month_names_be_BY,
&my_locale_typelib_ab_month_names_be_BY,
&my_locale_typelib_day_names_be_BY,
- &my_locale_typelib_ab_day_names_be_BY
+ &my_locale_typelib_ab_day_names_be_BY,
+ 10,
+ 10
);
/***** LOCALE END be_BY *****/
@@ -229,7 +241,9 @@ MY_LOCALE my_locale_bg_BG
&my_locale_typelib_month_names_bg_BG,
&my_locale_typelib_ab_month_names_bg_BG,
&my_locale_typelib_day_names_bg_BG,
- &my_locale_typelib_ab_day_names_bg_BG
+ &my_locale_typelib_ab_day_names_bg_BG,
+ 9,
+ 10
);
/***** LOCALE END bg_BG *****/
@@ -259,7 +273,9 @@ MY_LOCALE my_locale_ca_ES
&my_locale_typelib_month_names_ca_ES,
&my_locale_typelib_ab_month_names_ca_ES,
&my_locale_typelib_day_names_ca_ES,
- &my_locale_typelib_ab_day_names_ca_ES
+ &my_locale_typelib_ab_day_names_ca_ES,
+ 8,
+ 9
);
/***** LOCALE END ca_ES *****/
@@ -289,7 +305,9 @@ MY_LOCALE my_locale_cs_CZ
&my_locale_typelib_month_names_cs_CZ,
&my_locale_typelib_ab_month_names_cs_CZ,
&my_locale_typelib_day_names_cs_CZ,
- &my_locale_typelib_ab_day_names_cs_CZ
+ &my_locale_typelib_ab_day_names_cs_CZ,
+ 8,
+ 7
);
/***** LOCALE END cs_CZ *****/
@@ -319,7 +337,9 @@ MY_LOCALE my_locale_da_DK
&my_locale_typelib_month_names_da_DK,
&my_locale_typelib_ab_month_names_da_DK,
&my_locale_typelib_day_names_da_DK,
- &my_locale_typelib_ab_day_names_da_DK
+ &my_locale_typelib_ab_day_names_da_DK,
+ 9,
+ 7
);
/***** LOCALE END da_DK *****/
@@ -349,7 +369,9 @@ MY_LOCALE my_locale_de_AT
&my_locale_typelib_month_names_de_AT,
&my_locale_typelib_ab_month_names_de_AT,
&my_locale_typelib_day_names_de_AT,
- &my_locale_typelib_ab_day_names_de_AT
+ &my_locale_typelib_ab_day_names_de_AT,
+ 9,
+ 10
);
/***** LOCALE END de_AT *****/
@@ -379,7 +401,9 @@ MY_LOCALE my_locale_de_DE
&my_locale_typelib_month_names_de_DE,
&my_locale_typelib_ab_month_names_de_DE,
&my_locale_typelib_day_names_de_DE,
- &my_locale_typelib_ab_day_names_de_DE
+ &my_locale_typelib_ab_day_names_de_DE,
+ 9,
+ 10
);
/***** LOCALE END de_DE *****/
@@ -409,7 +433,9 @@ MY_LOCALE my_locale_en_US
&my_locale_typelib_month_names_en_US,
&my_locale_typelib_ab_month_names_en_US,
&my_locale_typelib_day_names_en_US,
- &my_locale_typelib_ab_day_names_en_US
+ &my_locale_typelib_ab_day_names_en_US,
+ 9,
+ 9
);
/***** LOCALE END en_US *****/
@@ -439,7 +465,9 @@ MY_LOCALE my_locale_es_ES
&my_locale_typelib_month_names_es_ES,
&my_locale_typelib_ab_month_names_es_ES,
&my_locale_typelib_day_names_es_ES,
- &my_locale_typelib_ab_day_names_es_ES
+ &my_locale_typelib_ab_day_names_es_ES,
+ 10,
+ 9
);
/***** LOCALE END es_ES *****/
@@ -469,7 +497,9 @@ MY_LOCALE my_locale_et_EE
&my_locale_typelib_month_names_et_EE,
&my_locale_typelib_ab_month_names_et_EE,
&my_locale_typelib_day_names_et_EE,
- &my_locale_typelib_ab_day_names_et_EE
+ &my_locale_typelib_ab_day_names_et_EE,
+ 9,
+ 9
);
/***** LOCALE END et_EE *****/
@@ -499,7 +529,9 @@ MY_LOCALE my_locale_eu_ES
&my_locale_typelib_month_names_eu_ES,
&my_locale_typelib_ab_month_names_eu_ES,
&my_locale_typelib_day_names_eu_ES,
- &my_locale_typelib_ab_day_names_eu_ES
+ &my_locale_typelib_ab_day_names_eu_ES,
+ 9,
+ 10
);
/***** LOCALE END eu_ES *****/
@@ -529,7 +561,9 @@ MY_LOCALE my_locale_fi_FI
&my_locale_typelib_month_names_fi_FI,
&my_locale_typelib_ab_month_names_fi_FI,
&my_locale_typelib_day_names_fi_FI,
- &my_locale_typelib_ab_day_names_fi_FI
+ &my_locale_typelib_ab_day_names_fi_FI,
+ 9,
+ 11
);
/***** LOCALE END fi_FI *****/
@@ -559,7 +593,9 @@ MY_LOCALE my_locale_fo_FO
&my_locale_typelib_month_names_fo_FO,
&my_locale_typelib_ab_month_names_fo_FO,
&my_locale_typelib_day_names_fo_FO,
- &my_locale_typelib_ab_day_names_fo_FO
+ &my_locale_typelib_ab_day_names_fo_FO,
+ 9,
+ 12
);
/***** LOCALE END fo_FO *****/
@@ -589,7 +625,9 @@ MY_LOCALE my_locale_fr_FR
&my_locale_typelib_month_names_fr_FR,
&my_locale_typelib_ab_month_names_fr_FR,
&my_locale_typelib_day_names_fr_FR,
- &my_locale_typelib_ab_day_names_fr_FR
+ &my_locale_typelib_ab_day_names_fr_FR,
+ 9,
+ 8
);
/***** LOCALE END fr_FR *****/
@@ -619,7 +657,9 @@ MY_LOCALE my_locale_gl_ES
&my_locale_typelib_month_names_gl_ES,
&my_locale_typelib_ab_month_names_gl_ES,
&my_locale_typelib_day_names_gl_ES,
- &my_locale_typelib_ab_day_names_gl_ES
+ &my_locale_typelib_ab_day_names_gl_ES,
+ 8,
+ 8
);
/***** LOCALE END gl_ES *****/
@@ -649,7 +689,9 @@ MY_LOCALE my_locale_gu_IN
&my_locale_typelib_month_names_gu_IN,
&my_locale_typelib_ab_month_names_gu_IN,
&my_locale_typelib_day_names_gu_IN,
- &my_locale_typelib_ab_day_names_gu_IN
+ &my_locale_typelib_ab_day_names_gu_IN,
+ 10,
+ 8
);
/***** LOCALE END gu_IN *****/
@@ -679,7 +721,9 @@ MY_LOCALE my_locale_he_IL
&my_locale_typelib_month_names_he_IL,
&my_locale_typelib_ab_month_names_he_IL,
&my_locale_typelib_day_names_he_IL,
- &my_locale_typelib_ab_day_names_he_IL
+ &my_locale_typelib_ab_day_names_he_IL,
+ 7,
+ 5
);
/***** LOCALE END he_IL *****/
@@ -709,7 +753,9 @@ MY_LOCALE my_locale_hi_IN
&my_locale_typelib_month_names_hi_IN,
&my_locale_typelib_ab_month_names_hi_IN,
&my_locale_typelib_day_names_hi_IN,
- &my_locale_typelib_ab_day_names_hi_IN
+ &my_locale_typelib_ab_day_names_hi_IN,
+ 7,
+ 9
);
/***** LOCALE END hi_IN *****/
@@ -739,7 +785,9 @@ MY_LOCALE my_locale_hr_HR
&my_locale_typelib_month_names_hr_HR,
&my_locale_typelib_ab_month_names_hr_HR,
&my_locale_typelib_day_names_hr_HR,
- &my_locale_typelib_ab_day_names_hr_HR
+ &my_locale_typelib_ab_day_names_hr_HR,
+ 8,
+ 11
);
/***** LOCALE END hr_HR *****/
@@ -769,7 +817,9 @@ MY_LOCALE my_locale_hu_HU
&my_locale_typelib_month_names_hu_HU,
&my_locale_typelib_ab_month_names_hu_HU,
&my_locale_typelib_day_names_hu_HU,
- &my_locale_typelib_ab_day_names_hu_HU
+ &my_locale_typelib_ab_day_names_hu_HU,
+ 10,
+ 9
);
/***** LOCALE END hu_HU *****/
@@ -799,7 +849,9 @@ MY_LOCALE my_locale_id_ID
&my_locale_typelib_month_names_id_ID,
&my_locale_typelib_ab_month_names_id_ID,
&my_locale_typelib_day_names_id_ID,
- &my_locale_typelib_ab_day_names_id_ID
+ &my_locale_typelib_ab_day_names_id_ID,
+ 9,
+ 6
);
/***** LOCALE END id_ID *****/
@@ -829,7 +881,9 @@ MY_LOCALE my_locale_is_IS
&my_locale_typelib_month_names_is_IS,
&my_locale_typelib_ab_month_names_is_IS,
&my_locale_typelib_day_names_is_IS,
- &my_locale_typelib_ab_day_names_is_IS
+ &my_locale_typelib_ab_day_names_is_IS,
+ 9,
+ 12
);
/***** LOCALE END is_IS *****/
@@ -859,7 +913,9 @@ MY_LOCALE my_locale_it_CH
&my_locale_typelib_month_names_it_CH,
&my_locale_typelib_ab_month_names_it_CH,
&my_locale_typelib_day_names_it_CH,
- &my_locale_typelib_ab_day_names_it_CH
+ &my_locale_typelib_ab_day_names_it_CH,
+ 9,
+ 9
);
/***** LOCALE END it_CH *****/
@@ -889,7 +945,9 @@ MY_LOCALE my_locale_ja_JP
&my_locale_typelib_month_names_ja_JP,
&my_locale_typelib_ab_month_names_ja_JP,
&my_locale_typelib_day_names_ja_JP,
- &my_locale_typelib_ab_day_names_ja_JP
+ &my_locale_typelib_ab_day_names_ja_JP,
+ 3,
+ 3
);
/***** LOCALE END ja_JP *****/
@@ -919,7 +977,9 @@ MY_LOCALE my_locale_ko_KR
&my_locale_typelib_month_names_ko_KR,
&my_locale_typelib_ab_month_names_ko_KR,
&my_locale_typelib_day_names_ko_KR,
- &my_locale_typelib_ab_day_names_ko_KR
+ &my_locale_typelib_ab_day_names_ko_KR,
+ 3,
+ 3
);
/***** LOCALE END ko_KR *****/
@@ -949,7 +1009,9 @@ MY_LOCALE my_locale_lt_LT
&my_locale_typelib_month_names_lt_LT,
&my_locale_typelib_ab_month_names_lt_LT,
&my_locale_typelib_day_names_lt_LT,
- &my_locale_typelib_ab_day_names_lt_LT
+ &my_locale_typelib_ab_day_names_lt_LT,
+ 9,
+ 14
);
/***** LOCALE END lt_LT *****/
@@ -979,7 +1041,9 @@ MY_LOCALE my_locale_lv_LV
&my_locale_typelib_month_names_lv_LV,
&my_locale_typelib_ab_month_names_lv_LV,
&my_locale_typelib_day_names_lv_LV,
- &my_locale_typelib_ab_day_names_lv_LV
+ &my_locale_typelib_ab_day_names_lv_LV,
+ 10,
+ 11
);
/***** LOCALE END lv_LV *****/
@@ -1009,7 +1073,9 @@ MY_LOCALE my_locale_mk_MK
&my_locale_typelib_month_names_mk_MK,
&my_locale_typelib_ab_month_names_mk_MK,
&my_locale_typelib_day_names_mk_MK,
- &my_locale_typelib_ab_day_names_mk_MK
+ &my_locale_typelib_ab_day_names_mk_MK,
+ 9,
+ 10
);
/***** LOCALE END mk_MK *****/
@@ -1039,7 +1105,9 @@ MY_LOCALE my_locale_mn_MN
&my_locale_typelib_month_names_mn_MN,
&my_locale_typelib_ab_month_names_mn_MN,
&my_locale_typelib_day_names_mn_MN,
- &my_locale_typelib_ab_day_names_mn_MN
+ &my_locale_typelib_ab_day_names_mn_MN,
+ 18,
+ 6
);
/***** LOCALE END mn_MN *****/
@@ -1069,7 +1137,9 @@ MY_LOCALE my_locale_ms_MY
&my_locale_typelib_month_names_ms_MY,
&my_locale_typelib_ab_month_names_ms_MY,
&my_locale_typelib_day_names_ms_MY,
- &my_locale_typelib_ab_day_names_ms_MY
+ &my_locale_typelib_ab_day_names_ms_MY,
+ 9,
+ 6
);
/***** LOCALE END ms_MY *****/
@@ -1099,7 +1169,9 @@ MY_LOCALE my_locale_nb_NO
&my_locale_typelib_month_names_nb_NO,
&my_locale_typelib_ab_month_names_nb_NO,
&my_locale_typelib_day_names_nb_NO,
- &my_locale_typelib_ab_day_names_nb_NO
+ &my_locale_typelib_ab_day_names_nb_NO,
+ 9,
+ 7
);
/***** LOCALE END nb_NO *****/
@@ -1129,7 +1201,9 @@ MY_LOCALE my_locale_nl_NL
&my_locale_typelib_month_names_nl_NL,
&my_locale_typelib_ab_month_names_nl_NL,
&my_locale_typelib_day_names_nl_NL,
- &my_locale_typelib_ab_day_names_nl_NL
+ &my_locale_typelib_ab_day_names_nl_NL,
+ 9,
+ 9
);
/***** LOCALE END nl_NL *****/
@@ -1159,7 +1233,9 @@ MY_LOCALE my_locale_pl_PL
&my_locale_typelib_month_names_pl_PL,
&my_locale_typelib_ab_month_names_pl_PL,
&my_locale_typelib_day_names_pl_PL,
- &my_locale_typelib_ab_day_names_pl_PL
+ &my_locale_typelib_ab_day_names_pl_PL,
+ 11,
+ 12
);
/***** LOCALE END pl_PL *****/
@@ -1189,7 +1265,9 @@ MY_LOCALE my_locale_pt_BR
&my_locale_typelib_month_names_pt_BR,
&my_locale_typelib_ab_month_names_pt_BR,
&my_locale_typelib_day_names_pt_BR,
- &my_locale_typelib_ab_day_names_pt_BR
+ &my_locale_typelib_ab_day_names_pt_BR,
+ 9,
+ 7
);
/***** LOCALE END pt_BR *****/
@@ -1219,7 +1297,9 @@ MY_LOCALE my_locale_pt_PT
&my_locale_typelib_month_names_pt_PT,
&my_locale_typelib_ab_month_names_pt_PT,
&my_locale_typelib_day_names_pt_PT,
- &my_locale_typelib_ab_day_names_pt_PT
+ &my_locale_typelib_ab_day_names_pt_PT,
+ 9,
+ 7
);
/***** LOCALE END pt_PT *****/
@@ -1249,7 +1329,9 @@ MY_LOCALE my_locale_ro_RO
&my_locale_typelib_month_names_ro_RO,
&my_locale_typelib_ab_month_names_ro_RO,
&my_locale_typelib_day_names_ro_RO,
- &my_locale_typelib_ab_day_names_ro_RO
+ &my_locale_typelib_ab_day_names_ro_RO,
+ 10,
+ 8
);
/***** LOCALE END ro_RO *****/
@@ -1279,7 +1361,9 @@ MY_LOCALE my_locale_ru_RU
&my_locale_typelib_month_names_ru_RU,
&my_locale_typelib_ab_month_names_ru_RU,
&my_locale_typelib_day_names_ru_RU,
- &my_locale_typelib_ab_day_names_ru_RU
+ &my_locale_typelib_ab_day_names_ru_RU,
+ 8,
+ 11
);
/***** LOCALE END ru_RU *****/
@@ -1309,7 +1393,9 @@ MY_LOCALE my_locale_ru_UA
&my_locale_typelib_month_names_ru_UA,
&my_locale_typelib_ab_month_names_ru_UA,
&my_locale_typelib_day_names_ru_UA,
- &my_locale_typelib_ab_day_names_ru_UA
+ &my_locale_typelib_ab_day_names_ru_UA,
+ 8,
+ 11
);
/***** LOCALE END ru_UA *****/
@@ -1339,7 +1425,9 @@ MY_LOCALE my_locale_sk_SK
&my_locale_typelib_month_names_sk_SK,
&my_locale_typelib_ab_month_names_sk_SK,
&my_locale_typelib_day_names_sk_SK,
- &my_locale_typelib_ab_day_names_sk_SK
+ &my_locale_typelib_ab_day_names_sk_SK,
+ 9,
+ 8
);
/***** LOCALE END sk_SK *****/
@@ -1369,7 +1457,9 @@ MY_LOCALE my_locale_sl_SI
&my_locale_typelib_month_names_sl_SI,
&my_locale_typelib_ab_month_names_sl_SI,
&my_locale_typelib_day_names_sl_SI,
- &my_locale_typelib_ab_day_names_sl_SI
+ &my_locale_typelib_ab_day_names_sl_SI,
+ 9,
+ 10
);
/***** LOCALE END sl_SI *****/
@@ -1399,7 +1489,9 @@ MY_LOCALE my_locale_sq_AL
&my_locale_typelib_month_names_sq_AL,
&my_locale_typelib_ab_month_names_sq_AL,
&my_locale_typelib_day_names_sq_AL,
- &my_locale_typelib_ab_day_names_sq_AL
+ &my_locale_typelib_ab_day_names_sq_AL,
+ 7,
+ 10
);
/***** LOCALE END sq_AL *****/
@@ -1429,7 +1521,9 @@ MY_LOCALE my_locale_sr_YU
&my_locale_typelib_month_names_sr_YU,
&my_locale_typelib_ab_month_names_sr_YU,
&my_locale_typelib_day_names_sr_YU,
- &my_locale_typelib_ab_day_names_sr_YU
+ &my_locale_typelib_ab_day_names_sr_YU,
+ 9,
+ 10
);
/***** LOCALE END sr_YU *****/
@@ -1459,7 +1553,9 @@ MY_LOCALE my_locale_sv_SE
&my_locale_typelib_month_names_sv_SE,
&my_locale_typelib_ab_month_names_sv_SE,
&my_locale_typelib_day_names_sv_SE,
- &my_locale_typelib_ab_day_names_sv_SE
+ &my_locale_typelib_ab_day_names_sv_SE,
+ 9,
+ 7
);
/***** LOCALE END sv_SE *****/
@@ -1489,7 +1585,9 @@ MY_LOCALE my_locale_ta_IN
&my_locale_typelib_month_names_ta_IN,
&my_locale_typelib_ab_month_names_ta_IN,
&my_locale_typelib_day_names_ta_IN,
- &my_locale_typelib_ab_day_names_ta_IN
+ &my_locale_typelib_ab_day_names_ta_IN,
+ 10,
+ 8
);
/***** LOCALE END ta_IN *****/
@@ -1519,7 +1617,9 @@ MY_LOCALE my_locale_te_IN
&my_locale_typelib_month_names_te_IN,
&my_locale_typelib_ab_month_names_te_IN,
&my_locale_typelib_day_names_te_IN,
- &my_locale_typelib_ab_day_names_te_IN
+ &my_locale_typelib_ab_day_names_te_IN,
+ 10,
+ 9
);
/***** LOCALE END te_IN *****/
@@ -1549,7 +1649,9 @@ MY_LOCALE my_locale_th_TH
&my_locale_typelib_month_names_th_TH,
&my_locale_typelib_ab_month_names_th_TH,
&my_locale_typelib_day_names_th_TH,
- &my_locale_typelib_ab_day_names_th_TH
+ &my_locale_typelib_ab_day_names_th_TH,
+ 10,
+ 8
);
/***** LOCALE END th_TH *****/
@@ -1579,7 +1681,9 @@ MY_LOCALE my_locale_tr_TR
&my_locale_typelib_month_names_tr_TR,
&my_locale_typelib_ab_month_names_tr_TR,
&my_locale_typelib_day_names_tr_TR,
- &my_locale_typelib_ab_day_names_tr_TR
+ &my_locale_typelib_ab_day_names_tr_TR,
+ 7,
+ 9
);
/***** LOCALE END tr_TR *****/
@@ -1609,7 +1713,9 @@ MY_LOCALE my_locale_uk_UA
&my_locale_typelib_month_names_uk_UA,
&my_locale_typelib_ab_month_names_uk_UA,
&my_locale_typelib_day_names_uk_UA,
- &my_locale_typelib_ab_day_names_uk_UA
+ &my_locale_typelib_ab_day_names_uk_UA,
+ 8,
+ 9
);
/***** LOCALE END uk_UA *****/
@@ -1639,7 +1745,9 @@ MY_LOCALE my_locale_ur_PK
&my_locale_typelib_month_names_ur_PK,
&my_locale_typelib_ab_month_names_ur_PK,
&my_locale_typelib_day_names_ur_PK,
- &my_locale_typelib_ab_day_names_ur_PK
+ &my_locale_typelib_ab_day_names_ur_PK,
+ 6,
+ 6
);
/***** LOCALE END ur_PK *****/
@@ -1669,7 +1777,9 @@ MY_LOCALE my_locale_vi_VN
&my_locale_typelib_month_names_vi_VN,
&my_locale_typelib_ab_month_names_vi_VN,
&my_locale_typelib_day_names_vi_VN,
- &my_locale_typelib_ab_day_names_vi_VN
+ &my_locale_typelib_ab_day_names_vi_VN,
+ 16,
+ 11
);
/***** LOCALE END vi_VN *****/
@@ -1699,7 +1809,9 @@ MY_LOCALE my_locale_zh_CN
&my_locale_typelib_month_names_zh_CN,
&my_locale_typelib_ab_month_names_zh_CN,
&my_locale_typelib_day_names_zh_CN,
- &my_locale_typelib_ab_day_names_zh_CN
+ &my_locale_typelib_ab_day_names_zh_CN,
+ 3,
+ 3
);
/***** LOCALE END zh_CN *****/
@@ -1729,7 +1841,9 @@ MY_LOCALE my_locale_zh_TW
&my_locale_typelib_month_names_zh_TW,
&my_locale_typelib_ab_month_names_zh_TW,
&my_locale_typelib_day_names_zh_TW,
- &my_locale_typelib_ab_day_names_zh_TW
+ &my_locale_typelib_ab_day_names_zh_TW,
+ 3,
+ 2
);
/***** LOCALE END zh_TW *****/
@@ -1743,7 +1857,9 @@ MY_LOCALE my_locale_ar_DZ
&my_locale_typelib_month_names_ar_BH,
&my_locale_typelib_ab_month_names_ar_BH,
&my_locale_typelib_day_names_ar_BH,
- &my_locale_typelib_ab_day_names_ar_BH
+ &my_locale_typelib_ab_day_names_ar_BH,
+ 6,
+ 8
);
/***** LOCALE END ar_DZ *****/
@@ -1757,7 +1873,9 @@ MY_LOCALE my_locale_ar_EG
&my_locale_typelib_month_names_ar_BH,
&my_locale_typelib_ab_month_names_ar_BH,
&my_locale_typelib_day_names_ar_BH,
- &my_locale_typelib_ab_day_names_ar_BH
+ &my_locale_typelib_ab_day_names_ar_BH,
+ 6,
+ 8
);
/***** LOCALE END ar_EG *****/
@@ -1771,7 +1889,9 @@ MY_LOCALE my_locale_ar_IN
&my_locale_typelib_month_names_ar_BH,
&my_locale_typelib_ab_month_names_ar_BH,
&my_locale_typelib_day_names_ar_BH,
- &my_locale_typelib_ab_day_names_ar_BH
+ &my_locale_typelib_ab_day_names_ar_BH,
+ 6,
+ 8
);
/***** LOCALE END ar_IN *****/
@@ -1785,7 +1905,9 @@ MY_LOCALE my_locale_ar_IQ
&my_locale_typelib_month_names_ar_BH,
&my_locale_typelib_ab_month_names_ar_BH,
&my_locale_typelib_day_names_ar_BH,
- &my_locale_typelib_ab_day_names_ar_BH
+ &my_locale_typelib_ab_day_names_ar_BH,
+ 6,
+ 8
);
/***** LOCALE END ar_IQ *****/
@@ -1799,7 +1921,9 @@ MY_LOCALE my_locale_ar_KW
&my_locale_typelib_month_names_ar_BH,
&my_locale_typelib_ab_month_names_ar_BH,
&my_locale_typelib_day_names_ar_BH,
- &my_locale_typelib_ab_day_names_ar_BH
+ &my_locale_typelib_ab_day_names_ar_BH,
+ 6,
+ 8
);
/***** LOCALE END ar_KW *****/
@@ -1813,7 +1937,9 @@ MY_LOCALE my_locale_ar_LB
&my_locale_typelib_month_names_ar_JO,
&my_locale_typelib_ab_month_names_ar_JO,
&my_locale_typelib_day_names_ar_JO,
- &my_locale_typelib_ab_day_names_ar_JO
+ &my_locale_typelib_ab_day_names_ar_JO,
+ 12,
+ 8
);
/***** LOCALE END ar_LB *****/
@@ -1827,7 +1953,9 @@ MY_LOCALE my_locale_ar_LY
&my_locale_typelib_month_names_ar_BH,
&my_locale_typelib_ab_month_names_ar_BH,
&my_locale_typelib_day_names_ar_BH,
- &my_locale_typelib_ab_day_names_ar_BH
+ &my_locale_typelib_ab_day_names_ar_BH,
+ 6,
+ 8
);
/***** LOCALE END ar_LY *****/
@@ -1841,7 +1969,9 @@ MY_LOCALE my_locale_ar_MA
&my_locale_typelib_month_names_ar_BH,
&my_locale_typelib_ab_month_names_ar_BH,
&my_locale_typelib_day_names_ar_BH,
- &my_locale_typelib_ab_day_names_ar_BH
+ &my_locale_typelib_ab_day_names_ar_BH,
+ 6,
+ 8
);
/***** LOCALE END ar_MA *****/
@@ -1855,7 +1985,9 @@ MY_LOCALE my_locale_ar_OM
&my_locale_typelib_month_names_ar_BH,
&my_locale_typelib_ab_month_names_ar_BH,
&my_locale_typelib_day_names_ar_BH,
- &my_locale_typelib_ab_day_names_ar_BH
+ &my_locale_typelib_ab_day_names_ar_BH,
+ 6,
+ 8
);
/***** LOCALE END ar_OM *****/
@@ -1869,7 +2001,9 @@ MY_LOCALE my_locale_ar_QA
&my_locale_typelib_month_names_ar_BH,
&my_locale_typelib_ab_month_names_ar_BH,
&my_locale_typelib_day_names_ar_BH,
- &my_locale_typelib_ab_day_names_ar_BH
+ &my_locale_typelib_ab_day_names_ar_BH,
+ 6,
+ 8
);
/***** LOCALE END ar_QA *****/
@@ -1883,7 +2017,9 @@ MY_LOCALE my_locale_ar_SD
&my_locale_typelib_month_names_ar_BH,
&my_locale_typelib_ab_month_names_ar_BH,
&my_locale_typelib_day_names_ar_BH,
- &my_locale_typelib_ab_day_names_ar_BH
+ &my_locale_typelib_ab_day_names_ar_BH,
+ 6,
+ 8
);
/***** LOCALE END ar_SD *****/
@@ -1897,7 +2033,9 @@ MY_LOCALE my_locale_ar_TN
&my_locale_typelib_month_names_ar_BH,
&my_locale_typelib_ab_month_names_ar_BH,
&my_locale_typelib_day_names_ar_BH,
- &my_locale_typelib_ab_day_names_ar_BH
+ &my_locale_typelib_ab_day_names_ar_BH,
+ 6,
+ 8
);
/***** LOCALE END ar_TN *****/
@@ -1911,7 +2049,9 @@ MY_LOCALE my_locale_ar_YE
&my_locale_typelib_month_names_ar_BH,
&my_locale_typelib_ab_month_names_ar_BH,
&my_locale_typelib_day_names_ar_BH,
- &my_locale_typelib_ab_day_names_ar_BH
+ &my_locale_typelib_ab_day_names_ar_BH,
+ 6,
+ 8
);
/***** LOCALE END ar_YE *****/
@@ -1925,7 +2065,9 @@ MY_LOCALE my_locale_de_BE
&my_locale_typelib_month_names_de_DE,
&my_locale_typelib_ab_month_names_de_DE,
&my_locale_typelib_day_names_de_DE,
- &my_locale_typelib_ab_day_names_de_DE
+ &my_locale_typelib_ab_day_names_de_DE,
+ 9,
+ 10
);
/***** LOCALE END de_BE *****/
@@ -1939,7 +2081,9 @@ MY_LOCALE my_locale_de_CH
&my_locale_typelib_month_names_de_DE,
&my_locale_typelib_ab_month_names_de_DE,
&my_locale_typelib_day_names_de_DE,
- &my_locale_typelib_ab_day_names_de_DE
+ &my_locale_typelib_ab_day_names_de_DE,
+ 9,
+ 10
);
/***** LOCALE END de_CH *****/
@@ -1953,7 +2097,9 @@ MY_LOCALE my_locale_de_LU
&my_locale_typelib_month_names_de_DE,
&my_locale_typelib_ab_month_names_de_DE,
&my_locale_typelib_day_names_de_DE,
- &my_locale_typelib_ab_day_names_de_DE
+ &my_locale_typelib_ab_day_names_de_DE,
+ 9,
+ 10
);
/***** LOCALE END de_LU *****/
@@ -1967,7 +2113,9 @@ MY_LOCALE my_locale_en_AU
&my_locale_typelib_month_names_en_US,
&my_locale_typelib_ab_month_names_en_US,
&my_locale_typelib_day_names_en_US,
- &my_locale_typelib_ab_day_names_en_US
+ &my_locale_typelib_ab_day_names_en_US,
+ 9,
+ 9
);
/***** LOCALE END en_AU *****/
@@ -1981,7 +2129,9 @@ MY_LOCALE my_locale_en_CA
&my_locale_typelib_month_names_en_US,
&my_locale_typelib_ab_month_names_en_US,
&my_locale_typelib_day_names_en_US,
- &my_locale_typelib_ab_day_names_en_US
+ &my_locale_typelib_ab_day_names_en_US,
+ 9,
+ 9
);
/***** LOCALE END en_CA *****/
@@ -1995,7 +2145,9 @@ MY_LOCALE my_locale_en_GB
&my_locale_typelib_month_names_en_US,
&my_locale_typelib_ab_month_names_en_US,
&my_locale_typelib_day_names_en_US,
- &my_locale_typelib_ab_day_names_en_US
+ &my_locale_typelib_ab_day_names_en_US,
+ 9,
+ 9
);
/***** LOCALE END en_GB *****/
@@ -2009,7 +2161,9 @@ MY_LOCALE my_locale_en_IN
&my_locale_typelib_month_names_en_US,
&my_locale_typelib_ab_month_names_en_US,
&my_locale_typelib_day_names_en_US,
- &my_locale_typelib_ab_day_names_en_US
+ &my_locale_typelib_ab_day_names_en_US,
+ 9,
+ 9
);
/***** LOCALE END en_IN *****/
@@ -2023,7 +2177,9 @@ MY_LOCALE my_locale_en_NZ
&my_locale_typelib_month_names_en_US,
&my_locale_typelib_ab_month_names_en_US,
&my_locale_typelib_day_names_en_US,
- &my_locale_typelib_ab_day_names_en_US
+ &my_locale_typelib_ab_day_names_en_US,
+ 9,
+ 9
);
/***** LOCALE END en_NZ *****/
@@ -2037,7 +2193,9 @@ MY_LOCALE my_locale_en_PH
&my_locale_typelib_month_names_en_US,
&my_locale_typelib_ab_month_names_en_US,
&my_locale_typelib_day_names_en_US,
- &my_locale_typelib_ab_day_names_en_US
+ &my_locale_typelib_ab_day_names_en_US,
+ 9,
+ 9
);
/***** LOCALE END en_PH *****/
@@ -2051,7 +2209,9 @@ MY_LOCALE my_locale_en_ZA
&my_locale_typelib_month_names_en_US,
&my_locale_typelib_ab_month_names_en_US,
&my_locale_typelib_day_names_en_US,
- &my_locale_typelib_ab_day_names_en_US
+ &my_locale_typelib_ab_day_names_en_US,
+ 9,
+ 9
);
/***** LOCALE END en_ZA *****/
@@ -2065,7 +2225,9 @@ MY_LOCALE my_locale_en_ZW
&my_locale_typelib_month_names_en_US,
&my_locale_typelib_ab_month_names_en_US,
&my_locale_typelib_day_names_en_US,
- &my_locale_typelib_ab_day_names_en_US
+ &my_locale_typelib_ab_day_names_en_US,
+ 9,
+ 9
);
/***** LOCALE END en_ZW *****/
@@ -2079,7 +2241,9 @@ MY_LOCALE my_locale_es_AR
&my_locale_typelib_month_names_es_ES,
&my_locale_typelib_ab_month_names_es_ES,
&my_locale_typelib_day_names_es_ES,
- &my_locale_typelib_ab_day_names_es_ES
+ &my_locale_typelib_ab_day_names_es_ES,
+ 10,
+ 9
);
/***** LOCALE END es_AR *****/
@@ -2093,7 +2257,9 @@ MY_LOCALE my_locale_es_BO
&my_locale_typelib_month_names_es_ES,
&my_locale_typelib_ab_month_names_es_ES,
&my_locale_typelib_day_names_es_ES,
- &my_locale_typelib_ab_day_names_es_ES
+ &my_locale_typelib_ab_day_names_es_ES,
+ 10,
+ 9
);
/***** LOCALE END es_BO *****/
@@ -2107,7 +2273,9 @@ MY_LOCALE my_locale_es_CL
&my_locale_typelib_month_names_es_ES,
&my_locale_typelib_ab_month_names_es_ES,
&my_locale_typelib_day_names_es_ES,
- &my_locale_typelib_ab_day_names_es_ES
+ &my_locale_typelib_ab_day_names_es_ES,
+ 10,
+ 9
);
/***** LOCALE END es_CL *****/
@@ -2121,7 +2289,9 @@ MY_LOCALE my_locale_es_CO
&my_locale_typelib_month_names_es_ES,
&my_locale_typelib_ab_month_names_es_ES,
&my_locale_typelib_day_names_es_ES,
- &my_locale_typelib_ab_day_names_es_ES
+ &my_locale_typelib_ab_day_names_es_ES,
+ 10,
+ 9
);
/***** LOCALE END es_CO *****/
@@ -2135,7 +2305,9 @@ MY_LOCALE my_locale_es_CR
&my_locale_typelib_month_names_es_ES,
&my_locale_typelib_ab_month_names_es_ES,
&my_locale_typelib_day_names_es_ES,
- &my_locale_typelib_ab_day_names_es_ES
+ &my_locale_typelib_ab_day_names_es_ES,
+ 10,
+ 9
);
/***** LOCALE END es_CR *****/
@@ -2149,7 +2321,9 @@ MY_LOCALE my_locale_es_DO
&my_locale_typelib_month_names_es_ES,
&my_locale_typelib_ab_month_names_es_ES,
&my_locale_typelib_day_names_es_ES,
- &my_locale_typelib_ab_day_names_es_ES
+ &my_locale_typelib_ab_day_names_es_ES,
+ 10,
+ 9
);
/***** LOCALE END es_DO *****/
@@ -2163,7 +2337,9 @@ MY_LOCALE my_locale_es_EC
&my_locale_typelib_month_names_es_ES,
&my_locale_typelib_ab_month_names_es_ES,
&my_locale_typelib_day_names_es_ES,
- &my_locale_typelib_ab_day_names_es_ES
+ &my_locale_typelib_ab_day_names_es_ES,
+ 10,
+ 9
);
/***** LOCALE END es_EC *****/
@@ -2177,7 +2353,9 @@ MY_LOCALE my_locale_es_GT
&my_locale_typelib_month_names_es_ES,
&my_locale_typelib_ab_month_names_es_ES,
&my_locale_typelib_day_names_es_ES,
- &my_locale_typelib_ab_day_names_es_ES
+ &my_locale_typelib_ab_day_names_es_ES,
+ 10,
+ 9
);
/***** LOCALE END es_GT *****/
@@ -2191,7 +2369,9 @@ MY_LOCALE my_locale_es_HN
&my_locale_typelib_month_names_es_ES,
&my_locale_typelib_ab_month_names_es_ES,
&my_locale_typelib_day_names_es_ES,
- &my_locale_typelib_ab_day_names_es_ES
+ &my_locale_typelib_ab_day_names_es_ES,
+ 10,
+ 9
);
/***** LOCALE END es_HN *****/
@@ -2205,7 +2385,9 @@ MY_LOCALE my_locale_es_MX
&my_locale_typelib_month_names_es_ES,
&my_locale_typelib_ab_month_names_es_ES,
&my_locale_typelib_day_names_es_ES,
- &my_locale_typelib_ab_day_names_es_ES
+ &my_locale_typelib_ab_day_names_es_ES,
+ 10,
+ 9
);
/***** LOCALE END es_MX *****/
@@ -2219,7 +2401,9 @@ MY_LOCALE my_locale_es_NI
&my_locale_typelib_month_names_es_ES,
&my_locale_typelib_ab_month_names_es_ES,
&my_locale_typelib_day_names_es_ES,
- &my_locale_typelib_ab_day_names_es_ES
+ &my_locale_typelib_ab_day_names_es_ES,
+ 10,
+ 9
);
/***** LOCALE END es_NI *****/
@@ -2233,7 +2417,9 @@ MY_LOCALE my_locale_es_PA
&my_locale_typelib_month_names_es_ES,
&my_locale_typelib_ab_month_names_es_ES,
&my_locale_typelib_day_names_es_ES,
- &my_locale_typelib_ab_day_names_es_ES
+ &my_locale_typelib_ab_day_names_es_ES,
+ 10,
+ 9
);
/***** LOCALE END es_PA *****/
@@ -2247,7 +2433,9 @@ MY_LOCALE my_locale_es_PE
&my_locale_typelib_month_names_es_ES,
&my_locale_typelib_ab_month_names_es_ES,
&my_locale_typelib_day_names_es_ES,
- &my_locale_typelib_ab_day_names_es_ES
+ &my_locale_typelib_ab_day_names_es_ES,
+ 10,
+ 9
);
/***** LOCALE END es_PE *****/
@@ -2261,7 +2449,9 @@ MY_LOCALE my_locale_es_PR
&my_locale_typelib_month_names_es_ES,
&my_locale_typelib_ab_month_names_es_ES,
&my_locale_typelib_day_names_es_ES,
- &my_locale_typelib_ab_day_names_es_ES
+ &my_locale_typelib_ab_day_names_es_ES,
+ 10,
+ 9
);
/***** LOCALE END es_PR *****/
@@ -2275,7 +2465,9 @@ MY_LOCALE my_locale_es_PY
&my_locale_typelib_month_names_es_ES,
&my_locale_typelib_ab_month_names_es_ES,
&my_locale_typelib_day_names_es_ES,
- &my_locale_typelib_ab_day_names_es_ES
+ &my_locale_typelib_ab_day_names_es_ES,
+ 10,
+ 9
);
/***** LOCALE END es_PY *****/
@@ -2289,7 +2481,9 @@ MY_LOCALE my_locale_es_SV
&my_locale_typelib_month_names_es_ES,
&my_locale_typelib_ab_month_names_es_ES,
&my_locale_typelib_day_names_es_ES,
- &my_locale_typelib_ab_day_names_es_ES
+ &my_locale_typelib_ab_day_names_es_ES,
+ 10,
+ 9
);
/***** LOCALE END es_SV *****/
@@ -2303,7 +2497,9 @@ MY_LOCALE my_locale_es_US
&my_locale_typelib_month_names_es_ES,
&my_locale_typelib_ab_month_names_es_ES,
&my_locale_typelib_day_names_es_ES,
- &my_locale_typelib_ab_day_names_es_ES
+ &my_locale_typelib_ab_day_names_es_ES,
+ 10,
+ 9
);
/***** LOCALE END es_US *****/
@@ -2317,7 +2513,9 @@ MY_LOCALE my_locale_es_UY
&my_locale_typelib_month_names_es_ES,
&my_locale_typelib_ab_month_names_es_ES,
&my_locale_typelib_day_names_es_ES,
- &my_locale_typelib_ab_day_names_es_ES
+ &my_locale_typelib_ab_day_names_es_ES,
+ 10,
+ 9
);
/***** LOCALE END es_UY *****/
@@ -2331,7 +2529,9 @@ MY_LOCALE my_locale_es_VE
&my_locale_typelib_month_names_es_ES,
&my_locale_typelib_ab_month_names_es_ES,
&my_locale_typelib_day_names_es_ES,
- &my_locale_typelib_ab_day_names_es_ES
+ &my_locale_typelib_ab_day_names_es_ES,
+ 10,
+ 9
);
/***** LOCALE END es_VE *****/
@@ -2345,7 +2545,9 @@ MY_LOCALE my_locale_fr_BE
&my_locale_typelib_month_names_fr_FR,
&my_locale_typelib_ab_month_names_fr_FR,
&my_locale_typelib_day_names_fr_FR,
- &my_locale_typelib_ab_day_names_fr_FR
+ &my_locale_typelib_ab_day_names_fr_FR,
+ 9,
+ 8
);
/***** LOCALE END fr_BE *****/
@@ -2359,7 +2561,9 @@ MY_LOCALE my_locale_fr_CA
&my_locale_typelib_month_names_fr_FR,
&my_locale_typelib_ab_month_names_fr_FR,
&my_locale_typelib_day_names_fr_FR,
- &my_locale_typelib_ab_day_names_fr_FR
+ &my_locale_typelib_ab_day_names_fr_FR,
+ 9,
+ 8
);
/***** LOCALE END fr_CA *****/
@@ -2373,7 +2577,9 @@ MY_LOCALE my_locale_fr_CH
&my_locale_typelib_month_names_fr_FR,
&my_locale_typelib_ab_month_names_fr_FR,
&my_locale_typelib_day_names_fr_FR,
- &my_locale_typelib_ab_day_names_fr_FR
+ &my_locale_typelib_ab_day_names_fr_FR,
+ 9,
+ 8
);
/***** LOCALE END fr_CH *****/
@@ -2387,7 +2593,9 @@ MY_LOCALE my_locale_fr_LU
&my_locale_typelib_month_names_fr_FR,
&my_locale_typelib_ab_month_names_fr_FR,
&my_locale_typelib_day_names_fr_FR,
- &my_locale_typelib_ab_day_names_fr_FR
+ &my_locale_typelib_ab_day_names_fr_FR,
+ 9,
+ 8
);
/***** LOCALE END fr_LU *****/
@@ -2401,7 +2609,9 @@ MY_LOCALE my_locale_it_IT
&my_locale_typelib_month_names_it_CH,
&my_locale_typelib_ab_month_names_it_CH,
&my_locale_typelib_day_names_it_CH,
- &my_locale_typelib_ab_day_names_it_CH
+ &my_locale_typelib_ab_day_names_it_CH,
+ 9,
+ 9
);
/***** LOCALE END it_IT *****/
@@ -2415,7 +2625,9 @@ MY_LOCALE my_locale_nl_BE
&my_locale_typelib_month_names_nl_NL,
&my_locale_typelib_ab_month_names_nl_NL,
&my_locale_typelib_day_names_nl_NL,
- &my_locale_typelib_ab_day_names_nl_NL
+ &my_locale_typelib_ab_day_names_nl_NL,
+ 9,
+ 9
);
/***** LOCALE END nl_BE *****/
@@ -2429,7 +2641,9 @@ MY_LOCALE my_locale_no_NO
&my_locale_typelib_month_names_nb_NO,
&my_locale_typelib_ab_month_names_nb_NO,
&my_locale_typelib_day_names_nb_NO,
- &my_locale_typelib_ab_day_names_nb_NO
+ &my_locale_typelib_ab_day_names_nb_NO,
+ 9,
+ 7
);
/***** LOCALE END no_NO *****/
@@ -2443,7 +2657,9 @@ MY_LOCALE my_locale_sv_FI
&my_locale_typelib_month_names_sv_SE,
&my_locale_typelib_ab_month_names_sv_SE,
&my_locale_typelib_day_names_sv_SE,
- &my_locale_typelib_ab_day_names_sv_SE
+ &my_locale_typelib_ab_day_names_sv_SE,
+ 9,
+ 7
);
/***** LOCALE END sv_FI *****/
@@ -2457,7 +2673,9 @@ MY_LOCALE my_locale_zh_HK
&my_locale_typelib_month_names_zh_CN,
&my_locale_typelib_ab_month_names_zh_CN,
&my_locale_typelib_day_names_zh_CN,
- &my_locale_typelib_ab_day_names_zh_CN
+ &my_locale_typelib_ab_day_names_zh_CN,
+ 3,
+ 3
);
/***** LOCALE END zh_HK *****/
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 4b9f3b4241a..b587d172b68 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2003 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -979,8 +979,24 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->set_time();
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_id= global_query_id;
- if (command != COM_STATISTICS && command != COM_PING)
+
+ switch( command ) {
+ /* Ignore these statements. */
+ case COM_STATISTICS:
+ case COM_PING:
+ break;
+ /* Only increase id on these statements but don't count them. */
+ case COM_STMT_PREPARE:
+ case COM_STMT_CLOSE:
+ case COM_STMT_RESET:
next_query_id();
+ break;
+ /* Increase id and count all other statements. */
+ default:
+ statistic_increment(thd->status_var.questions, &LOCK_status);
+ next_query_id();
+ }
+
thread_running++;
/* TODO: set thd->lex->sql_command to SQLCOM_END here */
VOID(pthread_mutex_unlock(&LOCK_thread_count));
@@ -1241,6 +1257,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_length= length;
thd->query= beginning_of_next_stmt;
+ /*
+ Count each statement from the client.
+ */
+ statistic_increment(thd->status_var.questions, &LOCK_status);
thd->query_id= next_query_id();
thd->set_time(); /* Reset the query start time. */
/* TODO: set thd->lex->sql_command to SQLCOM_END here */
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index dea6030e378..41766d15c2a 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2006 MySQL AB
+/* Copyright 2005-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -4233,9 +4233,8 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
after the change as before. Thus we can reply ok immediately
without any changes at all.
*/
- DBUG_RETURN(fast_end_partition(thd, ULL(0), ULL(0),
- table, NULL,
- TRUE, NULL, FALSE));
+ *fast_alter_partition= TRUE;
+ DBUG_RETURN(FALSE);
}
else if (new_part_no > curr_part_no)
{
@@ -5304,8 +5303,8 @@ static bool write_log_changed_partitions(ALTER_PARTITION_PARAM_TYPE *lpt,
DDL_LOG_ENTRY ddl_log_entry;
partition_info *part_info= lpt->part_info;
DDL_LOG_MEMORY_ENTRY *log_entry;
- char tmp_path[FN_LEN];
- char normal_path[FN_LEN];
+ char tmp_path[FN_REFLEN];
+ char normal_path[FN_REFLEN];
List_iterator<partition_element> part_it(part_info->partitions);
uint temp_partitions= part_info->temp_partitions.elements;
uint no_elements= part_info->partitions.elements;
@@ -5516,7 +5515,7 @@ static bool write_log_drop_shadow_frm(ALTER_PARTITION_PARAM_TYPE *lpt)
partition_info *part_info= lpt->part_info;
DDL_LOG_MEMORY_ENTRY *log_entry;
DDL_LOG_MEMORY_ENTRY *exec_log_entry= NULL;
- char shadow_path[FN_LEN];
+ char shadow_path[FN_REFLEN];
DBUG_ENTER("write_log_drop_shadow_frm");
build_table_shadow_filename(shadow_path, sizeof(shadow_path), lpt);
@@ -5559,8 +5558,8 @@ static bool write_log_rename_frm(ALTER_PARTITION_PARAM_TYPE *lpt)
partition_info *part_info= lpt->part_info;
DDL_LOG_MEMORY_ENTRY *log_entry;
DDL_LOG_MEMORY_ENTRY *exec_log_entry= part_info->exec_log_entry;
- char path[FN_LEN];
- char shadow_path[FN_LEN];
+ char path[FN_REFLEN];
+ char shadow_path[FN_REFLEN];
DDL_LOG_MEMORY_ENTRY *old_first_log_entry= part_info->first_log_entry;
DBUG_ENTER("write_log_rename_frm");
@@ -5610,8 +5609,8 @@ static bool write_log_drop_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
partition_info *part_info= lpt->part_info;
DDL_LOG_MEMORY_ENTRY *log_entry;
DDL_LOG_MEMORY_ENTRY *exec_log_entry= part_info->exec_log_entry;
- char tmp_path[FN_LEN];
- char path[FN_LEN];
+ char tmp_path[FN_REFLEN];
+ char path[FN_REFLEN];
uint next_entry= 0;
DDL_LOG_MEMORY_ENTRY *old_first_log_entry= part_info->first_log_entry;
DBUG_ENTER("write_log_drop_partition");
@@ -5669,8 +5668,8 @@ static bool write_log_add_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
partition_info *part_info= lpt->part_info;
DDL_LOG_MEMORY_ENTRY *log_entry;
DDL_LOG_MEMORY_ENTRY *exec_log_entry= NULL;
- char tmp_path[FN_LEN];
- char path[FN_LEN];
+ char tmp_path[FN_REFLEN];
+ char path[FN_REFLEN];
uint next_entry= 0;
DBUG_ENTER("write_log_add_change_partition");
@@ -5723,8 +5722,8 @@ static bool write_log_final_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
partition_info *part_info= lpt->part_info;
DDL_LOG_MEMORY_ENTRY *log_entry;
DDL_LOG_MEMORY_ENTRY *exec_log_entry= part_info->exec_log_entry;
- char path[FN_LEN];
- char shadow_path[FN_LEN];
+ char path[FN_REFLEN];
+ char shadow_path[FN_REFLEN];
DDL_LOG_MEMORY_ENTRY *old_first_log_entry= part_info->first_log_entry;
uint next_entry= 0;
DBUG_ENTER("write_log_final_change_partition");
@@ -6679,6 +6678,7 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
uint32 max_endpoint_val;
get_endpoint_func get_endpoint;
uint field_len= field->pack_length_in_rec();
+ part_iter->ret_null_part= part_iter->ret_null_part_orig= FALSE;
if (part_info->part_type == RANGE_PARTITION)
{
@@ -6699,7 +6699,6 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
max_endpoint_val= part_info->no_list_values;
part_iter->get_next= get_next_partition_id_list;
part_iter->part_info= part_info;
- part_iter->ret_null_part= part_iter->ret_null_part_orig= FALSE;
if (max_endpoint_val == 0)
{
/*
@@ -6761,7 +6760,7 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
store_key_image_to_rec(field, max_value, field_len);
bool include_endp= !test(flags & NEAR_MAX);
part_iter->part_nums.end= get_endpoint(part_info, 0, include_endp);
- if (part_iter->part_nums.start == part_iter->part_nums.end &&
+ if (part_iter->part_nums.start >= part_iter->part_nums.end &&
!part_iter->ret_null_part)
return 0; /* No partitions */
}
@@ -6939,7 +6938,7 @@ int get_part_iter_for_interval_via_walking(partition_info *part_info,
uint32 get_next_partition_id_range(PARTITION_ITERATOR* part_iter)
{
- if (part_iter->part_nums.cur == part_iter->part_nums.end)
+ if (part_iter->part_nums.cur >= part_iter->part_nums.end)
{
part_iter->part_nums.cur= part_iter->part_nums.start;
return NOT_A_PARTITION_ID;
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 7d3b6f86b8c..5a961109ab2 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -751,21 +751,22 @@ static bool plugin_add(MEM_ROOT *tmp_root,
tmp.name.length= name_len;
tmp.ref_count= 0;
tmp.state= PLUGIN_IS_UNINITIALIZED;
- if (!test_plugin_options(tmp_root, &tmp, argc, argv, true))
+ if (test_plugin_options(tmp_root, &tmp, argc, argv, true))
+ tmp.state= PLUGIN_IS_DISABLED;
+
+ if ((tmp_plugin_ptr= plugin_insert_or_reuse(&tmp)))
{
- if ((tmp_plugin_ptr= plugin_insert_or_reuse(&tmp)))
+ plugin_array_version++;
+ if (!my_hash_insert(&plugin_hash[plugin->type], (uchar*)tmp_plugin_ptr))
{
- plugin_array_version++;
- if (!my_hash_insert(&plugin_hash[plugin->type], (uchar*)tmp_plugin_ptr))
- {
- init_alloc_root(&tmp_plugin_ptr->mem_root, 4096, 4096);
- DBUG_RETURN(FALSE);
- }
- tmp_plugin_ptr->state= PLUGIN_IS_FREED;
+ init_alloc_root(&tmp_plugin_ptr->mem_root, 4096, 4096);
+ DBUG_RETURN(FALSE);
}
- mysql_del_sys_var_chain(tmp.system_vars);
- goto err;
+ tmp_plugin_ptr->state= PLUGIN_IS_FREED;
}
+ mysql_del_sys_var_chain(tmp.system_vars);
+ goto err;
+
/* plugin was disabled */
plugin_dl_del(dl);
DBUG_RETURN(FALSE);
@@ -1145,11 +1146,12 @@ int plugin_init(int *argc, char **argv, int flags)
tmp.plugin= plugin;
tmp.name.str= (char *)plugin->name;
tmp.name.length= strlen(plugin->name);
-
+ tmp.state= 0;
free_root(&tmp_root, MYF(MY_MARK_BLOCKS_FREE));
if (test_plugin_options(&tmp_root, &tmp, argc, argv, def_enabled))
- continue;
-
+ tmp.state= PLUGIN_IS_DISABLED;
+ else
+ tmp.state= PLUGIN_IS_UNINITIALIZED;
if (register_builtin(plugin, &tmp, &plugin_ptr))
goto err_unlock;
@@ -1159,7 +1161,8 @@ int plugin_init(int *argc, char **argv, int flags)
my_strcasecmp(&my_charset_latin1, plugin->name, "CSV"))
continue;
- if (plugin_initialize(plugin_ptr))
+ if (plugin_ptr->state == PLUGIN_IS_UNINITIALIZED &&
+ plugin_initialize(plugin_ptr))
goto err_unlock;
/*
@@ -1246,8 +1249,6 @@ static bool register_builtin(struct st_mysql_plugin *plugin,
struct st_plugin_int **ptr)
{
DBUG_ENTER("register_builtin");
-
- tmp->state= PLUGIN_IS_UNINITIALIZED;
tmp->ref_count= 0;
tmp->plugin_dl= 0;
@@ -1296,7 +1297,7 @@ bool plugin_register_builtin(THD *thd, struct st_mysql_plugin *plugin)
if (test_plugin_options(thd->mem_root, &tmp, &dummy_argc, NULL, true))
goto end;
-
+ tmp.state= PLUGIN_IS_UNINITIALIZED;
if ((result= register_builtin(plugin, &tmp, &ptr)))
mysql_del_sys_var_chain(tmp.system_vars);
@@ -1534,7 +1535,7 @@ void plugin_shutdown(void)
}
}
- if (count > free_slots)
+ if (count > free_slots && global_system_variables.log_warnings > 1)
sql_print_warning("Forcing shutdown of %d plugins", count - free_slots);
plugins= (struct st_plugin_int **) my_alloca(sizeof(void*) * (count+1));
@@ -1555,7 +1556,8 @@ void plugin_shutdown(void)
We loop through all plugins and call deinit() if they have one.
*/
for (i= 0; i < count; i++)
- if (!(plugins[i]->state & (PLUGIN_IS_UNINITIALIZED | PLUGIN_IS_FREED)))
+ if (!(plugins[i]->state & (PLUGIN_IS_UNINITIALIZED | PLUGIN_IS_FREED |
+ PLUGIN_IS_DISABLED)))
{
sql_print_information("Plugin '%s' will be forced to shutdown",
plugins[i]->name.str);
diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h
index e8f2cb6ee5e..8ae38d58845 100644
--- a/sql/sql_plugin.h
+++ b/sql/sql_plugin.h
@@ -54,6 +54,7 @@ typedef struct st_mysql_show_var SHOW_VAR;
#define PLUGIN_IS_UNINITIALIZED 4
#define PLUGIN_IS_READY 8
#define PLUGIN_IS_DYING 16
+#define PLUGIN_IS_DISABLED 32
/* A handle for the dynamic library containing a plugin or plugins. */
diff --git a/sql/sql_profile.cc b/sql/sql_profile.cc
index 6f234a2a626..320360b2587 100644
--- a/sql/sql_profile.cc
+++ b/sql/sql_profile.cc
@@ -549,8 +549,8 @@ int PROFILING::fill_statistics_info(THD *thd, TABLE_LIST *tables, Item *cond)
The order of these fields is set by the query_profile_statistics_info
array.
*/
- table->field[0]->store((ulonglong) query->profiling_query_id);
- table->field[1]->store((ulonglong) seq); /* the step in the sequence */
+ table->field[0]->store((ulonglong) query->profiling_query_id, TRUE);
+ table->field[1]->store((ulonglong) seq, TRUE); /* the step in the sequence */
/*
This entry, n, has a point in time, T(n), and a status phrase, S(n).
The status phrase S(n) describes the period of time that begins at
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 126bc7c03b3..14088961ea2 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -63,7 +63,7 @@ static int fake_rotate_event(NET* net, String* packet, char* log_file_name,
ulong event_len = ident_len + LOG_EVENT_HEADER_LEN + ROTATE_HEADER_LEN;
int4store(header + SERVER_ID_OFFSET, server_id);
int4store(header + EVENT_LEN_OFFSET, event_len);
- int2store(header + FLAGS_OFFSET, 0);
+ int2store(header + FLAGS_OFFSET, LOG_EVENT_ARTIFICIAL_F);
// TODO: check what problems this may cause and fix them
int4store(header + LOG_POS_OFFSET, 0);
@@ -257,6 +257,17 @@ bool purge_error_message(THD* thd, int res)
}
+/**
+ Execute a PURGE BINARY LOGS TO <log> command.
+
+ @param thd Pointer to THD object for the client thread executing the
+ statement.
+
+ @param to_log Name of the last log to purge.
+
+ @retval FALSE success
+ @retval TRUE failure
+*/
bool purge_master_logs(THD* thd, const char* to_log)
{
char search_file_name[FN_REFLEN];
@@ -273,6 +284,17 @@ bool purge_master_logs(THD* thd, const char* to_log)
}
+/**
+ Execute a PURGE BINARY LOGS BEFORE <date> command.
+
+ @param thd Pointer to THD object for the client thread executing the
+ statement.
+
+ @param purge_time Date before which logs should be purged.
+
+ @retval FALSE success
+ @retval TRUE failure
+*/
bool purge_master_logs_before_date(THD* thd, time_t purge_time)
{
if (!mysql_bin_log.is_open())
@@ -765,6 +787,20 @@ err:
DBUG_VOID_RETURN;
}
+
+/**
+ Execute a START SLAVE statement.
+
+ @param thd Pointer to THD object for the client thread executing the
+ statement.
+
+ @param mi Pointer to Master_info object for the slave's IO thread.
+
+ @param net_report If true, saves the exit status into thd->main_da.
+
+ @retval 0 success
+ @retval 1 error
+*/
int start_slave(THD* thd , Master_info* mi, bool net_report)
{
int slave_errno= 0;
@@ -890,6 +926,19 @@ int start_slave(THD* thd , Master_info* mi, bool net_report)
}
+/**
+ Execute a STOP SLAVE statement.
+
+ @param thd Pointer to THD object for the client thread executing the
+ statement.
+
+ @param mi Pointer to Master_info object for the slave's IO thread.
+
+ @param net_report If true, saves the exit status into thd->main_da.
+
+ @retval 0 success
+ @retval 1 error
+*/
int stop_slave(THD* thd, Master_info* mi, bool net_report )
{
DBUG_ENTER("stop_slave");
@@ -942,20 +991,17 @@ int stop_slave(THD* thd, Master_info* mi, bool net_report )
}
-/*
- Remove all relay logs and start replication from the start
-
- SYNOPSIS
- reset_slave()
- thd Thread handler
- mi Master info for the slave
+/**
+ Execute a RESET SLAVE statement.
- RETURN
- 0 ok
- 1 error
-*/
+ @param thd Pointer to THD object of the client thread executing the
+ statement.
+ @param mi Pointer to Master_info object for the slave.
+ @retval 0 success
+ @retval 1 error
+*/
int reset_slave(THD *thd, Master_info* mi)
{
MY_STAT stat_area;
@@ -1070,6 +1116,18 @@ void kill_zombie_dump_threads(uint32 slave_server_id)
}
+/**
+ Execute a CHANGE MASTER statement.
+
+ @param thd Pointer to THD object for the client thread executing the
+ statement.
+
+ @param mi Pointer to Master_info object belonging to the slave's IO
+ thread.
+
+ @retval FALSE success
+ @retval TRUE error
+*/
bool change_master(THD* thd, Master_info* mi)
{
int thread_mask;
@@ -1283,6 +1341,16 @@ bool change_master(THD* thd, Master_info* mi)
DBUG_RETURN(FALSE);
}
+
+/**
+ Execute a RESET MASTER statement.
+
+ @param thd Pointer to THD object of the client thread executing the
+ statement.
+
+ @retval 0 success
+ @retval 1 error
+*/
int reset_master(THD* thd)
{
if (!mysql_bin_log.is_open())
@@ -1312,6 +1380,15 @@ int cmp_master_pos(const char* log_file_name1, ulonglong log_pos1,
}
+/**
+ Execute a SHOW BINLOG EVENTS statement.
+
+ @param thd Pointer to THD object for the client thread executing the
+ statement.
+
+ @retval FALSE success
+ @retval TRUE failure
+*/
bool mysql_show_binlog_events(THD* thd)
{
Protocol *protocol= thd->protocol;
@@ -1462,6 +1539,15 @@ err:
}
+/**
+ Execute a SHOW MASTER STATUS statement.
+
+ @param thd Pointer to THD object for the client thread executing the
+ statement.
+
+ @retval FALSE success
+ @retval TRUE failure
+*/
bool show_binlog_info(THD* thd)
{
Protocol *protocol= thd->protocol;
@@ -1495,18 +1581,15 @@ bool show_binlog_info(THD* thd)
}
-/*
- Send a list of all binary logs to client
+/**
+ Execute a SHOW BINARY LOGS statement.
- SYNOPSIS
- show_binlogs()
- thd Thread specific variable
+ @param thd Pointer to THD object for the client thread executing the
+ statement.
- RETURN VALUES
- FALSE OK
- TRUE error
+ @retval FALSE success
+ @retval TRUE failure
*/
-
bool show_binlogs(THD* thd)
{
IO_CACHE *index_file;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 828656005e7..5f755660c65 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2006 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1677,8 +1677,11 @@ JOIN::exec()
(zero_result_cause?zero_result_cause:"No tables used"));
else
{
- result->send_fields(*columns_list,
- Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
+ if (result->send_fields(*columns_list,
+ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
+ {
+ DBUG_VOID_RETURN;
+ }
/*
We have to test for 'conds' here as the WHERE may not be constant
even if we don't have any tables for prepared statements or if
@@ -2606,7 +2609,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
if (s->dependent & table->map)
s->dependent |= table->reginfo.join_tab->dependent;
}
- if (s->dependent)
+ if (outer_join & s->table->map)
s->table->maybe_null= 1;
}
/* Catch illegal cross references for outer joins */
@@ -14063,6 +14066,7 @@ join_init_cache(THD *thd,JOIN_TAB *tables,uint table_count)
length=0;
for (i=0 ; i < table_count ; i++)
{
+ bool have_bit_fields= FALSE;
uint null_fields=0,used_fields;
Field **f_ptr,*field;
MY_BITMAP *read_set= tables[i].table->read_set;
@@ -14077,13 +14081,16 @@ join_init_cache(THD *thd,JOIN_TAB *tables,uint table_count)
length+=field->fill_cache_field(copy);
if (copy->blob_field)
(*blob_ptr++)=copy;
- if (field->maybe_null())
+ if (field->real_maybe_null())
null_fields++;
+ if (field->type() == MYSQL_TYPE_BIT &&
+ ((Field_bit*)field)->bit_len)
+ have_bit_fields= TRUE;
copy++;
}
}
/* Copy null bits from table */
- if (null_fields && tables[i].table->s->null_fields)
+ if (null_fields || have_bit_fields)
{ /* must copy null bits */
copy->str= tables[i].table->null_flags;
copy->length= tables[i].table->s->null_bytes;
diff --git a/sql/sql_select.h b/sql/sql_select.h
index c8922d9045e..eacd3d39905 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -285,7 +285,11 @@ public:
fetching data from a cursor
*/
bool resume_nested_loop;
- table_map const_table_map,found_const_table_map,outer_join;
+ table_map const_table_map,found_const_table_map;
+ /*
+ Bitmap of all inner tables from outer joins
+ */
+ table_map outer_join;
ha_rows send_records,found_records,examined_rows,row_limit, select_limit;
/**
Used to fetch no more than given amount of rows per one
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 570a98b3aa3..697a9d42bca 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2004 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -112,7 +112,6 @@ static my_bool show_plugins(THD *thd, plugin_ref plugin,
make_version_string(version_buf, sizeof(version_buf), plug->version),
cs);
-
switch (plugin_state(plugin)) {
/* case PLUGIN_IS_FREED: does not happen */
case PLUGIN_IS_DELETED:
@@ -124,6 +123,9 @@ static my_bool show_plugins(THD *thd, plugin_ref plugin,
case PLUGIN_IS_READY:
table->field[2]->store(STRING_WITH_LEN("ACTIVE"), cs);
break;
+ case PLUGIN_IS_DISABLED:
+ table->field[2]->store(STRING_WITH_LEN("DISABLED"), cs);
+ break;
default:
DBUG_ASSERT(0);
}
@@ -471,6 +473,7 @@ find_files(THD *thd, List<LEX_STRING> *files, const char *db,
if (wild && !wild[0])
wild=0;
+
bzero((char*) &table_list,sizeof(table_list));
if (!(dirp = my_dir(path,MYF(dir ? MY_WANT_STAT : 0))))
@@ -993,15 +996,14 @@ static bool get_field_default_value(THD *thd, TABLE *table,
{
bool has_default;
bool has_now_default;
-
+ enum enum_field_types field_type= field->type();
/*
- We are using CURRENT_TIMESTAMP instead of NOW because it is
- more standard
+ We are using CURRENT_TIMESTAMP instead of NOW because it is
+ more standard
*/
has_now_default= table->timestamp_field == field &&
field->unireg_check != Field::TIMESTAMP_UN_FIELD;
-
- has_default= (field->type() != FIELD_TYPE_BLOB &&
+ has_default= (field_type != FIELD_TYPE_BLOB &&
!(field->flags & NO_DEFAULT_VALUE_FLAG) &&
field->unireg_check != Field::NEXT_NUMBER &&
!((thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40))
@@ -1016,7 +1018,19 @@ static bool get_field_default_value(THD *thd, TABLE *table,
{ // Not null by default
char tmp[MAX_FIELD_WIDTH];
String type(tmp, sizeof(tmp), field->charset());
- field->val_str(&type);
+ if (field_type == MYSQL_TYPE_BIT)
+ {
+ longlong dec= field->val_int();
+ char *ptr= longlong2str(dec, tmp + 2, 2);
+ uint32 length= (uint32) (ptr - tmp);
+ tmp[0]= 'b';
+ tmp[1]= '\'';
+ tmp[length]= '\'';
+ type.length(length + 1);
+ quoted= 0;
+ }
+ else
+ field->val_str(&type);
if (type.length())
{
String def_val;
@@ -2092,7 +2106,7 @@ static bool show_status_array(THD *thd, const char *wild,
CHARSET_INFO *charset= system_charset_info;
DBUG_ENTER("show_status_array");
- thd->count_cuted_fields= CHECK_FIELD_WARN;
+ thd->count_cuted_fields= CHECK_FIELD_WARN;
null_lex_str.str= 0; // For sys_var->value_ptr()
null_lex_str.length= 0;
@@ -3571,6 +3585,11 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
ptr=strxmov(ptr, " row_format=",
ha_row_type[(uint) share->row_type],
NullS);
+ if (share->key_block_size)
+ {
+ ptr= strmov(ptr, " key_block_size=");
+ ptr= longlong10_to_str(share->key_block_size, ptr, 10);
+ }
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (is_partitioned)
ptr= strmov(ptr, " partitioned");
@@ -3907,6 +3926,25 @@ static my_bool iter_schema_engines(THD *thd, plugin_ref plugin,
handlerton *default_type= ha_default_handlerton(thd);
DBUG_ENTER("iter_schema_engines");
+
+ /* Disabled plugins */
+ if (plugin_state(plugin) != PLUGIN_IS_READY)
+ {
+
+ struct st_mysql_plugin *plug= plugin_decl(plugin);
+ if (!(wild && wild[0] &&
+ wild_case_compare(scs, plug->name,wild)))
+ {
+ restore_record(table, s->default_values);
+ table->field[0]->store(plug->name, strlen(plug->name), scs);
+ table->field[1]->store(C_STRING_WITH_LEN("NO"), scs);
+ table->field[2]->store(plug->descr, strlen(plug->descr), scs);
+ if (schema_table_store_record(thd, table))
+ DBUG_RETURN(1);
+ }
+ DBUG_RETURN(0);
+ }
+
if (!(hton->flags & HTON_HIDDEN))
{
LEX_STRING *name= plugin_name(plugin);
@@ -3927,10 +3965,13 @@ static my_bool iter_schema_engines(THD *thd, plugin_ref plugin,
strlen(plugin_decl(plugin)->descr), scs);
tmp= &yesno[test(hton->commit)];
table->field[3]->store(tmp->str, tmp->length, scs);
+ table->field[3]->set_notnull();
tmp= &yesno[test(hton->prepare)];
table->field[4]->store(tmp->str, tmp->length, scs);
+ table->field[4]->set_notnull();
tmp= &yesno[test(hton->savepoint_set)];
table->field[5]->store(tmp->str, tmp->length, scs);
+ table->field[5]->set_notnull();
if (schema_table_store_record(thd, table))
DBUG_RETURN(1);
@@ -3941,8 +3982,12 @@ static my_bool iter_schema_engines(THD *thd, plugin_ref plugin,
int fill_schema_engines(THD *thd, TABLE_LIST *tables, COND *cond)
{
- return plugin_foreach(thd, iter_schema_engines,
- MYSQL_STORAGE_ENGINE_PLUGIN, tables->table);
+ DBUG_ENTER("fill_schema_engines");
+ if (plugin_foreach_with_mask(thd, iter_schema_engines,
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ ~PLUGIN_IS_FREED, tables->table))
+ DBUG_RETURN(1);
+ DBUG_RETURN(0);
}
@@ -5362,7 +5407,7 @@ get_referential_constraints_record(THD *thd, TABLE_LIST *tables,
f_key_info->referenced_table->length, cs);
if (f_key_info->referenced_key_name)
{
- table->field[5]->store(f_key_info->referenced_key_name->str,
+ table->field[5]->store(f_key_info->referenced_key_name->str,
f_key_info->referenced_key_name->length, cs);
table->field[5]->set_notnull();
}
@@ -6139,9 +6184,9 @@ ST_FIELD_INFO engines_fields_info[]=
{"ENGINE", 64, MYSQL_TYPE_STRING, 0, 0, "Engine", SKIP_OPEN_TABLE},
{"SUPPORT", 8, MYSQL_TYPE_STRING, 0, 0, "Support", SKIP_OPEN_TABLE},
{"COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, "Comment", SKIP_OPEN_TABLE},
- {"TRANSACTIONS", 3, MYSQL_TYPE_STRING, 0, 0, "Transactions", SKIP_OPEN_TABLE},
- {"XA", 3, MYSQL_TYPE_STRING, 0, 0, "XA", SKIP_OPEN_TABLE},
- {"SAVEPOINTS", 3 ,MYSQL_TYPE_STRING, 0, 0, "Savepoints", SKIP_OPEN_TABLE},
+ {"TRANSACTIONS", 3, MYSQL_TYPE_STRING, 0, 1, "Transactions", SKIP_OPEN_TABLE},
+ {"XA", 3, MYSQL_TYPE_STRING, 0, 1, "XA", SKIP_OPEN_TABLE},
+ {"SAVEPOINTS", 3 ,MYSQL_TYPE_STRING, 0, 1, "Savepoints", SKIP_OPEN_TABLE},
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
};
@@ -6641,7 +6686,7 @@ ST_SCHEMA_TABLE schema_tables[]=
{"PROCESSLIST", processlist_fields_info, create_schema_table,
fill_schema_processlist, make_old_format, 0, -1, -1, 0, 0},
{"PROFILING", query_profile_statistics_info, create_schema_table,
- fill_query_profile_statistics_info, make_profile_table_for_show,
+ fill_query_profile_statistics_info, make_profile_table_for_show,
NULL, -1, -1, false, 0},
{"REFERENTIAL_CONSTRAINTS", referential_constraints_fields_info,
create_schema_table, get_all_tables, 0, get_referential_constraints_record,
@@ -6656,12 +6701,12 @@ ST_SCHEMA_TABLE schema_tables[]=
fill_status, make_old_format, 0, 0, -1, 0, 0},
{"SESSION_VARIABLES", variables_fields_info, create_schema_table,
fill_variables, make_old_format, 0, 0, -1, 0, 0},
- {"STATISTICS", stat_fields_info, create_schema_table,
+ {"STATISTICS", stat_fields_info, create_schema_table,
get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0,
OPEN_TABLE_ONLY|OPTIMIZE_I_S_TABLE},
- {"STATUS", variables_fields_info, create_schema_table, fill_status,
+ {"STATUS", variables_fields_info, create_schema_table, fill_status,
make_old_format, 0, 0, -1, 1, 0},
- {"TABLES", tables_fields_info, create_schema_table,
+ {"TABLES", tables_fields_info, create_schema_table,
get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0,
OPTIMIZE_I_S_TABLE},
{"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table,
@@ -6677,7 +6722,7 @@ ST_SCHEMA_TABLE schema_tables[]=
fill_schema_user_privileges, 0, 0, -1, -1, 0, 0},
{"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
make_old_format, 0, 0, -1, 1, 0},
- {"VIEWS", view_fields_info, create_schema_table,
+ {"VIEWS", view_fields_info, create_schema_table,
get_all_tables, 0, get_schema_views_record, 1, 2, 0,
OPEN_VIEW_ONLY|OPTIMIZE_I_S_TABLE},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
diff --git a/sql/sql_show.h b/sql/sql_show.h
index 3baaef00a7d..fa067a46033 100644
--- a/sql/sql_show.h
+++ b/sql/sql_show.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 MySQL AB
+/* Copyright 2006-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index e91a82a0b1d..47440c2cfe4 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2004 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -114,6 +114,30 @@ uint filename_to_tablename(const char *from, char *to, uint to_length)
}
+/**
+ Check if given string begins with "#mysql50#" prefix, cut it if so.
+
+ @param from string to check and cut
+ @param to[out] buffer for result string
+ @param to_length its size
+
+ @retval
+ 0 no prefix found
+ @retval
+ non-0 result string length
+*/
+
+uint check_n_cut_mysql50_prefix(const char *from, char *to, uint to_length)
+{
+ if (from[0] == '#' &&
+ !strncmp(from, MYSQL50_TABLE_NAME_PREFIX,
+ MYSQL50_TABLE_NAME_PREFIX_LENGTH))
+ return (uint) (strmake(to, from + MYSQL50_TABLE_NAME_PREFIX_LENGTH,
+ to_length - 1) - to);
+ return 0;
+}
+
+
/*
Translate a table name to a file name (WL #1324).
@@ -133,11 +157,8 @@ uint tablename_to_filename(const char *from, char *to, uint to_length)
DBUG_ENTER("tablename_to_filename");
DBUG_PRINT("enter", ("from '%s'", from));
- if (from[0] == '#' && !strncmp(from, MYSQL50_TABLE_NAME_PREFIX,
- MYSQL50_TABLE_NAME_PREFIX_LENGTH))
- DBUG_RETURN((uint) (strmake(to, from+MYSQL50_TABLE_NAME_PREFIX_LENGTH,
- to_length-1) -
- (from + MYSQL50_TABLE_NAME_PREFIX_LENGTH)));
+ if ((length= check_n_cut_mysql50_prefix(from, to, to_length)))
+ DBUG_RETURN(length);
length= strconvert(system_charset_info, from,
&my_charset_filename, to, to_length, &errors);
if (check_if_legal_tablename(to) &&
@@ -3111,10 +3132,12 @@ static bool prepare_blob_field(THD *thd, Create_field *sql_field)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_AUTO_CONVERT,
warn_buff);
}
-
+
if ((sql_field->flags & BLOB_FLAG) && sql_field->length)
{
- if (sql_field->sql_type == MYSQL_TYPE_BLOB)
+ if (sql_field->sql_type == FIELD_TYPE_BLOB ||
+ sql_field->sql_type == FIELD_TYPE_TINY_BLOB ||
+ sql_field->sql_type == FIELD_TYPE_MEDIUM_BLOB)
{
/* The user has given a length to the blob column */
sql_field->sql_type= get_blob_type_from_length(sql_field->length);
@@ -3426,14 +3449,6 @@ bool mysql_create_table_no_lock(THD *thd,
}
else
{
- #ifdef FN_DEVCHAR
- /* check if the table name contains FN_DEVCHAR when defined */
- if (strchr(alias, FN_DEVCHAR))
- {
- my_error(ER_WRONG_TABLE_NAME, MYF(0), alias);
- DBUG_RETURN(TRUE);
- }
-#endif
path_length= build_table_filename(path, sizeof(path), db, alias, reg_ext,
internal_tmp_table ? FN_IS_TMP : 0);
}
@@ -4328,6 +4343,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
table->table=0; // For query cache
if (protocol->write())
goto err;
+ thd->main_da.reset_diagnostics_area();
continue;
/* purecov: end */
}
@@ -5881,7 +5897,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
if (key_info->flags & HA_USES_BLOCK_SIZE)
key_create_info.block_size= key_info->block_size;
if (key_info->flags & HA_USES_PARSER)
- key_create_info.parser_name= *key_info->parser_name;
+ key_create_info.parser_name= *plugin_name(key_info->parser);
if (key_info->flags & HA_SPATIAL)
key_type= Key::SPATIAL;
diff --git a/sql/sql_test.cc b/sql/sql_test.cc
index 01363714484..78932396efe 100644
--- a/sql/sql_test.cc
+++ b/sql/sql_test.cc
@@ -513,7 +513,7 @@ Next alarm time: %lu\n",
fprintf(stdout,"\nBegin safemalloc memory dump:\n"); // tag needed for test suite
TERMINATE(stdout, 1); // Write malloc information
fprintf(stdout,"\nEnd safemalloc memory dump.\n");
-
+ fflush(stdout);
#ifdef HAVE_MALLINFO
struct mallinfo info= mallinfo();
printf("\nMemory status:\n\
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index 7fe487c87cf..bad8db56f02 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -1368,15 +1368,27 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
if (triggers->on_table_names_list.push_back(on_table_name, &table->mem_root))
goto err_with_lex_cleanup;
-
+#ifndef DBUG_OFF
/*
Let us check that we correctly update trigger definitions when we
rename tables with triggers.
+
+ In special cases like "RENAME TABLE `#mysql50#somename` TO `somename`"
+ or "ALTER DATABASE `#mysql50#somename` UPGRADE DATA DIRECTORY NAME"
+ we might be given table or database name with "#mysql50#" prefix (and
+ trigger's definiton contains un-prefixed version of the same name).
+ To remove this prefix we use check_n_cut_mysql50_prefix().
*/
- DBUG_ASSERT(!my_strcasecmp(table_alias_charset, lex.query_tables->db, db) &&
- !my_strcasecmp(table_alias_charset, lex.query_tables->table_name,
- table_name));
+ char fname[NAME_LEN + 1];
+ DBUG_ASSERT((!my_strcasecmp(table_alias_charset, lex.query_tables->db, db) ||
+ (check_n_cut_mysql50_prefix(db, fname, sizeof(fname)) &&
+ !my_strcasecmp(table_alias_charset, lex.query_tables->db, fname))) &&
+ (!my_strcasecmp(table_alias_charset, lex.query_tables->table_name,
+ table_name) ||
+ (check_n_cut_mysql50_prefix(table_name, fname, sizeof(fname)) &&
+ !my_strcasecmp(table_alias_charset, lex.query_tables->table_name, fname))));
+#endif
if (names_only)
{
lex_end(&lex);
@@ -1692,7 +1704,8 @@ end:
(change name of table in triggers' definitions).
@param thd Thread context
- @param db_name Database of subject table
+ @param old_db_name Old database of subject table
+ @param new_db_name New database of subject table
@param old_table_name Old subject table's name
@param new_table_name New subject table's name
@@ -1704,7 +1717,8 @@ end:
bool
Table_triggers_list::change_table_name_in_triggers(THD *thd,
- const char *db_name,
+ const char *old_db_name,
+ const char *new_db_name,
LEX_STRING *old_table_name,
LEX_STRING *new_table_name)
{
@@ -1757,11 +1771,11 @@ Table_triggers_list::change_table_name_in_triggers(THD *thd,
if (thd->is_fatal_error)
return TRUE; /* OOM */
- if (save_trigger_file(this, db_name, new_table_name->str))
+ if (save_trigger_file(this, new_db_name, new_table_name->str))
return TRUE;
- if (rm_trigger_file(path_buff, db_name, old_table_name->str))
+ if (rm_trigger_file(path_buff, old_db_name, old_table_name->str))
{
- (void) rm_trigger_file(path_buff, db_name, new_table_name->str);
+ (void) rm_trigger_file(path_buff, new_db_name, new_table_name->str);
return TRUE;
}
return FALSE;
@@ -1772,7 +1786,8 @@ Table_triggers_list::change_table_name_in_triggers(THD *thd,
Iterate though Table_triggers_list::names_list list and update
.TRN files after renaming triggers' subject table.
- @param db_name Database of subject table
+ @param old_db_name Old database of subject table
+ @param new_db_name New database of subject table
@param new_table_name New subject table's name
@param stopper Pointer to Table_triggers_list::names_list at
which we should stop updating.
@@ -1785,7 +1800,8 @@ Table_triggers_list::change_table_name_in_triggers(THD *thd,
*/
LEX_STRING*
-Table_triggers_list::change_table_name_in_trignames(const char *db_name,
+Table_triggers_list::change_table_name_in_trignames(const char *old_db_name,
+ const char *new_db_name,
LEX_STRING *new_table_name,
LEX_STRING *stopper)
{
@@ -1798,7 +1814,7 @@ Table_triggers_list::change_table_name_in_trignames(const char *db_name,
while ((trigger= it_name++) != stopper)
{
trigname_file.length= build_table_filename(trigname_buff, FN_REFLEN-1,
- db_name, trigger->str,
+ new_db_name, trigger->str,
TRN_EXT, 0);
trigname_file.str= trigname_buff;
@@ -1807,6 +1823,16 @@ Table_triggers_list::change_table_name_in_trignames(const char *db_name,
if (sql_create_definition_file(NULL, &trigname_file, &trigname_file_type,
(uchar*)&trigname, trigname_file_parameters))
return trigger;
+
+ /* Remove stale .TRN file in case of database upgrade */
+ if (old_db_name)
+ {
+ if (rm_trigname_file(trigname_buff, old_db_name, trigger->str))
+ {
+ (void) rm_trigname_file(trigname_buff, new_db_name, trigger->str);
+ return trigger;
+ }
+ }
}
return 0;
@@ -1840,6 +1866,7 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db,
{
TABLE table;
bool result= 0;
+ bool upgrading50to51= FALSE;
LEX_STRING *err_trigname;
DBUG_ENTER("change_table_name");
@@ -1877,14 +1904,27 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db,
moving table with them between two schemas raises too many questions.
(E.g. what should happen if in new schema we already have trigger
with same name ?).
+
+ In case of "ALTER DATABASE `#mysql50#db1` UPGRADE DATA DIRECTORY NAME"
+ we will be given table name with "#mysql50#" prefix
+ To remove this prefix we use check_n_cut_mysql50_prefix().
*/
if (my_strcasecmp(table_alias_charset, db, new_db))
{
- my_error(ER_TRG_IN_WRONG_SCHEMA, MYF(0));
- result= 1;
- goto end;
+ char dbname[NAME_LEN + 1];
+ if (check_n_cut_mysql50_prefix(db, dbname, sizeof(dbname)) &&
+ !my_strcasecmp(table_alias_charset, dbname, new_db))
+ {
+ upgrading50to51= TRUE;
+ }
+ else
+ {
+ my_error(ER_TRG_IN_WRONG_SCHEMA, MYF(0));
+ result= 1;
+ goto end;
+ }
}
- if (table.triggers->change_table_name_in_triggers(thd, db,
+ if (table.triggers->change_table_name_in_triggers(thd, db, new_db,
&old_table_name,
&new_table_name))
{
@@ -1892,7 +1932,8 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db,
goto end;
}
if ((err_trigname= table.triggers->change_table_name_in_trignames(
- db, &new_table_name, 0)))
+ upgrading50to51 ? db : NULL,
+ new_db, &new_table_name, 0)))
{
/*
If we were unable to update one of .TRN files properly we will
@@ -1900,16 +1941,17 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db,
We assume that we will be able to undo our changes without errors
(we can't do much if there will be an error anyway).
*/
- (void) table.triggers->change_table_name_in_trignames(db,
- &old_table_name,
- err_trigname);
- (void) table.triggers->change_table_name_in_triggers(thd, db,
- &new_table_name,
- &old_table_name);
+ (void) table.triggers->change_table_name_in_trignames(
+ upgrading50to51 ? new_db : NULL, db,
+ &old_table_name, err_trigname);
+ (void) table.triggers->change_table_name_in_triggers(
+ thd, db, new_db,
+ &new_table_name, &old_table_name);
result= 1;
goto end;
}
}
+
end:
delete table.triggers;
free_root(&table.mem_root, MYF(0));
diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h
index 1b0edf6bea8..f6754a75284 100644
--- a/sql/sql_trigger.h
+++ b/sql/sql_trigger.h
@@ -146,11 +146,13 @@ public:
private:
bool prepare_record1_accessors(TABLE *table);
- LEX_STRING* change_table_name_in_trignames(const char *db_name,
+ LEX_STRING* change_table_name_in_trignames(const char *old_db_name,
+ const char *new_db_name,
LEX_STRING *new_table_name,
LEX_STRING *stopper);
bool change_table_name_in_triggers(THD *thd,
- const char *db_name,
+ const char *old_db_name,
+ const char *new_db_name,
LEX_STRING *old_table_name,
LEX_STRING *new_table_name);
};
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 050deeaf0ae..68a614c710e 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2003 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 91d486fc38c..2de3a5d67a9 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2006 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 00099fa6a79..4bbee0ba696 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2003 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/table.cc b/sql/table.cc
index 6355d46f4d5..c4c12208719 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2006 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -400,6 +400,8 @@ void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key,
void free_table_share(TABLE_SHARE *share)
{
MEM_ROOT mem_root;
+ uint idx;
+ KEY *key_info;
DBUG_ENTER("free_table_share");
DBUG_PRINT("enter", ("table: %s.%s", share->db.str, share->table_name.str));
DBUG_ASSERT(share->ref_count == 0);
@@ -426,6 +428,16 @@ void free_table_share(TABLE_SHARE *share)
plugin_unlock(NULL, share->db_plugin);
share->db_plugin= NULL;
+ /* Release fulltext parsers */
+ key_info= share->key_info;
+ for (idx= share->keys; idx; idx--, key_info++)
+ {
+ if (key_info->flags & HA_USES_PARSER)
+ {
+ plugin_unlock(NULL, key_info->parser);
+ key_info->flags= 0;
+ }
+ }
/* We must copy mem_root from share because share is allocated through it */
memcpy((char*) &mem_root, (char*) &share->mem_root, sizeof(mem_root));
free_root(&mem_root, MYF(0)); // Free's share
@@ -1416,7 +1428,9 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
*/
if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
{
- field->part_of_key= share->keys_in_use;
+ if (field->key_length() == key_part->length &&
+ !(field->flags & BLOB_FLAG))
+ field->part_of_key= share->keys_in_use;
if (field->part_of_sortkey.is_set(key))
field->part_of_sortkey= share->keys_in_use;
}
@@ -1941,22 +1955,11 @@ partititon_err:
int closefrm(register TABLE *table, bool free_share)
{
int error=0;
- uint idx;
- KEY *key_info;
DBUG_ENTER("closefrm");
DBUG_PRINT("enter", ("table: 0x%lx", (long) table));
if (table->db_stat)
error=table->file->close();
- key_info= table->key_info;
- for (idx= table->s->keys; idx; idx--, key_info++)
- {
- if (key_info->flags & HA_USES_PARSER)
- {
- plugin_unlock(NULL, key_info->parser);
- key_info->flags= 0;
- }
- }
my_free((char*) table->alias, MYF(MY_ALLOW_ZERO_PTR));
table->alias= 0;
if (table->field)
diff --git a/sql/table.h b/sql/table.h
index 1cdc1381eb5..97840d2a1c6 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2006 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1691,5 +1691,35 @@ static inline void dbug_tmp_restore_column_map(MY_BITMAP *bitmap,
#endif
}
+
+/*
+ Variant of the above : handle both read and write sets.
+ Provide for the possiblity of the read set being the same as the write set
+*/
+static inline void dbug_tmp_use_all_columns(TABLE *table,
+ my_bitmap_map **save,
+ MY_BITMAP *read_set,
+ MY_BITMAP *write_set)
+{
+#ifndef DBUG_OFF
+ save[0]= read_set->bitmap;
+ save[1]= write_set->bitmap;
+ (void) tmp_use_all_columns(table, read_set);
+ (void) tmp_use_all_columns(table, write_set);
+#endif
+}
+
+
+static inline void dbug_tmp_restore_column_maps(MY_BITMAP *read_set,
+ MY_BITMAP *write_set,
+ my_bitmap_map **old)
+{
+#ifndef DBUG_OFF
+ tmp_restore_column_map(read_set, old[0]);
+ tmp_restore_column_map(write_set, old[1]);
+#endif
+}
+
+
size_t max_row_length(TABLE *table, const uchar *data);
diff --git a/sql/unireg.cc b/sql/unireg.cc
index 10446c036ec..cbe09889b39 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -204,6 +204,24 @@ bool mysql_create_frm(THD *thd, const char *file_name,
(create_info->min_rows == 1) && (keys == 0));
int2store(fileinfo+28,key_info_length);
+ /*
+ This gives us the byte-position of the character at
+ (character-position, not byte-position) TABLE_COMMENT_MAXLEN.
+ The trick here is that character-positions start at 0, so the last
+ character in a maximum-allowed length string would be at char-pos
+ MAXLEN-1; charpos MAXLEN will be the position of the terminator.
+ Consequently, bytepos(charpos(MAXLEN)) should be equal to
+ comment[length] (which should also be the terminator, or at least
+ the first byte after the payload in the strict sense). If this is
+ not so (bytepos(charpos(MAXLEN)) comes /before/ the end of the
+ string), the string is too long.
+
+ For additional credit, realise that UTF-8 has 1-3 bytes before 6.0,
+ and 1-4 bytes in 6.0 (6.0 also has UTF-32). This means that the
+ inlined COMMENT supposedly does not exceed 60 character plus
+ terminator, vulgo, 181 bytes.
+ */
+
tmp_len= system_charset_info->cset->charpos(system_charset_info,
create_info->comment.str,
create_info->comment.str +
@@ -226,14 +244,6 @@ bool mysql_create_frm(THD *thd, const char *file_name,
strmake((char*) forminfo+47, create_info->comment.str ?
create_info->comment.str : "", create_info->comment.length);
forminfo[46]=(uchar) create_info->comment.length;
-#ifdef EXTRA_DEBUG
- /*
- EXTRA_DEBUG causes strmake() to initialize its buffer behind the
- payload with a magic value to detect wrong buffer-sizes. We
- explicitly zero that segment again.
- */
- memset((char*) forminfo+47 + forminfo[46], 0, 61 - forminfo[46]);
-#endif
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (part_info)
{