summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc42
-rw-r--r--sql/field.h17
-rw-r--r--sql/ha_berkeley.cc14
-rw-r--r--sql/ha_innobase.cc259
-rw-r--r--sql/ha_innobase.h10
-rw-r--r--sql/ha_myisammrg.cc4
-rw-r--r--sql/handler.cc9
-rw-r--r--sql/item.h1
-rw-r--r--sql/item_timefunc.cc4
-rw-r--r--sql/log.cc58
-rw-r--r--sql/mysqld.cc52
-rw-r--r--sql/nt_servc.cc380
-rw-r--r--sql/nt_servc.h3
-rwxr-xr-xsql/share/norwegian-ny/.cvsignore1
-rwxr-xr-xsql/share/norwegian/.cvsignore1
-rw-r--r--sql/sql_lex.cc27
-rw-r--r--sql/sql_select.cc51
-rw-r--r--sql/time.cc6
18 files changed, 634 insertions, 305 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 07f521abf3e..df6c2a80424 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -2412,8 +2412,7 @@ String *Field_timestamp::val_str(String *val_buffer,
return val_buffer;
}
-bool Field_timestamp::get_date(TIME *ltime,
- bool fuzzydate __attribute__((unused)))
+bool Field_timestamp::get_date(TIME *ltime, bool fuzzydate)
{
long temp;
#ifdef WORDS_BIGENDIAN
@@ -2424,6 +2423,8 @@ bool Field_timestamp::get_date(TIME *ltime,
longget(temp,ptr);
if (temp == 0L)
{ /* Zero time is "000000" */
+ if (!fuzzydate)
+ return 1;
bzero((char*) ltime,sizeof(*ltime));
}
else
@@ -2447,8 +2448,7 @@ bool Field_timestamp::get_date(TIME *ltime,
bool Field_timestamp::get_time(TIME *ltime)
{
- Field_timestamp::get_date(ltime,0);
- return 0;
+ return Field_timestamp::get_date(ltime,0);
}
int Field_timestamp::cmp(const char *a_ptr, const char *b_ptr)
@@ -3029,13 +3029,12 @@ bool Field_newdate::get_date(TIME *ltime,bool fuzzydate)
ltime->month= (tmp >> 5) & 15;
ltime->year= (tmp >> 9);
ltime->time_type=TIMESTAMP_DATE;
- return (!fuzzydate && (!ltime->month || !ltime->day) && ltime->year) ? 1 : 0;
+ return (!fuzzydate && (!ltime->month || !ltime->day)) ? 1 : 0;
}
bool Field_newdate::get_time(TIME *ltime)
{
- Field_newdate::get_date(ltime,0);
- return 0;
+ return Field_newdate::get_date(ltime,0);
}
int Field_newdate::cmp(const char *a_ptr, const char *b_ptr)
@@ -3214,13 +3213,12 @@ bool Field_datetime::get_date(TIME *ltime,bool fuzzydate)
ltime->day= part1%100;
ltime->month= part1/100%100;
ltime->year= part1/10000;
- return (!fuzzydate && (!ltime->month || !ltime->day) && ltime->year) ? 1 : 0;
+ return (!fuzzydate && (!ltime->month || !ltime->day)) ? 1 : 0;
}
bool Field_datetime::get_time(TIME *ltime)
{
- Field_datetime::get_date(ltime,0);
- return 0;
+ return Field_datetime::get_date(ltime,0);
}
int Field_datetime::cmp(const char *a_ptr, const char *b_ptr)
@@ -3468,9 +3466,9 @@ int Field_string::pack_cmp(const char *b, uint length)
}
-uint Field_string::packed_col_length(const char *ptr)
+uint Field_string::packed_col_length(const char *ptr, uint length)
{
- if (field_length > 255)
+ if (length > 255)
return uint2korr(ptr)+2;
else
return (uint) ((uchar) *ptr)+1;
@@ -3478,7 +3476,7 @@ uint Field_string::packed_col_length(const char *ptr)
uint Field_string::max_packed_col_length(uint max_length)
{
- return (field_length > 255 ? 2 : 1)+max_length;
+ return (max_length > 255 ? 2 : 1)+max_length;
}
@@ -3687,9 +3685,9 @@ int Field_varstring::pack_cmp(const char *b, uint key_length)
return my_sortncmp(a,a_length, b,b_length);
}
-uint Field_varstring::packed_col_length(const char *ptr)
+uint Field_varstring::packed_col_length(const char *ptr, uint length)
{
- if (field_length > 255)
+ if (length > 255)
return uint2korr(ptr)+2;
else
return (uint) ((uchar) *ptr)+1;
@@ -3697,7 +3695,7 @@ uint Field_varstring::packed_col_length(const char *ptr)
uint Field_varstring::max_packed_col_length(uint max_length)
{
- return (field_length > 255 ? 2 : 1)+max_length;
+ return (max_length > 255 ? 2 : 1)+max_length;
}
/****************************************************************************
@@ -4173,6 +4171,18 @@ char *Field_blob::pack_key_from_key_image(char *to, const char *from,
return to+length;
}
+uint Field_blob::packed_col_length(const char *ptr, uint length)
+{
+ if (length > 255)
+ return uint2korr(ptr)+2;
+ else
+ return (uint) ((uchar) *ptr)+1;
+}
+
+uint Field_blob::max_packed_col_length(uint max_length)
+{
+ return (max_length > 255 ? 2 : 1)+max_length;
+}
/****************************************************************************
** enum type.
diff --git a/sql/field.h b/sql/field.h
index ddcc281d0c8..777e4388850 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -176,10 +176,10 @@ public:
{
return pack(to,from,max_length);
}
- virtual uint packed_col_length(const char *to)
- { return pack_length();}
+ virtual uint packed_col_length(const char *to, uint length)
+ { return length;}
virtual uint max_packed_col_length(uint max_length)
- { return pack_length();}
+ { return max_length;}
virtual int pack_cmp(const char *a,const char *b, uint key_length_arg)
{ return cmp(a,b); }
@@ -749,7 +749,7 @@ public:
const char *unpack(char* to, const char *from);
int pack_cmp(const char *a,const char *b,uint key_length);
int pack_cmp(const char *b,uint key_length);
- uint packed_col_length(const char *to);
+ uint packed_col_length(const char *to, uint length);
uint max_packed_col_length(uint max_length);
uint size_of() const { return sizeof(*this); }
enum_field_types real_type() const { return FIELD_TYPE_STRING; }
@@ -801,7 +801,7 @@ public:
const char *unpack(char* to, const char *from);
int pack_cmp(const char *a, const char *b, uint key_length);
int pack_cmp(const char *b, uint key_length);
- uint packed_col_length(const char *to);
+ uint packed_col_length(const char *to, uint length);
uint max_packed_col_length(uint max_length);
uint size_of() const { return sizeof(*this); }
enum_field_types real_type() const { return FIELD_TYPE_VAR_STRING; }
@@ -887,11 +887,8 @@ public:
char *pack_key_from_key_image(char* to, const char *from, uint max_length);
int pack_cmp(const char *a, const char *b, uint key_length);
int pack_cmp(const char *b, uint key_length);
- uint packed_col_length(const char *col_ptr)
- { return get_length(col_ptr)+packlength;}
- virtual uint max_packed_col_length(uint max_length)
- { return packlength+max_length; }
-
+ uint packed_col_length(const char *col_ptr, uint length);
+ uint max_packed_col_length(uint max_length);
inline void free() { value.free(); }
inline void clear_temporary() { bzero((char*) &value,sizeof(value)); }
friend void field_conv(Field *to,Field *from);
diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc
index b10939227ff..f52b99f5a12 100644
--- a/sql/ha_berkeley.cc
+++ b/sql/ha_berkeley.cc
@@ -28,8 +28,8 @@
- Get a more accurate count of the number of rows (estimate_number_of_rows()).
We could store the found number of rows when the table is scanned and
then increment the counter for each attempted write.
- - We will need a manager thread that calls flush_logs, removes old
- logs and makes checkpoints at given intervals.
+ - We will need to extend the manager thread to makes checkpoints at
+ given intervals.
- When not using UPDATE IGNORE, don't make a sub transaction but abort
the main transaction on errors.
- Handling of drop table during autocommit=0 ?
@@ -372,10 +372,12 @@ berkeley_cmp_packed_key(DB *file, const DBT *new_key, const DBT *saved_key)
if ((cmp=key_part->field->pack_cmp(new_key_ptr,saved_key_ptr,
key_part->length)))
return cmp;
- uint length=key_part->field->packed_col_length(new_key_ptr);
+ uint length=key_part->field->packed_col_length(new_key_ptr,
+ key_part->length);
new_key_ptr+=length;
key_length-=length;
- saved_key_ptr+=key_part->field->packed_col_length(saved_key_ptr);
+ saved_key_ptr+=key_part->field->packed_col_length(saved_key_ptr,
+ key_part->length);
}
return key->handler.bdb_return_if_eq;
}
@@ -433,7 +435,7 @@ berkeley_key_cmp(TABLE *table, KEY *key_info, const char *key, uint key_length)
}
if ((cmp=key_part->field->pack_cmp(key,key_part->length)))
return cmp;
- uint length=key_part->field->packed_col_length(key);
+ uint length=key_part->field->packed_col_length(key,key_part->length);
key+=length;
key_length-=length;
}
@@ -1552,7 +1554,7 @@ DBT *ha_berkeley::get_pos(DBT *to, byte *pos)
KEY_PART_INFO *end=key_part+table->key_info[primary_key].key_parts;
for ( ; key_part != end ; key_part++)
- pos+=key_part->field->packed_col_length((char*) pos);
+ pos+=key_part->field->packed_col_length((char*) pos,key_part->length);
to->size= (uint) (pos- (byte*) to->data);
}
return to;
diff --git a/sql/ha_innobase.cc b/sql/ha_innobase.cc
index 7e11fbe46d1..dd72bb15473 100644
--- a/sql/ha_innobase.cc
+++ b/sql/ha_innobase.cc
@@ -79,13 +79,14 @@ ulong innobase_cache_size = 0;
long innobase_mirrored_log_groups, innobase_log_files_in_group,
innobase_log_file_size, innobase_log_buffer_size,
innobase_buffer_pool_size, innobase_additional_mem_pool_size,
- innobase_file_io_threads, innobase_lock_wait_timeout;
+ innobase_file_io_threads, innobase_lock_wait_timeout,
+ innobase_thread_concurrency, innobase_force_recovery;
char *innobase_data_home_dir;
char *innobase_log_group_home_dir, *innobase_log_arch_dir;
char *innobase_unix_file_flush_method;
bool innobase_flush_log_at_trx_commit, innobase_log_archive,
- innobase_use_native_aio;
+ innobase_use_native_aio, innobase_fast_shutdown;
/*
Set default InnoDB size to 64M, to let users use InnoDB without having
@@ -165,19 +166,19 @@ convert_error_code_to_mysql(
} else if (error == (int) DB_LOCK_WAIT_TIMEOUT) {
- return(1000001);
+ return(HA_ERR_LOCK_WAIT_TIMEOUT);
} else if (error == (int) DB_NO_REFERENCED_ROW) {
- return(1000010);
+ return(HA_ERR_NO_REFERENCED_ROW);
} else if (error == (int) DB_ROW_IS_REFERENCED) {
- return(1000011);
+ return(HA_ERR_ROW_IS_REFERENCED);
} else if (error == (int) DB_CANNOT_ADD_CONSTRAINT) {
- return(1000012);
+ return(HA_ERR_CANNOT_ADD_FOREIGN);
} else if (error == (int) DB_OUT_OF_FILE_SPACE) {
@@ -354,12 +355,6 @@ innobase_parse_data_file_paths_and_sizes(void)
str++;
}
- if (size >= 4096) {
- fprintf(stderr,
- "InnoDB: error: data file size must not be >= 4096M\n");
- return(FALSE);
- }
-
if (strlen(str) >= 6
&& *str == 'n'
&& *(str + 1) == 'e'
@@ -566,8 +561,10 @@ innobase_init(void)
srv_query_thread_priority = QUERY_PRIOR;
}
- /* Set InnoDB initialization parameters according to the values
- read from MySQL .cnf file */
+ /*
+ Set InnoDB initialization parameters according to the values
+ read from MySQL .cnf file
+ */
// Make a copy of innobase_data_file_path to not modify the original
internal_innobase_data_file_path=my_strdup(innobase_data_file_path,
@@ -604,7 +601,7 @@ innobase_init(void)
srv_log_archive_on = (ulint) innobase_log_archive;
srv_log_buffer_size = (ulint) innobase_log_buffer_size;
- srv_flush_log_at_trx_commit = (ulint) innobase_flush_log_at_trx_commit;
+ srv_flush_log_at_trx_commit = (ibool) innobase_flush_log_at_trx_commit;
srv_use_native_aio = 0;
@@ -614,6 +611,10 @@ innobase_init(void)
srv_n_file_io_threads = (ulint) innobase_file_io_threads;
srv_lock_wait_timeout = (ulint) innobase_lock_wait_timeout;
+ srv_thread_concurrency = (ulint) innobase_thread_concurrency;
+ srv_force_recovery = (ulint) innobase_force_recovery;
+
+ srv_fast_shutdown = (ibool) innobase_fast_shutdown;
srv_print_verbose_log = mysql_embedded ? 0 : 1;
if (strcmp(default_charset_info->name, "latin1") == 0) {
@@ -713,12 +714,15 @@ innobase_commit(
trx = check_trx_exists(thd);
if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle) {
+ srv_conc_enter_innodb(trx);
+
trx_commit_for_mysql(trx);
- trx_mark_sql_stat_end_do_not_start_new(trx);
- } else {
- trx_mark_sql_stat_end(trx);
+
+ srv_conc_exit_innodb();
}
+ trx_mark_sql_stat_end(trx);
+
#ifndef DBUG_OFF
if (error) {
DBUG_PRINT("error", ("error: %d", error));
@@ -751,14 +755,18 @@ innobase_rollback(
trx = check_trx_exists(thd);
+ srv_conc_enter_innodb(trx);
+
if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle) {
error = trx_rollback_for_mysql(trx);
- trx_mark_sql_stat_end_do_not_start_new(trx);
} else {
error = trx_rollback_last_sql_stat_for_mysql(trx);
- trx_mark_sql_stat_end(trx);
}
+ srv_conc_exit_innodb();
+
+ trx_mark_sql_stat_end(trx);
+
DBUG_RETURN(convert_error_code_to_mysql(error));
}
@@ -908,10 +916,11 @@ ha_innobase::open(
if (NULL == (ib_table = dict_table_get(norm_name, NULL))) {
fprintf(stderr,
-"InnoDB: Cannot find table %s from the internal data dictionary\n"
+"InnoDB: Error: cannot find table %s from the internal data dictionary\n"
"InnoDB: of InnoDB though the .frm file for the table exists. Maybe you\n"
"InnoDB: have deleted and recreated InnoDB data files but have forgotten\n"
-"InnoDB: to delete the corresponding .frm files of InnoDB tables?\n",
+"InnoDB: to delete the corresponding .frm files of InnoDB tables, or you\n"
+"InnoDB: have moved .frm files to another database?\n",
norm_name);
free_share(share);
@@ -956,7 +965,9 @@ ha_innobase::open(
dbug_assert(key_used_on_scan == MAX_KEY);
}
- /* Init table lock structure */
+ auto_inc_counter_for_this_stat = 0;
+
+ /* Init table lock structure */
thr_lock_data_init(&share->lock,&lock,(void*) 0);
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
@@ -1253,14 +1264,20 @@ build_template(
Field* field;
ulint n_fields;
ulint n_requested_fields = 0;
+ ibool fetch_all_in_key = FALSE;
ulint i;
clust_index = dict_table_get_first_index_noninline(prebuilt->table);
if (!prebuilt->in_update_remember_pos) {
- /* We are building a temporary table: fetch all columns */
-
- templ_type = ROW_MYSQL_WHOLE_ROW;
+ if (prebuilt->read_just_key) {
+ fetch_all_in_key = TRUE;
+ } else {
+ /* We are building a temporary table: fetch all
+ columns */
+
+ templ_type = ROW_MYSQL_WHOLE_ROW;
+ }
}
if (prebuilt->select_lock_type == LOCK_X) {
@@ -1270,7 +1287,6 @@ build_template(
templ_type = ROW_MYSQL_WHOLE_ROW;
}
-
if (templ_type == ROW_MYSQL_REC_FIELDS) {
if (prebuilt->select_lock_type != LOCK_NONE) {
@@ -1310,6 +1326,9 @@ build_template(
field = table->field[i];
if (templ_type == ROW_MYSQL_REC_FIELDS
+ && !(fetch_all_in_key &&
+ ULINT_UNDEFINED != dict_index_get_nth_col_pos(
+ index, i))
&& thd->query_id != field->query_id
&& thd->query_id != (field->query_id ^ MAX_ULONG_BIT)
&& thd->query_id !=
@@ -1408,9 +1427,6 @@ ha_innobase::write_row(
}
if (table->next_number_field && record == table->record[0]) {
- /* Set the 'in_update_remember_pos' flag to FALSE to
- make sure all columns are fetched in the select done by
- update_auto_increment */
/* Fetch the value the user possibly has set in the
autoincrement field */
@@ -1420,12 +1436,29 @@ ha_innobase::write_row(
/* In replication and also otherwise the auto-inc column
can be set with SET INSERT_ID. Then we must look at
user_thd->next_insert_id. If it is nonzero and the user
- has not supplied a value, we must use it. */
+ has not supplied a value, we must use it, and use values
+ incremented by 1 in all subsequent inserts within the
+ same SQL statement! */
if (auto_inc == 0 && user_thd->next_insert_id != 0) {
auto_inc = user_thd->next_insert_id;
+ auto_inc_counter_for_this_stat = auto_inc;
}
+ if (auto_inc == 0 && auto_inc_counter_for_this_stat) {
+ /* The user set the auto-inc counter for
+ this SQL statement with SET INSERT_ID. We must
+ assign sequential values from the counter. */
+
+ auto_inc_counter_for_this_stat++;
+
+ auto_inc = auto_inc_counter_for_this_stat;
+
+ /* We give MySQL a new value to place in the
+ auto-inc column */
+ user_thd->next_insert_id = auto_inc;
+ }
+
if (auto_inc != 0) {
/* This call will calculate the max of the
current value and the value supplied by the user, if
@@ -1449,11 +1482,14 @@ ha_innobase::write_row(
dict_table_autoinc_update(prebuilt->table, auto_inc);
} else {
+ srv_conc_enter_innodb(prebuilt->trx);
+
if (!prebuilt->trx->auto_inc_lock) {
error = row_lock_table_autoinc_for_mysql(
prebuilt);
if (error != DB_SUCCESS) {
+ srv_conc_exit_innodb();
error = convert_error_code_to_mysql(
error);
@@ -1462,6 +1498,7 @@ ha_innobase::write_row(
}
auto_inc = dict_table_autoinc_get(prebuilt->table);
+ srv_conc_exit_innodb();
/* If auto_inc is now != 0 the autoinc counter
was already initialized for the table: we can give
@@ -1472,6 +1509,10 @@ ha_innobase::write_row(
}
}
+ /* Set the 'in_update_remember_pos' flag to FALSE to
+ make sure all columns are fetched in the select done by
+ update_auto_increment */
+
prebuilt->in_update_remember_pos = FALSE;
update_auto_increment();
@@ -1482,6 +1523,14 @@ ha_innobase::write_row(
auto_inc = table->next_number_field->val_int();
+ error = row_lock_table_autoinc_for_mysql(prebuilt);
+
+ if (error != DB_SUCCESS) {
+
+ error = convert_error_code_to_mysql(error);
+ goto func_exit;
+ }
+
dict_table_autoinc_initialize(prebuilt->table,
auto_inc);
}
@@ -1510,8 +1559,12 @@ ha_innobase::write_row(
prebuilt->trx->ignore_duplicates_in_insert = FALSE;
}
+ srv_conc_enter_innodb(prebuilt->trx);
+
error = row_insert_for_mysql((byte*) record, prebuilt);
+ srv_conc_exit_innodb();
+
prebuilt->trx->ignore_duplicates_in_insert = FALSE;
error = convert_error_code_to_mysql(error);
@@ -1725,8 +1778,12 @@ ha_innobase::update_row(
assert(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW);
}
+ srv_conc_enter_innodb(prebuilt->trx);
+
error = row_update_for_mysql((byte*) old_row, prebuilt);
+ srv_conc_exit_innodb();
+
error = convert_error_code_to_mysql(error);
/* Tell InnoDB server that there might be work for
@@ -1765,8 +1822,12 @@ ha_innobase::delete_row(
prebuilt->upd_node->is_delete = TRUE;
prebuilt->in_update_remember_pos = TRUE;
+ srv_conc_enter_innodb(prebuilt->trx);
+
error = row_update_for_mysql((byte*) record, prebuilt);
+ srv_conc_exit_innodb();
+
error = convert_error_code_to_mysql(error);
/* Tell the InnoDB server that there might be work for
@@ -1789,7 +1850,7 @@ ha_innobase::index_init(
int error = 0;
DBUG_ENTER("index_init");
- change_active_index(keynr);
+ error = change_active_index(keynr);
DBUG_RETURN(error);
}
@@ -1905,8 +1966,12 @@ ha_innobase::index_read(
last_match_mode = match_mode;
+ srv_conc_enter_innodb(prebuilt->trx);
+
ret = row_search_for_mysql((byte*) buf, mode, prebuilt, match_mode, 0);
+ srv_conc_exit_innodb();
+
if (ret == DB_SUCCESS) {
error = 0;
table->status = 0;
@@ -1956,11 +2021,20 @@ ha_innobase::change_active_index(
prebuilt->table);
}
+ if (!prebuilt->index) {
+ fprintf(stderr,
+ "InnoDB: Could not find key n:o %u with name %s from dict cache\n"
+ "InnoDB: for table %s\n", keynr, key->name, prebuilt->table->name);
+
+ return(1);
+ }
+
+ assert(prebuilt->search_tuple);
+
dtuple_set_n_fields(prebuilt->search_tuple, prebuilt->index->n_fields);
dict_index_copy_types(prebuilt->search_tuple, prebuilt->index,
prebuilt->index->n_fields);
- assert(prebuilt->index);
/* Maybe MySQL changes the active index for a handle also
during some queries, we do not know: then it is safest to build
@@ -1989,7 +2063,10 @@ ha_innobase::index_read_idx(
uint key_len, /* in: key value length */
enum ha_rkey_function find_flag)/* in: search flags from my_base.h */
{
- change_active_index(keynr);
+ if (change_active_index(keynr)) {
+
+ return(1);
+ }
return(index_read(buf, key, key_len, find_flag));
}
@@ -2015,8 +2092,11 @@ ha_innobase::general_fetch(
DBUG_ENTER("general_fetch");
- ret = row_search_for_mysql((byte*)buf, 0, prebuilt,
- match_mode, direction);
+ srv_conc_enter_innodb(prebuilt->trx);
+
+ ret = row_search_for_mysql((byte*)buf, 0, prebuilt, match_mode,
+ direction);
+ srv_conc_exit_innodb();
if (ret == DB_SUCCESS) {
error = 0;
@@ -2148,17 +2228,19 @@ ha_innobase::rnd_init(
/* out: 0 or error number */
bool scan) /* in: ???????? */
{
+ int err;
+
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
if (prebuilt->clust_index_was_generated) {
- change_active_index(MAX_KEY);
+ err = change_active_index(MAX_KEY);
} else {
- change_active_index(primary_key);
+ err = change_active_index(primary_key);
}
start_of_scan = 1;
- return(0);
+ return(err);
}
/*********************************************************************
@@ -2226,11 +2308,15 @@ ha_innobase::rnd_pos(
row reference is the row id, not any key value
that MySQL knows */
- change_active_index(MAX_KEY);
+ error = change_active_index(MAX_KEY);
} else {
- change_active_index(primary_key);
+ error = change_active_index(primary_key);
}
+ if (error) {
+ DBUG_RETURN(error);
+ }
+
error = index_read(buf, pos, ref_stored_len, HA_READ_KEY_EXACT);
change_active_index(keynr);
@@ -2285,11 +2371,21 @@ ha_innobase::extra(
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
switch (operation) {
+ case HA_EXTRA_RESET:
+ case HA_EXTRA_RESET_STATE:
+ prebuilt->read_just_key = 0;
+ break;
+ case HA_EXTRA_NO_KEYREAD:
+ prebuilt->read_just_key = 0;
+ break;
case HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE:
- prebuilt->in_update_remember_pos = FALSE;
- break;
- default: /* Do nothing */
- ;
+ prebuilt->in_update_remember_pos = FALSE;
+ break;
+ case HA_EXTRA_KEYREAD:
+ prebuilt->read_just_key = 1;
+ break;
+ default:/* Do nothing */
+ ;
}
return(0);
@@ -2327,6 +2423,8 @@ ha_innobase::external_lock(
prebuilt->sql_stat_start = TRUE;
prebuilt->in_update_remember_pos = TRUE;
+ prebuilt->read_just_key = 0;
+
if (lock_type == F_WRLCK) {
/* If this is a SELECT, then it is in UPDATE TABLE ...
@@ -2338,6 +2436,7 @@ ha_innobase::external_lock(
if (trx->n_mysql_tables_in_use == 0) {
trx_mark_sql_stat_end(trx);
}
+
thd->transaction.all.innodb_active_trans = 1;
trx->n_mysql_tables_in_use++;
@@ -2347,6 +2446,7 @@ ha_innobase::external_lock(
}
} else {
trx->n_mysql_tables_in_use--;
+ auto_inc_counter_for_this_stat = 0;
if (trx->n_mysql_tables_in_use == 0) {
@@ -2363,11 +2463,14 @@ ha_innobase::external_lock(
some table in this SQL statement, we release
it now */
+ srv_conc_enter_innodb(trx);
row_unlock_table_autoinc_for_mysql(trx);
+ srv_conc_exit_innodb();
}
if (!(thd->options
& (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN))) {
+
innobase_commit(thd, trx);
}
}
@@ -2636,6 +2739,12 @@ ha_innobase::create(
trx_commit_for_mysql(trx);
+ /* Flush the log to reduce probability that the .frm files and
+ the InnoDB data dictionary get out-of-sync if the user runs
+ with innodb_flush_log_at_trx_commit = 0 */
+
+ log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
+
innobase_table = dict_table_get(norm_name, NULL);
assert(innobase_table);
@@ -2685,6 +2794,12 @@ ha_innobase::delete_table(
error = row_drop_table_for_mysql(norm_name, trx, FALSE);
+ /* Flush the log to reduce probability that the .frm files and
+ the InnoDB data dictionary get out-of-sync if the user runs
+ with innodb_flush_log_at_trx_commit = 0 */
+
+ log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
+
/* Tell the InnoDB server that there might be work for
utility threads: */
@@ -2732,6 +2847,12 @@ innobase_drop_database(
error = row_drop_database_for_mysql(namebuf, trx);
+ /* Flush the log to reduce probability that the .frm files and
+ the InnoDB data dictionary get out-of-sync if the user runs
+ with innodb_flush_log_at_trx_commit = 0 */
+
+ log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
+
/* Tell the InnoDB server that there might be work for
utility threads: */
@@ -2778,6 +2899,12 @@ ha_innobase::rename_table(
error = row_rename_table_for_mysql(norm_from, norm_to, trx);
+ /* Flush the log to reduce probability that the .frm files and
+ the InnoDB data dictionary get out-of-sync if the user runs
+ with innodb_flush_log_at_trx_commit = 0 */
+
+ log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
+
/* Tell the InnoDB server that there might be work for
utility threads: */
@@ -3062,31 +3189,41 @@ ha_innobase::check(
}
/*****************************************************************
-Adds information about free space in the InnoDB tablespace to a
-table comment which is printed out when a user calls SHOW TABLE STATUS. */
+Adds information about free space in the InnoDB tablespace to a table comment
+which is printed out when a user calls SHOW TABLE STATUS. Adds also info on
+foreign keys. */
char*
ha_innobase::update_table_comment(
/*==============================*/
- const char* comment)
+ /* out: table comment + InnoDB free space +
+ info on foreign keys */
+ const char* comment)/* in: table comment defined by user */
{
- uint length=strlen(comment);
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
+ uint length = strlen(comment);
+ char* str = my_malloc(length + 200, MYF(0));
+ char* pos;
- char *str=my_malloc(length + 100,MYF(0)), *pos;
+ if (!str) {
+ return((char*)comment);
+ }
- if (!str)
- return (char*)comment;
+ pos = str;
+ if (length) {
+ pos=strmov(str, comment);
+ *pos++=';';
+ *pos++=' ';
+ }
- pos=str;
- if (length)
- {
- pos=strmov(str,comment);
- *pos++=';';
- *pos++=' ';
- }
- sprintf(pos, "InnoDB free: %lu kB", (ulong) innobase_get_free_space());
+ pos += sprintf(pos, "InnoDB free: %lu kB",
+ (ulong) innobase_get_free_space());
- return(str);
+ /* We assume 150 bytes of space to print info */
+
+ dict_print_info_on_foreign_keys(pos, 150, prebuilt->table);
+
+ return(str);
}
/****************************************************************************
diff --git a/sql/ha_innobase.h b/sql/ha_innobase.h
index 404b20edbac..95bba76c842 100644
--- a/sql/ha_innobase.h
+++ b/sql/ha_innobase.h
@@ -63,7 +63,7 @@ class ha_innobase: public handler
uint last_match_mode;/* match mode of the latest search:
ROW_SEL_EXACT, ROW_SEL_EXACT_PREFIX,
or undefined */
-
+ longlong auto_inc_counter_for_this_stat;
ulong max_row_length(const byte *buf);
uint store_key_val_for_row(uint keynr, char* buff, const byte* record);
@@ -96,7 +96,10 @@ class ha_innobase: public handler
uint max_record_length() const { return HA_MAX_REC_LENGTH; }
uint max_keys() const { return MAX_KEY; }
uint max_key_parts() const { return MAX_REF_PARTS; }
- uint max_key_length() const { return MAX_KEY_LENGTH; }
+ /* An InnoDB page must store >= 2 keys:
+ max key length is therefore set to 7000
+ bytes */
+ uint max_key_length() const { return 7000; }
bool fast_key_read() { return 1;}
bool has_transactions() { return 1;}
@@ -161,11 +164,12 @@ extern long innobase_mirrored_log_groups, innobase_log_files_in_group;
extern long innobase_log_file_size, innobase_log_buffer_size;
extern long innobase_buffer_pool_size, innobase_additional_mem_pool_size;
extern long innobase_file_io_threads, innobase_lock_wait_timeout;
+extern long innobase_force_recovery, innobase_thread_concurrency;
extern char *innobase_data_home_dir, *innobase_data_file_path;
extern char *innobase_log_group_home_dir, *innobase_log_arch_dir;
extern char *innobase_unix_file_flush_method;
extern bool innobase_flush_log_at_trx_commit, innobase_log_archive,
- innobase_use_native_aio;
+ innobase_use_native_aio, innobase_fast_shutdown;
extern TYPELIB innobase_lock_typelib;
diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc
index 0a2ef534ad1..d82c202baa3 100644
--- a/sql/ha_myisammrg.cc
+++ b/sql/ha_myisammrg.cc
@@ -181,7 +181,11 @@ void ha_myisammrg::info(uint flag)
mean_rec_length=info.reclength;
block_size=0;
update_time=0;
+#if SIZEOF_OFF_T > 4
ref_length=6; // Should be big enough
+#else
+ ref_length=4; // Can't be > than my_off_t
+#endif
}
diff --git a/sql/handler.cc b/sql/handler.cc
index 742bcd3aa0a..9bf9b25f76f 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -642,6 +642,15 @@ void handler::print_error(int error, myf errflag)
case HA_ERR_READ_ONLY_TRANSACTION:
textno=ER_READ_ONLY_TRANSACTION;
break;
+ case HA_ERR_CANNOT_ADD_FOREIGN:
+ textno=ER_CANNOT_ADD_FOREIGN;
+ break;
+ case HA_ERR_ROW_IS_REFERENCED:
+ textno=ER_ROW_IS_REFERENCED;
+ break;
+ case HA_ERR_NO_REFERENCED_ROW:
+ textno=ER_NO_REFERENCED_ROW;
+ break;
default:
{
my_error(ER_GET_ERRNO,errflag,error);
diff --git a/sql/item.h b/sql/item.h
index df2b1aa243d..1bcbc4c7f0f 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -309,6 +309,7 @@ public:
Item_result_field() :result_field(0) {}
~Item_result_field() {} /* Required with gcc 2.95 */
Field *tmp_table_field() { return result_field; }
+ table_map used_tables() const { return 1; }
virtual void fix_length_and_dec()=0;
};
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index b305b5ccec3..a8bd219eef1 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -248,8 +248,10 @@ longlong Item_func_unix_timestamp::val_int()
longlong Item_func_time_to_sec::val_int()
{
TIME ltime;
+ longlong seconds;
(void) get_arg0_time(&ltime);
- return ltime.hour*3600L+ltime.minute*60+ltime.second;
+ seconds=ltime.hour*3600L+ltime.minute*60+ltime.second;
+ return ltime.neg ? -seconds : seconds;
}
diff --git a/sql/log.cc b/sql/log.cc
index 51bf077895a..b55d514058f 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -516,36 +516,46 @@ bool MYSQL_LOG::is_active(const char* log_file_name)
void MYSQL_LOG::new_file(bool inside_mutex)
{
- // only rotate open logs that are marked non-rotatable
- // (binlog with constant name are non-rotatable)
- if (is_open() && ! no_rotate)
+ if (is_open())
{
char new_name[FN_REFLEN], *old_name=name;
if (!inside_mutex)
VOID(pthread_mutex_lock(&LOCK_log));
- if (generate_new_name(new_name, name))
- {
- if (!inside_mutex)
- VOID(pthread_mutex_unlock(&LOCK_log));
- return; // Something went wrong
- }
- if (log_type == LOG_BIN)
+
+ if (!no_rotate)
{
/*
- We log the whole file name for log file as the user may decide
- to change base names at some point.
+ only rotate open logs that are marked non-rotatable
+ (binlog with constant name are non-rotatable)
*/
- THD* thd = current_thd;
- Rotate_log_event r(thd,new_name+dirname_length(new_name));
- r.set_log_seq(0, this);
- // this log rotation could have been initiated by a master of
- // the slave running with log-bin
- // we set the flag on rotate event to prevent inifinite log rotation
- // loop
- if(thd && slave_thd && thd == slave_thd)
- r.flags |= LOG_EVENT_FORCED_ROTATE_F;
- r.write(&log_file);
- VOID(pthread_cond_broadcast(&COND_binlog_update));
+ if (generate_new_name(new_name, name))
+ {
+ if (!inside_mutex)
+ VOID(pthread_mutex_unlock(&LOCK_log));
+ return; // Something went wrong
+ }
+ if (log_type == LOG_BIN)
+ {
+ /*
+ We log the whole file name for log file as the user may decide
+ to change base names at some point.
+ */
+ THD* thd = current_thd;
+ Rotate_log_event r(thd,new_name+dirname_length(new_name));
+ r.set_log_seq(0, this);
+
+ /*
+ This log rotation could have been initiated by a master of
+ the slave running with log-bin we set the flag on rotate
+ event to prevent inifinite log rotation loop
+ */
+ if (thd && slave_thd && thd == slave_thd)
+ r.flags |= LOG_EVENT_FORCED_ROTATE_F;
+ r.write(&log_file);
+ VOID(pthread_cond_broadcast(&COND_binlog_update));
+ }
+ else
+ strmov(new_name, old_name); // Reopen old file name
}
name=0;
close();
@@ -843,7 +853,7 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
{
/* For slow query log */
if (my_b_printf(&log_file,
- "# Time: %lu Lock_time: %lu Rows_sent: %lu Rows_examined: %lu\n",
+ "# Query_time: %lu Lock_time: %lu Rows_sent: %lu Rows_examined: %lu\n",
(ulong) (current_time - query_start),
(ulong) (thd->time_after_lock - query_start),
(ulong) thd->sent_row_count,
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 61eba065f9a..45812754cad 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -1237,7 +1237,7 @@ the thread stack. Please read http://www.mysql.com/doc/L/i/Linux.html\n\n",
Some pointers may be invalid and cause the dump to abort...\n");
safe_print_str("thd->query", thd->query, 1024);
fprintf(stderr, "thd->thread_id=%ld\n", thd->thread_id);
- fprintf(stderr, "\n
+ fprintf(stderr, "\n\
Successfully dumped variables, if you ran with --log, take a look at the\n\
details of what thread %ld did to cause the crash. In some cases of really\n\
bad corruption, the values shown above may be invalid.\n\n",
@@ -2083,14 +2083,18 @@ int main(int argc, char **argv)
{
if (argc == 2)
{
+ char path[FN_REFLEN];
+ my_path(path, argv[0], ""); // Find name in path
+ fn_format(path,argv[0],path,"",1+4+16); // Force use of full path
+
if (!strcmp(argv[1],"-install") || !strcmp(argv[1],"--install"))
{
- char path[FN_REFLEN];
- my_path(path, argv[0], ""); // Find name in path
- fn_format(path,argv[0],path,"",1+4+16); // Force use of full path
- if (!Service.Install(MYSQL_SERVICENAME,MYSQL_SERVICENAME,path))
- MessageBox(NULL,"Failed to install Service",MYSQL_SERVICENAME,
- MB_OK|MB_ICONSTOP);
+ Service.Install(1,MYSQL_SERVICENAME,MYSQL_SERVICENAME,path);
+ return 0;
+ }
+ else if (!strcmp(argv[1],"-install-manual") || !strcmp(argv[1],"--install-manual"))
+ {
+ Service.Install(0,MYSQL_SERVICENAME,MYSQL_SERVICENAME,path);
return 0;
}
else if (!strcmp(argv[1],"-remove") || !strcmp(argv[1],"--remove"))
@@ -2586,6 +2590,7 @@ enum options {
OPT_INNODB_LOG_ARCHIVE,
OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT,
OPT_INNODB_FLUSH_METHOD,
+ OPT_INNODB_FAST_SHUTDOWN,
OPT_SAFE_SHOW_DB,
OPT_INNODB_SKIP, OPT_SKIP_SAFEMALLOC,
OPT_TEMP_POOL, OPT_TX_ISOLATION,
@@ -2648,6 +2653,8 @@ static struct option long_options[] = {
OPT_INNODB_LOG_ARCHIVE},
{"innodb_flush_log_at_trx_commit", optional_argument, 0,
OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT},
+ {"innodb_fast_shutdown", optional_argument, 0,
+ OPT_INNODB_FAST_SHUTDOWN},
{"innodb_flush_method", required_argument, 0,
OPT_INNODB_FLUSH_METHOD},
#endif
@@ -2762,6 +2769,8 @@ static struct option long_options[] = {
{0, 0, 0, 0}
};
+#define LONG_TIMEOUT ((ulong) 3600L*24L*365L)
+
CHANGEABLE_VAR changeable_vars[] = {
{ "back_log", (long*) &back_log,
50, 1, 65535, 0, 1 },
@@ -2779,15 +2788,15 @@ CHANGEABLE_VAR changeable_vars[] = {
{ "binlog_cache_size", (long*) &binlog_cache_size,
32*1024L, IO_SIZE, ~0L, 0, IO_SIZE },
{ "connect_timeout", (long*) &connect_timeout,
- CONNECT_TIMEOUT, 2, 65535, 0, 1 },
+ CONNECT_TIMEOUT, 2, LONG_TIMEOUT, 0, 1 },
{ "delayed_insert_timeout", (long*) &delayed_insert_timeout,
- DELAYED_WAIT_TIMEOUT, 1, ~0L, 0, 1 },
+ DELAYED_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 },
{ "delayed_insert_limit", (long*) &delayed_insert_limit,
DELAYED_LIMIT, 1, ~0L, 0, 1 },
{ "delayed_queue_size", (long*) &delayed_queue_size,
DELAYED_QUEUE_SIZE, 1, ~0L, 0, 1 },
{ "flush_time", (long*) &flush_time,
- FLUSH_TIME, 0, ~0L, 0, 1 },
+ FLUSH_TIME, 0, LONG_TIMEOUT, 0, 1 },
{ "ft_min_word_len", (long*) &ft_min_word_len,
4, 1, HA_FT_MAXLEN, 0, 1 },
{ "ft_max_word_len", (long*) &ft_max_word_len,
@@ -2816,15 +2825,19 @@ CHANGEABLE_VAR changeable_vars[] = {
{"innodb_lock_wait_timeout",
(long*) &innobase_lock_wait_timeout, 1024 * 1024 * 1024, 1,
1024 * 1024 * 1024, 0, 1},
+ {"innodb_thread_concurrency",
+ (long*) &innobase_thread_concurrency, 8, 1, 1000, 0, 1},
+ {"innodb_force_recovery",
+ (long*) &innobase_force_recovery, 0, 0, 6, 0, 1},
#endif
{ "interactive_timeout", (long*) &net_interactive_timeout,
- NET_WAIT_TIMEOUT, 1, 31*24*60*60, 0, 1 },
+ NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 },
{ "join_buffer_size", (long*) &join_buff_size,
128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE },
{ "key_buffer_size", (long*) &keybuff_size,
KEY_CACHE_SIZE, MALLOC_OVERHEAD, (long) ~0, MALLOC_OVERHEAD, IO_SIZE },
{ "long_query_time", (long*) &long_query_time,
- 10, 1, ~0L, 0, 1 },
+ 10, 1, LONG_TIMEOUT, 0, 1 },
{ "lower_case_table_names", (long*) &lower_case_table_names,
IF_WIN(1,0), 0, 1, 0, 1 },
{ "max_allowed_packet", (long*) &max_allowed_packet,
@@ -2868,9 +2881,9 @@ CHANGEABLE_VAR changeable_vars[] = {
{ "net_retry_count", (long*) &mysqld_net_retry_count,
MYSQLD_NET_RETRY_COUNT, 1, ~0L, 0, 1 },
{ "net_read_timeout", (long*) &net_read_timeout,
- NET_READ_TIMEOUT, 1, 65535, 0, 1 },
+ NET_READ_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 },
{ "net_write_timeout", (long*) &net_write_timeout,
- NET_WRITE_TIMEOUT, 1, 65535, 0, 1 },
+ NET_WRITE_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 },
{ "open_files_limit", (long*) &open_files_limit,
0, 0, 65535, 0, 1},
{ "query_buffer_size", (long*) &query_buff_size,
@@ -2880,9 +2893,9 @@ CHANGEABLE_VAR changeable_vars[] = {
{ "record_rnd_buffer", (long*) &record_rnd_cache_size,
0, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE },
{ "slave_net_timeout", (long*) &slave_net_timeout,
- SLAVE_NET_TIMEOUT, 1, 65535, 0, 1 },
+ SLAVE_NET_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 },
{ "slow_launch_time", (long*) &slow_launch_time,
- 2L, 0L, ~0L, 0, 1 },
+ 2L, 0L, LONG_TIMEOUT, 0, 1 },
{ "sort_buffer", (long*) &sortbuff_size,
MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*2, ~0L, MALLOC_OVERHEAD, 1 },
{ "table_cache", (long*) &table_cache_size,
@@ -2896,7 +2909,7 @@ CHANGEABLE_VAR changeable_vars[] = {
{ "thread_stack", (long*) &thread_stack,
DEFAULT_THREAD_STACK, 1024*32, ~0L, 0, 1024 },
{ "wait_timeout", (long*) &net_wait_timeout,
- NET_WAIT_TIMEOUT, 1, ~0L, 0, 1 },
+ NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 },
{ NullS, (long*) 0, 0, 0, 0, 0, 0}
};
@@ -2942,7 +2955,10 @@ struct show_var_st init_vars[]= {
{"innodb_data_file_path", (char*) &innobase_data_file_path, SHOW_CHAR_PTR},
{"innodb_data_home_dir", (char*) &innobase_data_home_dir, SHOW_CHAR_PTR},
{"innodb_file_io_threads", (char*) &innobase_file_io_threads, SHOW_LONG },
+ {"innodb_force_recovery", (char*) &innobase_force_recovery, SHOW_LONG },
+ {"innodb_thread_concurrency", (char*) &innobase_thread_concurrency, SHOW_LONG },
{"innodb_flush_log_at_trx_commit", (char*) &innobase_flush_log_at_trx_commit, SHOW_MY_BOOL},
+ {"innodb_fast_shutdown", (char*) &innobase_fast_shutdown, SHOW_MY_BOOL},
{"innodb_flush_method", (char*) &innobase_unix_file_flush_method, SHOW_CHAR_PTR},
{"innodb_lock_wait_timeout", (char*) &innobase_lock_wait_timeout, SHOW_LONG },
{"innodb_log_arch_dir", (char*) &innobase_log_arch_dir, SHOW_CHAR_PTR},
@@ -3869,6 +3885,8 @@ static void get_options(int argc,char **argv)
break;
case OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT:
innobase_flush_log_at_trx_commit= optarg ? test(atoi(optarg)) : 1;
+ case OPT_INNODB_FAST_SHUTDOWN:
+ innobase_fast_shutdown= optarg ? test(atoi(optarg)) : 1;
break;
case OPT_INNODB_FLUSH_METHOD:
innobase_unix_file_flush_method=optarg;
diff --git a/sql/nt_servc.cc b/sql/nt_servc.cc
index 3a36f5740a9..6930800982e 100644
--- a/sql/nt_servc.cc
+++ b/sql/nt_servc.cc
@@ -5,6 +5,7 @@
-------------------------------------------------------------------------- */
#include <windows.h>
#include <process.h>
+#include <stdio.h>
#include "nt_servc.h"
@@ -52,11 +53,12 @@ NTService::NTService()
-------------------------------------------------------------------------- */
NTService::~NTService()
{
- if(ServiceName != NULL) delete[] ServiceName;
+ if (ServiceName != NULL) delete[] ServiceName;
}
/* ------------------------------------------------------------------------
-------------------------------------------------------------------------- */
+
BOOL NTService::GetOS()
{
bOsNT = FALSE;
@@ -70,12 +72,14 @@ BOOL NTService::GetOS()
return bOsNT;
}
+
/* ------------------------------------------------------------------------
Init() Registers the main service thread with the service manager
ServiceThread - pointer to the main programs entry function
when the service is started
-------------------------------------------------------------------------- */
+
long NTService::Init(LPCSTR szInternName,void *ServiceThread)
{
@@ -93,6 +97,8 @@ long NTService::Init(LPCSTR szInternName,void *ServiceThread)
return StartServiceCtrlDispatcher(stb); //register with the Service Manager
}
+
+
/* ------------------------------------------------------------------------
Install() - Installs the service with Service manager
nError values:
@@ -100,41 +106,55 @@ long NTService::Init(LPCSTR szInternName,void *ServiceThread)
1 Can't open the Service manager
2 Failed to create service
-------------------------------------------------------------------------- */
-BOOL NTService::Install(LPCSTR szInternName,LPCSTR szDisplayName,
- LPCSTR szFullPath, LPCSTR szAccountName,LPCSTR szPassword)
+
+BOOL NTService::Install(int startType, LPCSTR szInternName,
+ LPCSTR szDisplayName,
+ LPCSTR szFullPath, LPCSTR szAccountName,
+ LPCSTR szPassword)
{
+ BOOL ret_val=FALSE;
SC_HANDLE newService, scm;
- nError=0;
+ if (!SeekStatus(szInternName,1))
+ return FALSE;
+
+ char szFilePath[_MAX_PATH];
+ GetModuleFileName(NULL, szFilePath, sizeof(szFilePath));
// open a connection to the SCM
- scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE);
- if(scm) // Install the new service
- { newService = CreateService(
- scm,
- szInternName,
- szDisplayName,
- dwDesiredAccess, //default: SERVICE_ALL_ACCESS
- dwServiceType, //default: SERVICE_WIN32_OWN_PROCESS
- dwStartType, //default: SERVICE_AUTOSTART
- dwErrorControl, //default: SERVICE_ERROR_NORMAL
- szFullPath, //exec full path
- szLoadOrderGroup, //default: NULL
- lpdwTagID, //default: NULL
- szDependencies, //default: NULL
- szAccountName, //default: NULL
- szPassword); //default: NULL
-
- if (newService) CloseServiceHandle(newService); // clean up
- else nError=2;
-
- // clean up
+ if (!(scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE)))
+ printf("Failed to install the service (Couldn't open the SCM)\n");
+ else // Install the new service
+ {
+ if (!(newService=
+ CreateService(scm,
+ szInternName,
+ szDisplayName,
+ dwDesiredAccess,//default: SERVICE_ALL_ACCESS
+ dwServiceType, //default: SERVICE_WIN32_OWN_PROCESS
+ //default: SERVICE_AUTOSTART
+ (startType == 1 ? SERVICE_AUTO_START :
+ SERVICE_DEMAND_START),
+ dwErrorControl, //default: SERVICE_ERROR_NORMAL
+ szFullPath, //exec full path
+ szLoadOrderGroup, //default: NULL
+ lpdwTagID, //default: NULL
+ szDependencies, //default: NULL
+ szAccountName, //default: NULL
+ szPassword))) //default: NULL
+ printf("Failed to install the service (Couldn't create service)\n");
+ else
+ {
+ printf("Service successfully installed.\n");
+ CloseServiceHandle(newService);
+ ret_val=TRUE; // Everything went ok
+ }
CloseServiceHandle(scm);
}
- else nError=1;
-
- return (!nError);
+ return ret_val;
}
+
+
/* ------------------------------------------------------------------------
Remove() - Removes the service
nError values:
@@ -143,35 +163,40 @@ BOOL NTService::Install(LPCSTR szInternName,LPCSTR szDisplayName,
2 Failed to locate service
3 Failed to delete service
-------------------------------------------------------------------------- */
+
BOOL NTService::Remove(LPCSTR szInternName)
{
-
+ BOOL ret_value=FALSE;
SC_HANDLE service, scm;
+ if (!SeekStatus(szInternName,0))
+ return FALSE;
+
nError=0;
// open a connection to the SCM
- scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE);
-
- if (scm)
+ if (!(scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE)))
+ {
+ printf("Failed to remove the service (Couldn't open the SCM)\n");
+ }
+ else
{
- //open the service
- service = OpenService(scm,szInternName, DELETE );
- if(service)
+ if ((service = OpenService(scm,szInternName, DELETE)))
{
- if(!DeleteService(service)) nError=3;
+ if (!DeleteService(service))
+ printf("Failed to remove the service\n");
+ else
+ {
+ printf("Service successfully removed.\n");
+ ret_value=TRUE; // everything went ok
+ }
CloseServiceHandle(service);
}
else
- {
- //MessageBox(NULL,"Can't find the service","Remove Error",MB_OK|MB_ICONHAND);
- nError=2;
- }
+ printf("Failed to remove the service (Couldn't open the service)\n");
CloseServiceHandle(scm);
}
- else nError=1;
-
- return (!nError);
+ return ret_value;
}
/* ------------------------------------------------------------------------
@@ -189,80 +214,66 @@ void NTService::Stop(void)
ServiceMain() - This is the function that is called from the
service manager to start the service
-------------------------------------------------------------------------- */
+
void NTService::ServiceMain(DWORD argc, LPTSTR *argv)
{
// registration function
- pService->hServiceStatusHandle =
- RegisterServiceCtrlHandler(pService->ServiceName,
- (LPHANDLER_FUNCTION )NTService::ServiceCtrlHandler);
-
- if(!pService->hServiceStatusHandle)
- {
- pService->Exit(GetLastError());
- return;
- }
+ if (!(pService->hServiceStatusHandle =
+ RegisterServiceCtrlHandler(pService->ServiceName,
+ (LPHANDLER_FUNCTION)
+ NTService::ServiceCtrlHandler)))
+ goto error;
// notify SCM of progress
- if(!pService->SetStatus(SERVICE_START_PENDING,NO_ERROR, 0, 1, 8000))
- {
- pService->Exit(GetLastError());
- return;
- }
+ if (!pService->SetStatus(SERVICE_START_PENDING,NO_ERROR, 0, 1, 8000))
+ goto error;
// create the exit event
- pService->hExitEvent = CreateEvent (0, TRUE, FALSE,0);
- if(!pService->hExitEvent)
- {
- pService->Exit(GetLastError());
- return;
- }
+ if (!(pService->hExitEvent = CreateEvent (0, TRUE, FALSE,0)))
+ goto error;
- if(!pService->SetStatus(SERVICE_START_PENDING,NO_ERROR, 0, 3, pService->nStartTimeOut))
- {
- pService->Exit(GetLastError());
- return;
- }
+ if (!pService->SetStatus(SERVICE_START_PENDING,NO_ERROR, 0, 3,
+ pService->nStartTimeOut))
+ goto error;
// save start arguments
pService->my_argc=argc;
pService->my_argv=argv;
// start the service
- if(!pService->StartService())
- {
- pService->Exit(GetLastError());
- return;
- }
+ if (!pService->StartService())
+ goto error;
- // the service is now running.
- if(!pService->SetStatus(SERVICE_RUNNING,NO_ERROR, 0, 0, 0))
- {
- pService->Exit(GetLastError());
- return;
- }
+ // Check that the service is now running.
+ if (!pService->SetStatus(SERVICE_RUNNING,NO_ERROR, 0, 0, 0))
+ goto error;
// wait for exit event
WaitForSingleObject (pService->hExitEvent, INFINITE);
// wait for thread to exit
- if (WaitForSingleObject (pService->hThreadHandle, 1000)==WAIT_TIMEOUT)
+ if (WaitForSingleObject (pService->hThreadHandle, 1000) == WAIT_TIMEOUT)
CloseHandle(pService->hThreadHandle);
pService->Exit(0);
+ return;
+
+error:
+ pService->Exit(GetLastError());
+ return;
}
/* ------------------------------------------------------------------------
StartService() - starts the appliaction thread
-------------------------------------------------------------------------- */
+
BOOL NTService::StartService()
{
-
// Start the real service's thread (application)
- hThreadHandle = (HANDLE) _beginthread((THREAD_FC)fpServiceThread,0,(void *)this);
-
- if (hThreadHandle==0) return FALSE;
-
+ if (!(hThreadHandle = (HANDLE) _beginthread((THREAD_FC)fpServiceThread,0,
+ (void *) this)))
+ return FALSE;
bRunning = TRUE;
return TRUE;
}
@@ -274,7 +285,7 @@ void NTService::StopService()
bRunning=FALSE;
// Set the event for application
- if(hShutdownEvent)
+ if (hShutdownEvent)
SetEvent(hShutdownEvent);
// Set the event for ServiceMain
@@ -285,117 +296,186 @@ void NTService::StopService()
-------------------------------------------------------------------------- */
void NTService::PauseService()
{
- bPause = TRUE;
- SuspendThread(hThreadHandle);
+ bPause = TRUE;
+ SuspendThread(hThreadHandle);
}
/* ------------------------------------------------------------------------
-------------------------------------------------------------------------- */
void NTService::ResumeService()
{
- bPause=FALSE;
- ResumeThread(hThreadHandle);
+ bPause=FALSE;
+ ResumeThread(hThreadHandle);
}
/* ------------------------------------------------------------------------
-------------------------------------------------------------------------- */
BOOL NTService::SetStatus (DWORD dwCurrentState,DWORD dwWin32ExitCode,
- DWORD dwServiceSpecificExitCode,DWORD dwCheckPoint,DWORD dwWaitHint)
+ DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint,
+ DWORD dwWaitHint)
{
BOOL bRet;
SERVICE_STATUS serviceStatus;
- dwState=dwCurrentState;
-
- serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
- serviceStatus.dwCurrentState = dwCurrentState;
+ dwState=dwCurrentState;
- if (dwCurrentState == SERVICE_START_PENDING)
- serviceStatus.dwControlsAccepted = 0; //don't accept conrol events
- else
- serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
- SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;
+ serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+ serviceStatus.dwCurrentState = dwCurrentState;
- // if a specific exit code is defined,set up the win32 exit code properly
- if (dwServiceSpecificExitCode == 0)
- serviceStatus.dwWin32ExitCode = dwWin32ExitCode;
- else
- serviceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
+ if (dwCurrentState == SERVICE_START_PENDING)
+ serviceStatus.dwControlsAccepted = 0; //don't accept control events
+ else
+ serviceStatus.dwControlsAccepted = (SERVICE_ACCEPT_STOP |
+ SERVICE_ACCEPT_PAUSE_CONTINUE |
+ SERVICE_ACCEPT_SHUTDOWN);
- serviceStatus.dwServiceSpecificExitCode = dwServiceSpecificExitCode;
+ // if a specific exit code is defined,set up the win32 exit code properly
+ if (dwServiceSpecificExitCode == 0)
+ serviceStatus.dwWin32ExitCode = dwWin32ExitCode;
+ else
+ serviceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
- serviceStatus.dwCheckPoint = dwCheckPoint;
- serviceStatus.dwWaitHint = dwWaitHint;
+ serviceStatus.dwServiceSpecificExitCode = dwServiceSpecificExitCode;
- // Pass the status to the Service Manager
- bRet=SetServiceStatus (hServiceStatusHandle, &serviceStatus);
+ serviceStatus.dwCheckPoint = dwCheckPoint;
+ serviceStatus.dwWaitHint = dwWaitHint;
- if(!bRet) StopService();
+ // Pass the status to the Service Manager
+ if (!(bRet=SetServiceStatus (hServiceStatusHandle, &serviceStatus)))
+ StopService();
- return bRet;
+ return bRet;
}
/* ------------------------------------------------------------------------
-------------------------------------------------------------------------- */
void NTService::ServiceCtrlHandler(DWORD ctrlCode)
{
+ DWORD dwState;
- DWORD dwState = 0;
-
- if(!pService) return;
+ if (!pService)
+ return;
dwState=pService->dwState; // get current state
- switch(ctrlCode)
- {
+ switch(ctrlCode) {
- /*********** do we need this ? *******************************
- case SERVICE_CONTROL_PAUSE:
- if (pService->bRunning && ! pService->bPause)
- {
- dwState = SERVICE_PAUSED;
- pService->SetStatus(SERVICE_PAUSE_PENDING,NO_ERROR, 0, 1, pService->nPauseTimeOut);
- pService->PauseService();
- }
- break;
-
- case SERVICE_CONTROL_CONTINUE:
- if (pService->bRunning && pService->bPause)
- {
- dwState = SERVICE_RUNNING;
- pService->SetStatus(SERVICE_CONTINUE_PENDING,NO_ERROR, 0, 1, pService->nResumeTimeOut);
- pService->ResumeService();
- }
- break;
- ****************************************************************/
-
- case SERVICE_CONTROL_SHUTDOWN:
- case SERVICE_CONTROL_STOP:
- dwState = SERVICE_STOP_PENDING;
- pService->SetStatus(SERVICE_STOP_PENDING,NO_ERROR, 0, 1, pService->nStopTimeOut);
- pService->StopService();
- break;
-
- default:
- pService->SetStatus(dwState, NO_ERROR,0, 0, 0);
- break;
+#ifdef NOT_USED /* do we need this ? */
+ case SERVICE_CONTROL_PAUSE:
+ if (pService->bRunning && ! pService->bPause)
+ {
+ dwState = SERVICE_PAUSED;
+ pService->SetStatus(SERVICE_PAUSE_PENDING,NO_ERROR, 0, 1,
+ pService->nPauseTimeOut);
+ pService->PauseService();
+ }
+ break;
+
+ case SERVICE_CONTROL_CONTINUE:
+ if (pService->bRunning && pService->bPause)
+ {
+ dwState = SERVICE_RUNNING;
+ pService->SetStatus(SERVICE_CONTINUE_PENDING,NO_ERROR, 0, 1,
+ pService->nResumeTimeOut);
+ pService->ResumeService();
+ }
+ break;
+#endif
+
+ case SERVICE_CONTROL_SHUTDOWN:
+ case SERVICE_CONTROL_STOP:
+ dwState = SERVICE_STOP_PENDING;
+ pService->SetStatus(SERVICE_STOP_PENDING,NO_ERROR, 0, 1,
+ pService->nStopTimeOut);
+ pService->StopService();
+ break;
+
+ default:
+ pService->SetStatus(dwState, NO_ERROR,0, 0, 0);
+ break;
}
//pService->SetStatus(dwState, NO_ERROR,0, 0, 0);
}
+
/* ------------------------------------------------------------------------
-------------------------------------------------------------------------- */
+
void NTService::Exit(DWORD error)
{
- if (hExitEvent) CloseHandle(hExitEvent);
+ if (hExitEvent)
+ CloseHandle(hExitEvent);
// Send a message to the scm to tell that we stop
if (hServiceStatusHandle)
- SetStatus(SERVICE_STOPPED, error,0, 0, 0);
+ SetStatus(SERVICE_STOPPED, error,0, 0, 0);
// If the thread has started kill it ???
// if (hThreadHandle) CloseHandle(hThreadHandle);
}
-/* ------------------------- the end -------------------------------------- */
+/* ------------------------------------------------------------------------
+
+ -------------------------------------------------------------------------- */
+
+BOOL NTService::SeekStatus(LPCSTR szInternName, int OperationType)
+{
+ BOOL ret_value=FALSE;
+ SC_HANDLE service, scm;
+
+ // open a connection to the SCM
+ if (!(scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE)))
+ printf("There is a problem with the Service Control Manager!\n");
+ else
+ {
+ if (OperationType == 1)
+ {
+ /* an install operation */
+ if ((service = OpenService(scm,szInternName, SERVICE_ALL_ACCESS )))
+ {
+ LPQUERY_SERVICE_CONFIG ConfigBuf;
+ DWORD dwSize;
+
+ ConfigBuf = (LPQUERY_SERVICE_CONFIG) LocalAlloc(LPTR, 4096);
+ printf("The service already exists!\n");
+ if (QueryServiceConfig(service,ConfigBuf,4096,&dwSize))
+ printf("The current server installed: %s\n",
+ ConfigBuf->lpBinaryPathName);
+ LocalFree(ConfigBuf);
+ CloseServiceHandle(service);
+ }
+ else
+ ret_value=TRUE;
+ }
+ else
+ {
+ /* a remove operation */
+ if (!(service = OpenService(scm,szInternName, SERVICE_ALL_ACCESS )))
+ printf("The service doesn't exists!\n");
+ else
+ {
+ SERVICE_STATUS ss;
+
+ memset(&ss, 0, sizeof(ss));
+ if (QueryServiceStatus(service,&ss))
+ {
+ DWORD dwState = ss.dwCurrentState;
+ if (dwState == SERVICE_RUNNING)
+ printf("Failed to remove the service because the service is running\nStop the service and try again\n");
+ else if (dwState == SERVICE_STOP_PENDING)
+ printf("\
+Failed to remove the service because the service is in stop pending state!\n\
+Wait 30 seconds and try again.\n\
+If this condition persist, reboot the machine and try again\n");
+ else
+ ret_value= TRUE;
+ }
+ CloseServiceHandle(service);
+ }
+ }
+ CloseServiceHandle(scm);
+ }
+
+ return ret_value;
+}
diff --git a/sql/nt_servc.h b/sql/nt_servc.h
index 5fda96dc4d8..40d1a8c03fa 100644
--- a/sql/nt_servc.h
+++ b/sql/nt_servc.h
@@ -48,8 +48,9 @@ class NTService
//service install / un-install
- BOOL Install(LPCSTR szInternName,LPCSTR szDisplayName,LPCSTR szFullPath,
+ BOOL Install(int startType,LPCSTR szInternName,LPCSTR szDisplayName,LPCSTR szFullPath,
LPCSTR szAccountName=NULL,LPCSTR szPassword=NULL);
+ BOOL SeekStatus(LPCSTR szInternName, int OperationType);
BOOL Remove(LPCSTR szInternName);
void Stop(void); //to be called from app. to stop service
diff --git a/sql/share/norwegian-ny/.cvsignore b/sql/share/norwegian-ny/.cvsignore
deleted file mode 100755
index 2f68f259c40..00000000000
--- a/sql/share/norwegian-ny/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-errmsg.sys
diff --git a/sql/share/norwegian/.cvsignore b/sql/share/norwegian/.cvsignore
deleted file mode 100755
index 2f68f259c40..00000000000
--- a/sql/share/norwegian/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-errmsg.sys
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 0a553945ea1..befae9103f4 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -616,9 +616,30 @@ int yylex(void *arg)
return(IDENT);
case STATE_USER_VARIABLE_DELIMITER:
- lex->tok_start=lex->ptr; // Skip first `
- while ((c=yyGet()) && state_map[c] != STATE_USER_VARIABLE_DELIMITER &&
- c != (uchar) NAMES_SEP_CHAR) ;
+ lex->tok_start=lex->ptr; // Skipp first `
+#ifdef USE_MB
+ if (use_mb(default_charset_info))
+ {
+ while ((c=yyGet()) && state_map[c] != STATE_USER_VARIABLE_DELIMITER &&
+ c != (uchar) NAMES_SEP_CHAR)
+ {
+ if (my_ismbhead(default_charset_info, c))
+ {
+ int l;
+ if ((l = my_ismbchar(default_charset_info,
+ (const char *)lex->ptr-1,
+ (const char *)lex->end_of_query)) == 0)
+ break;
+ lex->ptr += l-1;
+ }
+ }
+ }
+ else
+#endif
+ {
+ while ((c=yyGet()) && state_map[c] != STATE_USER_VARIABLE_DELIMITER &&
+ c != (uchar) NAMES_SEP_CHAR) ;
+ }
yylval->lex_str=get_token(lex,yyLength());
if (lex->convert_set)
lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index f2c25e89bd8..fea3dd7728b 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -3185,7 +3185,8 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
/* fix to replace 'NULL' dates with '0' (shreeve@uci.edu) */
else if (((field->type() == FIELD_TYPE_DATE) ||
(field->type() == FIELD_TYPE_DATETIME)) &&
- (field->flags & NOT_NULL_FLAG))
+ (field->flags & NOT_NULL_FLAG) &&
+ !field->table->maybe_null)
{
COND *new_cond;
if ((new_cond= new Item_func_eq(args[0],new Item_int("0", 0, 2))))
@@ -4083,14 +4084,17 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
{
if (table->group && join->tmp_table_param.sum_func_count)
{
- DBUG_PRINT("info",("Using end_update"));
if (table->keys)
{
+ DBUG_PRINT("info",("Using end_update"));
end_select=end_update;
table->file->index_init(0);
}
else
+ {
+ DBUG_PRINT("info",("Using end_unique_update"));
end_select=end_unique_update;
+ }
}
else if (join->sort_and_group)
{
@@ -4206,8 +4210,6 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
int error;
bool found=0;
COND *on_expr=join_tab->on_expr, *select_cond=join_tab->select_cond;
- int (*next_select)(JOIN *,struct st_join_table *,bool)=
- join_tab->next_select;
if (!(error=(*join_tab->read_first_record)(join_tab)))
{
@@ -4215,7 +4217,6 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
bool not_used_in_distinct=join_tab->not_used_in_distinct;
ha_rows found_records=join->found_records;
READ_RECORD *info= &join_tab->read_record;
- join->examined_rows++;
do
{
@@ -4224,6 +4225,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
my_error(ER_SERVER_SHUTDOWN,MYF(0)); /* purecov: inspected */
return -2; /* purecov: inspected */
}
+ join->examined_rows++;
if (!on_expr || on_expr->val_int())
{
found=1;
@@ -4231,7 +4233,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
break; // Searching after not null columns
if (!select_cond || select_cond->val_int())
{
- if ((error=(*next_select)(join,join_tab+1,0)) < 0)
+ if ((error=(*join_tab->next_select)(join,join_tab+1,0)) < 0)
return error;
if (not_used_in_distinct && found_records != join->found_records)
return 0;
@@ -4252,7 +4254,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
mark_as_null_row(join_tab->table); // For group by without error
if (!select_cond || select_cond->val_int())
{
- if ((error=(*next_select)(join,join_tab+1,0)) < 0)
+ if ((error=(*join_tab->next_select)(join,join_tab+1,0)) < 0)
return error; /* purecov: inspected */
}
}
@@ -5449,6 +5451,41 @@ err:
DBUG_RETURN(-1);
}
+/*
+** Add the HAVING criteria to table->select
+*/
+
+#ifdef NOT_YET
+static bool fix_having(JOIN *join, Item **having)
+{
+ (*having)->update_used_tables(); // Some tables may have been const
+ JOIN_TAB *table=&join->join_tab[join->const_tables];
+ table_map used_tables= join->const_table_map | table->table->map;
+
+ DBUG_EXECUTE("where",print_where(*having,"having"););
+ Item* sort_table_cond=make_cond_for_table(*having,used_tables,used_tables);
+ if (sort_table_cond)
+ {
+ if (!table->select)
+ if (!(table->select=new SQL_SELECT))
+ return 1;
+ if (!table->select->cond)
+ table->select->cond=sort_table_cond;
+ else // This should never happen
+ if (!(table->select->cond=new Item_cond_and(table->select->cond,
+ sort_table_cond)))
+ return 1;
+ table->select_cond=table->select->cond;
+ DBUG_EXECUTE("where",print_where(table->select_cond,
+ "select and having"););
+ *having=make_cond_for_table(*having,~ (table_map) 0,~used_tables);
+ DBUG_EXECUTE("where",print_where(*having,"having after make_cond"););
+ }
+ return 0;
+}
+#endif
+
+
/*****************************************************************************
** Remove duplicates from tmp table
** This should be recoded to add a uniuqe index to the table and remove
diff --git a/sql/time.cc b/sql/time.cc
index 440cba457f4..e4565bdeea7 100644
--- a/sql/time.cc
+++ b/sql/time.cc
@@ -429,7 +429,6 @@ timestamp_type
str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date)
{
uint field_length,year_length,digits,i,number_of_fields,date[7];
- bool date_used=0;
const char *pos;
const char *end=str+length;
DBUG_ENTER("str_to_TIME");
@@ -455,8 +454,7 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date)
tmp_value=tmp_value*10 + (uint) (uchar) (*str - '0');
str++;
}
- if ((date[i]=tmp_value))
- date_used=1; // Found something
+ date[i]=tmp_value;
if (i == 2 && str != end && *str == 'T')
str++; // ISO8601: CCYYMMDDThhmmss
else if ( i != 5 ) // Skip inter-field delimiters
@@ -489,7 +487,7 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date)
number_of_fields=i;
while (i < 6)
date[i++]=0;
- if (number_of_fields < 3 || !date_used || date[1] > 12 ||
+ if (number_of_fields < 3 || date[1] > 12 ||
date[2] > 31 || date[3] > 23 || date[4] > 59 || date[5] > 59 ||
!fuzzy_date && (date[1] == 0 || date[2] == 0))
{