diff options
author | unknown <mskold@mysql.com> | 2005-01-21 08:43:41 +0100 |
---|---|---|
committer | unknown <mskold@mysql.com> | 2005-01-21 08:43:41 +0100 |
commit | 5c52b71d4872ae556d9f4f087f6ff9e0d0074f1e (patch) | |
tree | 98550be0e92e345e463c3f159d07fb888eadeabb /sql | |
parent | 78edb8a569e33ae8f7957240166c0a5eef9f0347 (diff) | |
parent | 205c24279aea5a4edd5130d5c533fb7553f3fad2 (diff) | |
download | mariadb-git-5c52b71d4872ae556d9f4f087f6ff9e0d0074f1e.tar.gz |
Merge mskold@bk-internal.mysql.com:/home/bk/mysql-5.0-ndb
into mysql.com:/usr/local/home/marty/MySQL/test/mysql-5.0-ndb
sql/filesort.cc:
Auto merged
sql/ha_ndbcluster.cc:
Auto merged
sql/item.h:
Auto merged
sql/item_cmpfunc.cc:
Auto merged
sql/item_cmpfunc.h:
Auto merged
sql/item_func.h:
Auto merged
sql/mysqld.cc:
Auto merged
sql/sql_class.h:
Auto merged
sql/sql_select.cc:
Auto merged
Diffstat (limited to 'sql')
41 files changed, 816 insertions, 591 deletions
diff --git a/sql/field.cc b/sql/field.cc index 400ebf65273..a1dc02eba4a 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1035,7 +1035,9 @@ int Field_decimal::store(longlong nr) double Field_decimal::val_real(void) { int not_used; - return my_strntod(&my_charset_bin, ptr, field_length, NULL, ¬_used); + char *end_not_used; + return my_strntod(&my_charset_bin, ptr, field_length, &end_not_used, + ¬_used); } longlong Field_decimal::val_int(void) @@ -4432,16 +4434,18 @@ int Field_string::store(longlong nr) double Field_string::val_real(void) { int not_used; - CHARSET_INFO *cs=charset(); - return my_strntod(cs,ptr,field_length,(char**)0,¬_used); + char *end_not_used; + CHARSET_INFO *cs= charset(); + return my_strntod(cs,ptr,field_length,&end_not_used,¬_used); } longlong Field_string::val_int(void) { int not_used; + char *end_not_used; CHARSET_INFO *cs=charset(); - return my_strntoll(cs,ptr,field_length,10,NULL,¬_used); + return my_strntoll(cs,ptr,field_length,10,&end_not_used,¬_used); } @@ -4740,8 +4744,9 @@ int Field_varstring::store(longlong nr) double Field_varstring::val_real(void) { int not_used; + char *end_not_used; uint length= length_bytes == 1 ? (uint) (uchar) *ptr : uint2korr(ptr); - return my_strntod(field_charset, ptr+length_bytes, length, (char**) 0, + return my_strntod(field_charset, ptr+length_bytes, length, &end_not_used, ¬_used); } @@ -4749,9 +4754,10 @@ double Field_varstring::val_real(void) longlong Field_varstring::val_int(void) { int not_used; + char *end_not_used; uint length= length_bytes == 1 ? (uint) (uchar) *ptr : uint2korr(ptr); - return my_strntoll(field_charset, ptr+length_bytes, length, 10, NULL, - ¬_used); + return my_strntoll(field_charset, ptr+length_bytes, length, 10, + &end_not_used, ¬_used); } @@ -5343,13 +5349,16 @@ int Field_blob::store(longlong nr) double Field_blob::val_real(void) { int not_used; - char *blob; + char *end_not_used, *blob; + uint32 length; + CHARSET_INFO *cs; + memcpy_fixed(&blob,ptr+packlength,sizeof(char*)); if (!blob) return 0.0; - uint32 length=get_length(ptr); - CHARSET_INFO *cs=charset(); - return my_strntod(cs,blob,length,(char**)0, ¬_used); + length= get_length(ptr); + cs= charset(); + return my_strntod(cs, blob, length, &end_not_used, ¬_used); } @@ -6353,11 +6362,13 @@ longlong Field_bit::val_int(void) String *Field_bit::val_str(String *val_buffer, String *val_ptr __attribute__((unused))) { + char buff[sizeof(longlong)]; uint length= min(pack_length(), sizeof(longlong)); ulonglong bits= val_int(); + mi_int8store(buff,bits); val_buffer->alloc(length); - memcpy_fixed((char*) val_buffer->ptr(), (char*) &bits, length); + memcpy_fixed((char*) val_buffer->ptr(), buff+8-length, length); val_buffer->length(length); val_buffer->set_charset(&my_charset_bin); return val_buffer; diff --git a/sql/field.h b/sql/field.h index ab911822c2c..fd1ef09d14f 100644 --- a/sql/field.h +++ b/sql/field.h @@ -123,6 +123,7 @@ public: } virtual bool eq_def(Field *field); virtual uint32 pack_length() const { return (uint32) field_length; } + virtual uint32 pack_length_in_rec() const { return pack_length(); } virtual void reset(void) { bzero(ptr,pack_length()); } virtual void reset_fields() {} virtual void set_default() @@ -1237,6 +1238,7 @@ public: { get_key_image(buff, length, itRAW); } uint32 pack_length() const { return (uint32) field_length + (bit_len > 0); } + uint32 pack_length_in_rec() const { return field_length; } void sql_type(String &str) const; field_cast_enum field_cast_type() { return FIELD_CAST_BIT; } char *pack(char *to, const char *from, uint max_length=~(uint) 0); @@ -1339,10 +1341,10 @@ int set_field_to_null_with_conversions(Field *field, bool no_conversions); #define FIELDFLAG_NUMBER 2 #define FIELDFLAG_ZEROFILL 4 #define FIELDFLAG_PACK 120 // Bits used for packing -#define FIELDFLAG_INTERVAL 256 -#define FIELDFLAG_BITFIELD 512 // mangled with dec! -#define FIELDFLAG_BLOB 1024 // mangled with dec! -#define FIELDFLAG_GEOM 2048 +#define FIELDFLAG_INTERVAL 256 // mangled with decimals! +#define FIELDFLAG_BITFIELD 512 // mangled with decimals! +#define FIELDFLAG_BLOB 1024 // mangled with decimals! +#define FIELDFLAG_GEOM 2048 // mangled with decimals! #define FIELDFLAG_LEFT_FULLSCREEN 8192 #define FIELDFLAG_RIGHT_FULLSCREEN 16384 @@ -1366,10 +1368,10 @@ int set_field_to_null_with_conversions(Field *field, bool no_conversions); #define f_decimals(x) ((uint8) (((x) >> FIELDFLAG_DEC_SHIFT) & FIELDFLAG_MAX_DEC)) #define f_is_alpha(x) (!f_is_num(x)) #define f_is_binary(x) ((x) & FIELDFLAG_BINARY) // 4.0- compatibility -#define f_is_enum(x) ((x) & FIELDFLAG_INTERVAL) -#define f_is_bitfield(x) ((x) & FIELDFLAG_BITFIELD) +#define f_is_enum(x) (((x) & (FIELDFLAG_INTERVAL | FIELDFLAG_NUMBER)) == FIELDFLAG_INTERVAL) +#define f_is_bitfield(x) (((x) & (FIELDFLAG_BITFIELD | FIELDFLAG_NUMBER)) == FIELDFLAG_BITFIELD) #define f_is_blob(x) (((x) & (FIELDFLAG_BLOB | FIELDFLAG_NUMBER)) == FIELDFLAG_BLOB) -#define f_is_geom(x) ((x) & FIELDFLAG_GEOM) +#define f_is_geom(x) (((x) & (FIELDFLAG_GEOM | FIELDFLAG_NUMBER)) == FIELDFLAG_GEOM) #define f_is_equ(x) ((x) & (1+2+FIELDFLAG_PACK+31*256)) #define f_settype(x) (((int) x) << FIELDFLAG_PACK_SHIFT) #define f_maybe_null(x) (x & FIELDFLAG_MAYBE_NULL) diff --git a/sql/field_conv.cc b/sql/field_conv.cc index b337ccd6306..07cc90283b7 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -584,6 +584,7 @@ void field_conv(Field *to,Field *from) if (to->real_type() == from->real_type()) { if (to->pack_length() == from->pack_length() && + !(to->flags & UNSIGNED_FLAG && !(from->flags & UNSIGNED_FLAG)) && to->real_type() != FIELD_TYPE_ENUM && to->real_type() != FIELD_TYPE_SET && from->charset() == to->charset() && diff --git a/sql/filesort.cc b/sql/filesort.cc index 486215e51a1..21f75fa5ea0 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -564,10 +564,10 @@ write_keys(SORTPARAM *param, register uchar **sort_keys, uint count, if (!my_b_inited(tempfile) && open_cached_file(tempfile, mysql_tmpdir, TEMP_PREFIX, DISK_BUFFER_SIZE, MYF(MY_WME))) - goto err; /* purecov: inspected */ + goto err; /* purecov: inspected */ buffpek.file_pos= my_b_tell(tempfile); if ((ha_rows) count > param->max_rows) - count=(uint) param->max_rows; /* purecov: inspected */ + count=(uint) param->max_rows; /* purecov: inspected */ buffpek.count=(ha_rows) count; for (end=sort_keys+count ; sort_keys != end ; sort_keys++) if (my_b_write(tempfile, (byte*) *sort_keys, (uint) rec_length)) @@ -838,11 +838,16 @@ int merge_many_buff(SORTPARAM *param, uchar *sort_buffer, if (flush_io_cache(to_file)) break; /* purecov: inspected */ temp=from_file; from_file=to_file; to_file=temp; + setup_io_cache(from_file); + setup_io_cache(to_file); *maxbuffer= (uint) (lastbuff-buffpek)-1; } close_cached_file(to_file); // This holds old result if (to_file == t_file) + { *t_file=t_file2; // Copy result file + setup_io_cache(t_file); + } DBUG_RETURN(*maxbuffer >= MERGEBUFF2); /* Return 1 if interrupted */ } /* merge_many_buff */ @@ -1170,7 +1175,12 @@ sortlength(SORT_FIELD *sortorder, uint s_length, bool *multi_byte_charset) else { sortorder->length=sortorder->field->pack_length(); - if (use_strnxfrm((cs=sortorder->field->charset()))) + /* + We must test cmp_type() to ensure that ENUM and SET are sorted + as numbers + */ + if (use_strnxfrm((cs=sortorder->field->charset())) && + sortorder->field->cmp_type() == STRING_RESULT) { sortorder->need_strxnfrm= 1; *multi_byte_charset= 1; diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc index abd33f2eaef..ea8633febe6 100644 --- a/sql/ha_federated.cc +++ b/sql/ha_federated.cc @@ -973,6 +973,7 @@ inline uint field_in_record_is_null ( int ha_federated::write_row(byte * buf) { int x= 0, num_fields= 0; + Field **field; ulong current_query_id= 1; ulong tmp_query_id; int all_fields_have_same_query_id= 1; @@ -1021,7 +1022,7 @@ int ha_federated::write_row(byte * buf) 0 if it remains 0, then that means no fields were specified in the query such as in the case of INSERT INTO table VALUES (val1, val2, valN) */ - for (Field **field= table->field; *field ; field++, x++) + for (field= table->field; *field ; field++, x++) { if (x > 0 && tmp_query_id != (*field)->query_id) all_fields_have_same_query_id= 0; @@ -1032,7 +1033,7 @@ int ha_federated::write_row(byte * buf) loop through the field pointer array, add any fields to both the values list and the fields list that match the current query id */ - for (Field **field= table->field; *field ; field++, x++) + for (field= table->field; *field ; field++, x++) { DBUG_PRINT("ha_federated::write_row", ("field type %d", (*field)->type())); // if there is a query id and if it's equal to the current query id diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index b5742699d7e..02d81882e7a 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -471,12 +471,24 @@ int ha_heap::create(const char *name, TABLE *table_arg, KEY_PART_INFO *key_part= pos->key_part; KEY_PART_INFO *key_part_end= key_part + pos->key_parts; - mem_per_row+= (pos->key_length + (sizeof(char*) * 2)); - keydef[key].keysegs= (uint) pos->key_parts; keydef[key].flag= (pos->flags & (HA_NOSAME | HA_NULL_ARE_EQUAL)); keydef[key].seg= seg; - keydef[key].algorithm= ((pos->algorithm == HA_KEY_ALG_UNDEF) ? + + switch (pos->algorithm) { + case HA_KEY_ALG_UNDEF: + case HA_KEY_ALG_HASH: + keydef[key].algorithm= HA_KEY_ALG_HASH; + mem_per_row+= sizeof(char*) * 2; // = sizeof(HASH_INFO) + break; + case HA_KEY_ALG_BTREE: + keydef[key].algorithm= HA_KEY_ALG_BTREE; + mem_per_row+=sizeof(TREE_ELEMENT)+pos->key_length+sizeof(char*); + break; + default: + DBUG_ASSERT(0); // cannot happen + } + keydef[key].algorithm= ((pos->algorithm == HA_KEY_ALG_UNDEF) ? HA_KEY_ALG_HASH : pos->algorithm); for (; key_part != key_part_end; key_part++, seg++) @@ -525,8 +537,10 @@ int ha_heap::create(const char *name, TABLE *table_arg, hp_create_info.auto_key_type= auto_key_type; hp_create_info.auto_increment= (create_info->auto_increment_value ? create_info->auto_increment_value - 1 : 0); + hp_create_info.max_table_size=current_thd->variables.max_heap_table_size; + max_rows = (ha_rows) (hp_create_info.max_table_size / mem_per_row); error= heap_create(fn_format(buff,name,"","",4+2), - keys,keydef, share->reclength, + keys, keydef, share->reclength, (ulong) ((share->max_rows < max_rows && share->max_rows) ? share->max_rows : max_rows), diff --git a/sql/ha_heap.h b/sql/ha_heap.h index 8b44695df07..fb526888b01 100644 --- a/sql/ha_heap.h +++ b/sql/ha_heap.h @@ -32,7 +32,11 @@ class ha_heap: public handler public: ha_heap(TABLE *table): handler(table), file(0), records_changed(0) {} ~ha_heap() {} - const char *table_type() const { return "HEAP"; } + const char *table_type() const + { + return (table->in_use->variables.sql_mode & MODE_MYSQL323) ? + "HEAP" : "MEMORY"; + } const char *index_type(uint inx) { return ((table->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ? "BTREE" : diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index d49f1c1ad46..18ab6f42d28 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -2425,6 +2425,8 @@ build_template( templ->mysql_col_len = (ulint) field->pack_length(); templ->type = get_innobase_type_from_mysql_type(field); + templ->charset = dtype_get_charset_coll_noninline( + index->table->cols[i].type.prtype); templ->is_unsigned = (ulint) (field->flags & UNSIGNED_FLAG); if (templ->type == DATA_BLOB) { @@ -4092,6 +4094,48 @@ ha_innobase::discard_or_import_tablespace( } /********************************************************************* +Deletes all rows of an InnoDB table. */ + +int +ha_innobase::delete_all_rows(void) +/*==============================*/ + /* out: error number */ +{ + row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt; + int error; + trx_t* trx; + THD* thd = current_thd; + + DBUG_ENTER("ha_innobase::delete_all_rows"); + + if (thd->lex->sql_command != SQLCOM_TRUNCATE) { + fallback: + /* We only handle TRUNCATE TABLE t as a special case. + DELETE FROM t will have to use ha_innobase::delete_row(). */ + DBUG_RETURN(my_errno=HA_ERR_WRONG_COMMAND); + } + + /* Get the transaction associated with the current thd, or create one + if not yet created */ + + trx = check_trx_exists(thd); + + /* Truncate the table in InnoDB */ + + error = row_truncate_table_for_mysql(prebuilt->table, trx); + if (error == DB_ERROR) { + /* Cannot truncate; resort to ha_innobase::delete_row() */ + goto fallback; + } + + innobase_commit_low(trx); + + error = convert_error_code_to_mysql(error, NULL); + + DBUG_RETURN(error); +} + +/********************************************************************* Drops a table from an InnoDB database. Before calling this function, MySQL calls innobase_commit to commit the transaction of the current user. Then the current user cannot have locks set on the table. Drop table diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index 0cb55e02ae3..2154e238fd1 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -159,6 +159,7 @@ class ha_innobase: public handler int create(const char *name, register TABLE *form, HA_CREATE_INFO *create_info); + int delete_all_rows(); int delete_table(const char *name); int rename_table(const char* from, const char* to); int check(THD* thd, HA_CHECK_OPT* check_opt); diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 87329c6f4af..9631b78bca3 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -1467,7 +1467,7 @@ int ha_myisam::create(const char *name, register TABLE *table_arg, fieldpos <= minpos) { /* skip null fields */ - if (!(temp_length= (*field)->pack_length())) + if (!(temp_length= (*field)->pack_length_in_rec())) continue; /* Skip null-fields */ if (! found || fieldpos < minpos || (fieldpos == minpos && temp_length < length)) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 8a2b8c8d9ae..badb486d16b 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -767,6 +767,13 @@ int ha_ndbcluster::set_ndb_value(NdbOperation *ndb_op, Field *field, DBUG_RETURN((ndb_op->setValue(fieldnr, (char*)NULL, pack_len) != 0)); DBUG_PRINT("info", ("bit field")); DBUG_DUMP("value", (char*)&bits, pack_len); +#ifdef WORDS_BIGENDIAN + if (pack_len < 5) + { + DBUG_RETURN(ndb_op->setValue(fieldnr, + ((char*)&bits)+4, pack_len) != 0); + } +#endif DBUG_RETURN(ndb_op->setValue(fieldnr, (char*)&bits, pack_len) != 0); } } @@ -859,7 +866,7 @@ int ha_ndbcluster::get_ndb_blobs_value(NdbBlob *last_ndb_blob) char *buf= m_blobs_buffer + offset; uint32 len= 0xffffffff; // Max uint32 DBUG_PRINT("value", ("read blob ptr=%x len=%u", - (uint)buf, (uint)blob_len)); + (UintPtr)buf, (uint)blob_len)); if (ndb_blob->readData(buf, len) != 0) DBUG_RETURN(-1); DBUG_ASSERT(len == blob_len); @@ -1355,6 +1362,47 @@ ha_ndbcluster::set_index_key(NdbOperation *op, DBUG_RETURN(0); } +inline +int ha_ndbcluster::define_read_attrs(byte* buf, NdbOperation* op) +{ + uint i; + THD *thd= current_thd; + + DBUG_ENTER("define_read_attrs"); + + // Define attributes to read + for (i= 0; i < table->s->fields; i++) + { + Field *field= table->field[i]; + if ((thd->query_id == field->query_id) || + ((field->flags & PRI_KEY_FLAG)) || + m_retrieve_all_fields) + { + if (get_ndb_value(op, field, i, buf)) + ERR_RETURN(op->getNdbError()); + } + else + { + m_value[i].ptr= NULL; + } + } + + if (table->s->primary_key == MAX_KEY) + { + DBUG_PRINT("info", ("Getting hidden key")); + // Scanning table with no primary key + int hidden_no= table->s->fields; +#ifndef DBUG_OFF + const NDBTAB *tab= (const NDBTAB *) m_table; + if (!tab->getColumn(hidden_no)) + DBUG_RETURN(1); +#endif + if (get_ndb_value(op, NULL, hidden_no, NULL)) + ERR_RETURN(op->getNdbError()); + } + DBUG_RETURN(0); +} + /* Read one record from NDB using primary key */ @@ -1828,47 +1876,6 @@ int ha_ndbcluster::set_bounds(NdbIndexScanOperation *op, DBUG_RETURN(0); } -inline -int ha_ndbcluster::define_read_attrs(byte* buf, NdbOperation* op) -{ - uint i; - THD *thd= current_thd; - - DBUG_ENTER("define_read_attrs"); - - // Define attributes to read - for (i= 0; i < table->s->fields; i++) - { - Field *field= table->field[i]; - if ((thd->query_id == field->query_id) || - ((field->flags & PRI_KEY_FLAG)) || - m_retrieve_all_fields) - { - if (get_ndb_value(op, field, i, buf)) - ERR_RETURN(op->getNdbError()); - } - else - { - m_value[i].ptr= NULL; - } - } - - if (table->s->primary_key == MAX_KEY) - { - DBUG_PRINT("info", ("Getting hidden key")); - // Scanning table with no primary key - int hidden_no= table->s->fields; -#ifndef DBUG_OFF - const NDBTAB *tab= (const NDBTAB *) m_table; - if (!tab->getColumn(hidden_no)) - DBUG_RETURN(1); -#endif - if (get_ndb_value(op, NULL, hidden_no, NULL)) - ERR_RETURN(op->getNdbError()); - } - DBUG_RETURN(0); -} - /* Start ordered index scan in NDB */ @@ -2734,13 +2741,13 @@ int ha_ndbcluster::index_read_last(byte * buf, const byte * key, uint key_len) inline int ha_ndbcluster::read_range_first_to_buf(const key_range *start_key, const key_range *end_key, - bool eq_range, bool sorted, + bool eq_r, bool sorted, byte* buf) { KEY* key_info; int error= 1; DBUG_ENTER("ha_ndbcluster::read_range_first_to_buf"); - DBUG_PRINT("info", ("eq_range: %d, sorted: %d", eq_range, sorted)); + DBUG_PRINT("info", ("eq_r: %d, sorted: %d", eq_r, sorted)); switch (get_index_type(active_index)){ case PRIMARY_KEY_ORDERED_INDEX: @@ -2781,14 +2788,14 @@ int ha_ndbcluster::read_range_first_to_buf(const key_range *start_key, int ha_ndbcluster::read_range_first(const key_range *start_key, const key_range *end_key, - bool eq_range, bool sorted) + bool eq_r, bool sorted) { byte* buf= table->record[0]; DBUG_ENTER("ha_ndbcluster::read_range_first"); DBUG_RETURN(read_range_first_to_buf(start_key, end_key, - eq_range, + eq_r, sorted, buf)); } @@ -3472,7 +3479,7 @@ int ha_ndbcluster::start_stmt(THD *thd) #if 0 NdbTransaction *tablock_trans= (NdbTransaction*)thd->transaction.all.ndb_tid; - DBUG_PRINT("info", ("tablock_trans: %x", (uint)tablock_trans)); + DBUG_PRINT("info", ("tablock_trans: %x", (UintPtr)tablock_trans)); DBUG_ASSERT(tablock_trans); // trans= ndb->hupp(tablock_trans); #endif @@ -4148,7 +4155,7 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg): HA_AUTO_PART_KEY | HA_NO_PREFIX_CHAR_KEYS | HA_NEED_READ_RANGE_BUFFER | - HA_CAN_BIT_FIELD), + HA_CAN_BIT_FIELD), m_share(0), m_use_write(FALSE), m_ignore_dup_key(FALSE), @@ -5100,7 +5107,8 @@ ndb_get_table_statistics(Ndb* ndb, const char * table, if (check == -1) break; - Uint64 rows, commits, size, mem; + Uint64 rows, commits, mem; + Uint32 size; pOp->getValue(NdbDictionary::Column::ROW_COUNT, (char*)&rows); pOp->getValue(NdbDictionary::Column::COMMIT_COUNT, (char*)&commits); pOp->getValue(NdbDictionary::Column::ROW_SIZE, (char*)&size); diff --git a/sql/item.cc b/sql/item.cc index c84496f8eb7..763ab84582d 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -46,7 +46,7 @@ void item_init(void) Item::Item(): name(0), orig_name(0), name_length(0), fixed(0), - collation(default_charset(), DERIVATION_COERCIBLE) + collation(&my_charset_bin, DERIVATION_COERCIBLE) { marker= 0; maybe_null=null_value=with_sum_func=unsigned_flag=0; @@ -1290,11 +1290,12 @@ double Item_param::val_real() return (double) value.integer; case STRING_VALUE: case LONG_DATA_VALUE: - { - int dummy_err; - return my_strntod(str_value.charset(), (char*) str_value.ptr(), - str_value.length(), (char**) 0, &dummy_err); - } + { + int dummy_err; + char *end_not_used; + return my_strntod(str_value.charset(), (char*) str_value.ptr(), + str_value.length(), &end_not_used, &dummy_err); + } case TIME_VALUE: /* This works for example when user says SELECT ?+0.0 and supplies @@ -2545,8 +2546,9 @@ Item_num *Item_uint::neg() Item_real::Item_real(const char *str_arg, uint length) { int error; - char *end; - value= my_strntod(&my_charset_bin, (char*) str_arg, length, &end, &error); + char *end_not_used; + value= my_strntod(&my_charset_bin, (char*) str_arg, length, &end_not_used, + &error); if (error) { /* @@ -3522,12 +3524,12 @@ void Item_cache_str::store(Item *item) double Item_cache_str::val_real() { DBUG_ASSERT(fixed == 1); - int err; + int err_not_used; + char *end_not_used; if (value) return my_strntod(value->charset(), (char*) value->ptr(), - value->length(), (char**) 0, &err); - else - return (double)0; + value->length(), &end_not_used, &err_not_used); + return (double) 0; } diff --git a/sql/item.h b/sql/item.h index d70e55b094f..c8b2d774696 100644 --- a/sql/item.h +++ b/sql/item.h @@ -888,9 +888,10 @@ public: double val_real() { DBUG_ASSERT(fixed == 1); - int err; + int err_not_used; + char *end_not_used; return my_strntod(str_value.charset(), (char*) str_value.ptr(), - str_value.length(), (char**) 0, &err); + str_value.length(), &end_not_used, &err_not_used); } longlong val_int() { @@ -1241,10 +1242,11 @@ public: enum_field_types field_type() const { return cached_field_type; } double val_real() { - int err; + int err_not_used; + char *end_not_used; return (null_value ? 0.0 : my_strntod(str_value.charset(), (char*) str_value.ptr(), - str_value.length(),NULL,&err)); + str_value.length(), &end_not_used, &err_not_used)); } longlong val_int() { diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index e840d66c962..a8c580d45f1 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1119,6 +1119,9 @@ Item_func_nullif::fix_length_and_dec() max_length=args[0]->max_length; decimals=args[0]->decimals; agg_result_type(&cached_result_type, args, 2); + if (cached_result_type == STRING_RESULT && + agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV)) + return; } } @@ -1773,64 +1776,13 @@ void Item_func_in::fix_length_and_dec() agg_cmp_type(&cmp_type, args, arg_count); + if (cmp_type == STRING_RESULT && + agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV)) + return; + for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++) const_itm&= arg[0]->const_item(); - - if (cmp_type == STRING_RESULT) - { - /* - We allow consts character set conversion for - - item IN (const1, const2, const3, ...) - - if item is in a superset for all arguments, - and if it is a stong side according to coercibility rules. - - TODO: add covnersion for non-constant IN values - via creating Item_func_conv_charset(). - */ - - if (agg_arg_collations_for_comparison(cmp_collation, args, arg_count, - MY_COLL_ALLOW_SUPERSET_CONV)) - return; - if ((!my_charset_same(args[0]->collation.collation, - cmp_collation.collation) || !const_itm)) - { - if (agg_arg_collations_for_comparison(cmp_collation, args, arg_count)) - return; - } - else - { - /* - Conversion is possible: - All IN arguments are constants. - */ - Item_arena *arena, backup; - arena= thd->change_arena_if_needed(&backup); - - for (arg= args+1, arg_end= args+arg_count; arg < arg_end; arg++) - { - if (!arg[0]->null_value && - !my_charset_same(cmp_collation.collation, - arg[0]->collation.collation)) - { - Item_string *conv; - String tmp, cstr, *ostr= arg[0]->val_str(&tmp); - uint dummy_errors; - cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), - cmp_collation.collation, &dummy_errors); - conv= new Item_string(cstr.ptr(),cstr.length(), cstr.charset(), - arg[0]->collation.derivation); - conv->str_value.copy(); - arg[0]= conv; - } - } - if (arena) - thd->restore_backup_item_arena(arena, &backup); - } - } - /* Row item with NULLs inside can return NULL or FALSE => they can't be processed as static diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index a2e244cfae2..ccc3fb2eb60 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -264,6 +264,7 @@ public: longlong val_int() { return *trig_var ? args[0]->val_int() : 1; } enum Functype functype() const { return TRIG_COND_FUNC; }; const char *func_name() const { return "trigcond"; }; + bool const_item() const { return FALSE; } }; class Item_func_not_all :public Item_func_not diff --git a/sql/item_func.h b/sql/item_func.h index 7c7c397bce0..cb6cc00c046 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -837,15 +837,19 @@ public: String *val_str(String *); double val_real() { - int err; - String *res; res=val_str(&str_value); - return res ? my_strntod(res->charset(),(char*) res->ptr(),res->length(),0,&err) : 0.0; + int err_not_used; + char *end_not_used; + String *res; + res= val_str(&str_value); + return res ? my_strntod(res->charset(),(char*) res->ptr(), + res->length(), &end_not_used, &err_not_used) : 0.0; } longlong val_int() { - int err; + int err_not_used; String *res; res=val_str(&str_value); - return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10,(char**) 0,&err) : (longlong) 0; + return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10, + (char**) 0, &err_not_used) : (longlong) 0; } enum Item_result result_type () const { return STRING_RESULT; } void fix_length_and_dec(); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 9e28acdd091..5d018b22055 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -58,17 +58,19 @@ uint nr_of_decimals(const char *str) return 0; } + double Item_str_func::val_real() { DBUG_ASSERT(fixed == 1); - int err; - char buff[64]; + int err_not_used; + char *end_not_used, buff[64]; String *res, tmp(buff,sizeof(buff), &my_charset_bin); res= val_str(&tmp); - return res ? my_strntod(res->charset(), (char*) res->ptr(),res->length(), - NULL, &err) : 0.0; + return res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(), + &end_not_used, &err_not_used) : 0.0; } + longlong Item_str_func::val_int() { DBUG_ASSERT(fixed == 1); @@ -275,7 +277,8 @@ String *Item_func_concat::val_str(String *str) current_thd->variables.max_allowed_packet); goto null; } - if (res->alloced_length() >= res->length()+res2->length()) + if (!args[0]->const_item() && + res->alloced_length() >= res->length()+res2->length()) { // Use old buffer res->append(*res2); } @@ -1904,6 +1907,7 @@ b1: str->append((char)(num>>8)); #endif str->append((char)num); } + str->set_charset(collation.collation); str->realloc(str->length()); // Add end 0 (for Purify) return str; } diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 2d4f88ed57b..d6d58adaf7c 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -177,6 +177,8 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref) } fix_length_and_dec(); } + else + return 1; uint8 uncacheable= engine->uncacheable(); if (uncacheable) { @@ -264,7 +266,6 @@ Item_singlerow_subselect::Item_singlerow_subselect(st_select_lex *select_lex) { DBUG_ENTER("Item_singlerow_subselect::Item_singlerow_subselect"); init(select_lex, new select_singlerow_subselect(this)); - max_columns= 1; maybe_null= 1; max_columns= UINT_MAX; DBUG_VOID_RETURN; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 168c68ad706..be89aa3f86d 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -591,14 +591,17 @@ void Item_sum_hybrid::clear() double Item_sum_hybrid::val_real() { DBUG_ASSERT(fixed == 1); - int err; if (null_value) return 0.0; switch (hybrid_type) { case STRING_RESULT: + { + char *end_not_used; + int err_not_used; String *res; res=val_str(&str_value); - return (res ? my_strntod(res->charset(), (char*) res->ptr(),res->length(), - (char**) 0, &err) : 0.0); + return (res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(), + &end_not_used, &err_not_used) : 0.0); + } case INT_RESULT: if (unsigned_flag) return ulonglong2double(sum_int); diff --git a/sql/item_sum.h b/sql/item_sum.h index 68899268b31..7866a9ae913 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -643,16 +643,18 @@ public: String *val_str(String *); double val_real() { - int err; + int err_not_used; + char *end_not_used; String *res; res=val_str(&str_value); return res ? my_strntod(res->charset(),(char*) res->ptr(),res->length(), - (char**) 0, &err) : 0.0; + &end_not_used, &err_not_used) : 0.0; } longlong val_int() { - int err; + int err_not_used; String *res; res=val_str(&str_value); - return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10, (char**) 0, &err) : (longlong) 0; + return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10, + (char**) 0, &err_not_used) : (longlong) 0; } enum Item_result result_type () const { return STRING_RESULT; } void fix_length_and_dec(); @@ -783,9 +785,10 @@ class Item_func_group_concat : public Item_sum String *res; char *end_ptr; int error; - res= val_str(&str_value); + if (!(res= val_str(&str_value))) + return (longlong) 0; end_ptr= (char*) res->ptr()+ res->length(); - return res ? my_strtoll10(res->ptr(), &end_ptr, &error) : (longlong) 0; + return my_strtoll10(res->ptr(), &end_ptr, &error); } String* val_str(String* str); Item *copy_or_same(THD* thd); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 2d0e5d7632f..0c1cd3cbad3 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2441,36 +2441,37 @@ void Item_func_add_time::print(String *str) /* + Calculate difference between two datetime values as seconds + microseconds. + SYNOPSIS calc_time_diff() - l_time1 TIME/DATE/DATETIME value - l_time2 TIME/DATE/DATETIME value - l_sign Can be 1 (operation of addition) - or -1 (substraction) - seconds_out Returns count of seconds bitween - l_time1 and l_time2 - microseconds_out Returns count of microseconds bitween - l_time1 and l_time2. - - DESCRIPTION - Calculates difference in seconds(seconds_out) - and microseconds(microseconds_out) - bitween two TIME/DATE/DATETIME values. + l_time1 - TIME/DATE/DATETIME value + l_time2 - TIME/DATE/DATETIME value + l_sign - 1 absolute values are substracted, + -1 absolute values are added. + seconds_out - Out parameter where difference between + l_time1 and l_time2 in seconds is stored. + microseconds_out- Out parameter where microsecond part of difference + between l_time1 and l_time2 is stored. + + NOTE + This function calculates difference between l_time1 and l_time2 absolute + values. So one should set l_sign and correct result if he want to take + signs into account (i.e. for TIME values). RETURN VALUES - Rertuns sign of difference. + Returns sign of difference. 1 means negative result 0 means positive result */ -bool calc_time_diff(TIME *l_time1,TIME *l_time2, int l_sign, - longlong *seconds_out, long *microseconds_out) +static bool calc_time_diff(TIME *l_time1, TIME *l_time2, int l_sign, + longlong *seconds_out, long *microseconds_out) { long days; bool neg; - longlong seconds= *seconds_out; - long microseconds= *microseconds_out; + longlong microseconds; /* We suppose that if first argument is MYSQL_TIMESTAMP_TIME @@ -2487,29 +2488,20 @@ bool calc_time_diff(TIME *l_time1,TIME *l_time2, int l_sign, (uint) l_time2->month, (uint) l_time2->day)); - microseconds= l_time1->second_part - l_sign*l_time2->second_part; - seconds= ((longlong) days*86400L + l_time1->hour*3600L + - l_time1->minute*60L + l_time1->second + microseconds/1000000L - - (longlong)l_sign*(l_time2->hour*3600L+l_time2->minute*60L+l_time2->second)); + microseconds= ((longlong)days*86400L + + l_time1->hour*3600L + l_time1->minute*60L + l_time1->second - + (longlong)l_sign*(l_time2->hour*3600L + l_time2->minute*60L + + l_time2->second))*1000000L + + l_time1->second_part - l_sign*l_time2->second_part; neg= 0; - if (seconds < 0) - { - seconds= -seconds; - neg= 1; - } - else if (seconds == 0 && microseconds < 0) + if (microseconds < 0) { microseconds= -microseconds; neg= 1; } - if (microseconds < 0) - { - microseconds+= 1000000L; - seconds--; - } - *seconds_out= seconds; - *microseconds_out= microseconds; + *seconds_out= microseconds/1000000L; + *microseconds_out= (long) (microseconds%1000000L); return neg; } @@ -2544,9 +2536,10 @@ String *Item_func_timediff::val_str(String *str) /* For MYSQL_TIMESTAMP_TIME only: If both argumets are negative values and diff between them - is negative we need to swap sign as result should be positive. + is non-zero we need to swap sign to get proper result. */ - if ((l_time2.neg == l_time1.neg) && l_time1.neg) + if ((l_time2.neg == l_time1.neg) && l_time1.neg && + (seconds || microseconds)) l_time3.neg= 1-l_time3.neg; // Swap sign of result calc_time_from_sec(&l_time3, (long) seconds, microseconds); @@ -2712,13 +2705,11 @@ longlong Item_func_timestamp_diff::val_int() case INTERVAL_SECOND: return seconds*neg; case INTERVAL_MICROSECOND: - { - longlong max_sec= LONGLONG_MAX/1000000; - if (max_sec > seconds || - max_sec == seconds && LONGLONG_MAX%1000000 >= microseconds) - return (longlong) (seconds*1000000L+microseconds)*neg; - goto null_date; - } + /* + In MySQL difference between any two valid datetime values + in microseconds fits into longlong. + */ + return (seconds*1000000L+microseconds)*neg; default: break; } diff --git a/sql/lock.cc b/sql/lock.cc index fffd48d5305..2dd12fce802 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -182,12 +182,12 @@ static int lock_external(THD *thd, TABLE **tables, uint count) if ((error=(*tables)->file->external_lock(thd,lock_type))) { + print_lock_error(error, (*tables)->file->table_type()); for (; i-- ; tables--) { (*tables)->file->external_lock(thd, F_UNLCK); (*tables)->current_lock=F_UNLCK; } - print_lock_error(error, (*tables)->file->table_type()); DBUG_RETURN(error); } else @@ -375,12 +375,13 @@ static int unlock_external(THD *thd, TABLE **table,uint count) { (*table)->current_lock = F_UNLCK; if ((error=(*table)->file->external_lock(thd, F_UNLCK))) + { error_code=error; + print_lock_error(error_code, (*table)->file->table_type()); + } } table++; } while (--count); - if (error_code) - print_lock_error(error_code, (*table)->file->table_type()); DBUG_RETURN(error_code); } diff --git a/sql/log_event.cc b/sql/log_event.cc index 2fa4e09913e..5ee034d785e 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -3201,7 +3201,7 @@ void User_var_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* las */ fprintf(file, ":=???;\n"); else - fprintf(file, ":=_%s %s COLLATE %s;\n", cs->csname, hex_str, cs->name); + fprintf(file, ":=_%s %s COLLATE `%s`;\n", cs->csname, hex_str, cs->name); my_afree(hex_str); } break; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 6f569ea3ef4..322b38abe13 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -831,6 +831,7 @@ void wait_for_refresh(THD *thd); int open_tables(THD *thd, TABLE_LIST *tables, uint *counter); int simple_open_n_lock_tables(THD *thd,TABLE_LIST *tables); bool open_and_lock_tables(THD *thd,TABLE_LIST *tables); +bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables); int lock_tables(THD *thd, TABLE_LIST *tables, uint counter); TABLE *open_temporary_table(THD *thd, const char *path, const char *db, const char *table_name, bool link_in_list); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 94c780301e1..58bcbfd641c 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -54,7 +54,7 @@ #endif #ifdef HAVE_NDBCLUSTER_DB #define OPT_NDBCLUSTER_DEFAULT 0 -#if defined(NDB_SHM_TRANSPORTER) && MYSQL_VERSION_ID >= 50000 +#if defined(NOT_ENOUGH_TESTED) && defined(NDB_SHM_TRANSPORTER) && MYSQL_VERSION_ID >= 50000 #define OPT_NDB_SHM_DEFAULT 1 #else #define OPT_NDB_SHM_DEFAULT 0 @@ -2700,12 +2700,37 @@ with --log-bin instead."); mysql_bin_log.purge_logs_before_date(purge_time); } #endif + if (!opt_bin_logname && !opt_binlog_index_name) + { + /* + User didn't give us info to name the binlog index file. + Picking `hostname`-bin.index like did in 4.x, causes replication to + fail if the hostname is changed later. So, we would like to instead + require a name. But as we don't want to break many existing setups, we + only give warning, not error. + */ + sql_print_warning("\ +No argument was provided to --log-bin, and --log-bin-index was not used; \ +so replication may break when this MySQL server acts as a master and \ +has his hostname changed!! Please use '--log-bin=%s' to avoid \ +this problem.", + mysql_bin_log.get_name()); + } } - else if (opt_log_slave_updates) + else { - sql_print_warning("\ -you need to use --log-bin to make --log-slave-updates work. \ -Now disabling --log-slave-updates."); + if (opt_log_slave_updates) + { + sql_print_error("\ +You need to use --log-bin=# to make --log-slave-updates work."); + unireg_abort(1); + } + if (opt_binlog_index_name) + { + sql_print_error("\ +You need to use --log-bin=# to make --log-bin-index work."); + unireg_abort(1); + } } #ifdef HAVE_REPLICATION @@ -4425,9 +4450,11 @@ Disable with --skip-large-pages.", Disable with --skip-innodb (will save memory).", (gptr*) &opt_innodb, (gptr*) &opt_innodb, 0, GET_BOOL, NO_ARG, OPT_INNODB_DEFAULT, 0, 0, 0, 0, 0}, +#ifdef HAVE_INNOBASE_DB {"innodb_checksums", OPT_INNODB_CHECKSUMS, "Enable InnoDB checksums validation (enabled by default). \ Disable with --skip-innodb-checksums.", (gptr*) &innobase_use_checksums, (gptr*) &innobase_use_checksums, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, +#endif {"innodb_data_file_path", OPT_INNODB_DATA_FILE_PATH, "Path to individual files and their sizes.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -4503,14 +4530,16 @@ Disable with --skip-isam.", {"log", 'l', "Log connections and queries to file.", (gptr*) &opt_logname, (gptr*) &opt_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"log-bin", OPT_BIN_LOG, - "Log update queries in binary format.", + "Log update queries in binary format. Optional (but strongly recommended " + "to avoid replication problems if server's hostname changes) argument " + "should be the chosen location for the binary log files.", (gptr*) &opt_bin_logname, (gptr*) &opt_bin_logname, 0, GET_STR_ALLOC, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"log-bin-index", OPT_BIN_LOG_INDEX, "File that holds the names for last binary log files.", (gptr*) &opt_binlog_index_name, (gptr*) &opt_binlog_index_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"log-error", OPT_ERROR_LOG_FILE, "Log error file.", + {"log-error", OPT_ERROR_LOG_FILE, "Error log file.", (gptr*) &log_error_file_ptr, (gptr*) &log_error_file_ptr, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"log-isam", OPT_ISAM_LOG, "Log all MyISAM changes to file.", diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 4b0e5f036cb..e67a9881bba 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -50,6 +50,11 @@ #define test_use_count(A) {} #endif +/* + Convert double value to #rows. Currently this does floor(), and we + might consider using round() instead. +*/ +#define double2rows(x) ((ha_rows)(x)) static int sel_cmp(Field *f,char *a,char *b,uint8 a_flag,uint8 b_flag); @@ -720,7 +725,7 @@ QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, TABLE *table, uint key_nr, key_part_info= head->key_info[index].key_part; my_init_dynamic_array(&ranges, sizeof(QUICK_RANGE*), 16, 16); - /* 'thd' is not accessible in QUICK_RANGE_SELECT::get_next_init(). */ + /* 'thd' is not accessible in QUICK_RANGE_SELECT::reset(). */ multi_range_bufsiz= thd->variables.read_rnd_buff_size; multi_range_count= thd->variables.multi_range_count; multi_range_length= 0; @@ -744,9 +749,6 @@ int QUICK_RANGE_SELECT::init() { DBUG_ENTER("QUICK_RANGE_SELECT::init"); - if ((error= get_next_init())) - DBUG_RETURN(error); - if (file->inited == handler::NONE) DBUG_RETURN(error= file->ha_index_init(index)); error= 0; @@ -1628,6 +1630,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, DBUG_PRINT("enter",("keys_to_use: %lu prev_tables: %lu const_tables: %lu", keys_to_use.to_ulonglong(), (ulong) prev_tables, (ulong) const_tables)); + DBUG_PRINT("info", ("records=%lu", (ulong)head->file->records)); delete quick; quick=0; needed_reg.clear_all(); @@ -1874,6 +1877,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, double get_sweep_read_cost(const PARAM *param, ha_rows records) { double result; + DBUG_ENTER("get_sweep_read_cost"); if (param->table->file->primary_key_is_clustered()) { result= param->table->file->read_time(param->table->s->primary_key, @@ -1912,7 +1916,7 @@ double get_sweep_read_cost(const PARAM *param, ha_rows records) } } DBUG_PRINT("info",("returning cost=%g", result)); - return result; + DBUG_RETURN(result); } @@ -2393,43 +2397,27 @@ typedef struct { const PARAM *param; MY_BITMAP covered_fields; /* union of fields covered by all scans */ - - /* TRUE if covered_fields is a superset of needed_fields */ - bool is_covering; - - double index_scan_costs; /* SUM(cost of 'index-only' scans) */ - double total_cost; /* Fraction of table records that satisfies conditions of all scans. This is the number of full records that will be retrieved if a non-index_only index intersection will be employed. */ - double records_fract; + double out_rows; + /* TRUE if covered_fields is a superset of needed_fields */ + bool is_covering; + ha_rows index_records; /* sum(#records to look in indexes) */ + double index_scan_costs; /* SUM(cost of 'index-only' scans) */ + double total_cost; } ROR_INTERSECT_INFO; /* - Re-initialize an allocated intersect info to contain zero scans. - SYNOPSIS - info Intersection info structure to re-initialize. -*/ - -static void ror_intersect_reinit(ROR_INTERSECT_INFO *info) -{ - info->is_covering= FALSE; - info->index_scan_costs= 0.0f; - info->records_fract= 1.0f; - bitmap_clear_all(&info->covered_fields); -} - -/* Allocate a ROR_INTERSECT_INFO and initialize it to contain zero scans. SYNOPSIS ror_intersect_init() param Parameter from test_quick_select - is_index_only If TRUE, set ROR_INTERSECT_INFO to be covering RETURN allocated structure @@ -2437,7 +2425,7 @@ static void ror_intersect_reinit(ROR_INTERSECT_INFO *info) */ static -ROR_INTERSECT_INFO* ror_intersect_init(const PARAM *param, bool is_index_only) +ROR_INTERSECT_INFO* ror_intersect_init(const PARAM *param) { ROR_INTERSECT_INFO *info; uchar* buf; @@ -2450,46 +2438,39 @@ ROR_INTERSECT_INFO* ror_intersect_init(const PARAM *param, bool is_index_only) if (bitmap_init(&info->covered_fields, buf, param->fields_bitmap_size*8, FALSE)) return NULL; - ror_intersect_reinit(info); + info->is_covering= FALSE; + info->index_scan_costs= 0.0; + info->index_records= 0; + info->out_rows= param->table->file->records; + bitmap_clear_all(&info->covered_fields); return info; } - +void ror_intersect_cpy(ROR_INTERSECT_INFO *dst, const ROR_INTERSECT_INFO *src) +{ + dst->param= src->param; + memcpy(dst->covered_fields.bitmap, src->covered_fields.bitmap, + src->covered_fields.bitmap_size); + dst->out_rows= src->out_rows; + dst->is_covering= src->is_covering; + dst->index_records= src->index_records; + dst->index_scan_costs= src->index_scan_costs; + dst->total_cost= src->total_cost; +} /* - Check if adding a ROR scan to a ROR-intersection reduces its cost of - ROR-intersection and if yes, update parameters of ROR-intersection, - including its cost. + Get selectivity of a ROR scan wrt ROR-intersection. SYNOPSIS - ror_intersect_add() - param Parameter from test_quick_select - info ROR-intersection structure to add the scan to. - ror_scan ROR scan info to add. - is_cpk_scan If TRUE, add the scan as CPK scan (this can be inferred - from other parameters and is passed separately only to - avoid duplicating the inference code) - + ror_scan_selectivity() + info ROR-interection + scan ROR scan + NOTES - Adding a ROR scan to ROR-intersect "makes sense" iff the cost of ROR- - intersection decreases. The cost of ROR-intersection is caclulated as - follows: - - cost= SUM_i(key_scan_cost_i) + cost_of_full_rows_retrieval - - if (union of indexes used covers all needed fields) - cost_of_full_rows_retrieval= 0; - else - { - cost_of_full_rows_retrieval= - cost_of_sweep_read(E(rows_to_retrieve), rows_in_table); - } - - E(rows_to_retrieve) is caclulated as follows: Suppose we have a condition on several keys cond=k_11=c_11 AND k_12=c_12 AND ... // parts of first key k_21=c_21 AND k_22=c_22 AND ... // parts of second key ... - k_n1=c_n1 AND k_n3=c_n3 AND ... (1) + k_n1=c_n1 AND k_n3=c_n3 AND ... (1) //parts of the key used by *scan where k_ij may be the same as any k_pq (i.e. keys may have common parts). @@ -2563,38 +2544,30 @@ ROR_INTERSECT_INFO* ror_intersect_init(const PARAM *param, bool is_index_only) and reduce adjacent fractions. RETURN - TRUE ROR scan added to ROR-intersection, cost updated. - FALSE It doesn't make sense to add this ROR scan to this ROR-intersection. + Selectivity of given ROR scan. + */ -bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info, - ROR_SCAN_INFO* ror_scan, bool is_cpk_scan=FALSE) +static double ror_scan_selectivity(const ROR_INTERSECT_INFO *info, + const ROR_SCAN_INFO *scan) { - int i; - SEL_ARG *sel_arg; - KEY_PART_INFO *key_part= - info->param->table->key_info[ror_scan->keynr].key_part; double selectivity_mult= 1.0; + KEY_PART_INFO *key_part= info->param->table->key_info[scan->keynr].key_part; byte key_val[MAX_KEY_LENGTH+MAX_FIELD_WIDTH]; /* key values tuple */ - - DBUG_ENTER("ror_intersect_add"); - DBUG_PRINT("info", ("Current selectivity= %g", info->records_fract)); - DBUG_PRINT("info", ("Adding scan on %s", - info->param->table->key_info[ror_scan->keynr].name)); - SEL_ARG *tuple_arg= NULL; char *key_ptr= (char*) key_val; - bool cur_covered, prev_covered= - bitmap_is_set(&info->covered_fields, key_part->fieldnr); - - ha_rows prev_records= param->table->file->records; + SEL_ARG *sel_arg, *tuple_arg= NULL; + bool cur_covered; + bool prev_covered= bitmap_is_set(&info->covered_fields, key_part->fieldnr); key_range min_range; key_range max_range; min_range.key= (byte*) key_val; min_range.flag= HA_READ_KEY_EXACT; max_range.key= (byte*) key_val; max_range.flag= HA_READ_AFTER_KEY; - - for(i= 0, sel_arg= ror_scan->sel_arg; sel_arg; + ha_rows prev_records= info->param->table->file->records; + int i; + DBUG_ENTER("ror_intersect_selectivity"); + for(i= 0, sel_arg= scan->sel_arg; sel_arg; i++, sel_arg= sel_arg->next_key_part) { cur_covered= bitmap_is_set(&info->covered_fields, (key_part + i)->fieldnr); @@ -2604,7 +2577,7 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info, { if (!tuple_arg) { - tuple_arg= ror_scan->sel_arg; + tuple_arg= scan->sel_arg; tuple_arg->store_min(key_part->length, &key_ptr, 0); } while (tuple_arg->next_key_part != sel_arg) @@ -2615,10 +2588,8 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info, } ha_rows records; min_range.length= max_range.length= ((char*) key_ptr - (char*) key_val); - records= param->table->file-> - records_in_range(ror_scan->keynr, - &min_range, - &max_range); + records= info->param->table->file-> + records_in_range(scan->keynr, &min_range, &max_range); if (cur_covered) { /* uncovered -> covered */ @@ -2637,49 +2608,105 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info, } if (!prev_covered) { - double tmp= rows2double(param->table->quick_rows[ror_scan->keynr]) / + double tmp= rows2double(info->param->table->quick_rows[scan->keynr]) / rows2double(prev_records); DBUG_PRINT("info", ("Selectivity multiplier: %g", tmp)); selectivity_mult *= tmp; } + DBUG_PRINT("info", ("Returning multiplier: %g", selectivity_mult)); + DBUG_RETURN(selectivity_mult); +} + +/* + Check if adding a ROR scan to a ROR-intersection reduces its cost of + ROR-intersection and if yes, update parameters of ROR-intersection, + including its cost. + + SYNOPSIS + ror_intersect_add() + param Parameter from test_quick_select + info ROR-intersection structure to add the scan to. + ror_scan ROR scan info to add. + is_cpk_scan If TRUE, add the scan as CPK scan (this can be inferred + from other parameters and is passed separately only to + avoid duplicating the inference code) + NOTES + Adding a ROR scan to ROR-intersect "makes sense" iff the cost of ROR- + intersection decreases. The cost of ROR-intersection is calculated as + follows: + + cost= SUM_i(key_scan_cost_i) + cost_of_full_rows_retrieval + + When we add a scan the first increases and the second decreases. + + cost_of_full_rows_retrieval= + (union of indexes used covers all needed fields) ? + cost_of_sweep_read(E(rows_to_retrieve), rows_in_table) : + 0 + + E(rows_to_retrieve) = #rows_in_table * ror_scan_selectivity(null, scan1) * + ror_scan_selectivity({scan1}, scan2) * ... * + ror_scan_selectivity({scan1,...}, scanN). + RETURN + TRUE ROR scan added to ROR-intersection, cost updated. + FALSE It doesn't make sense to add this ROR scan to this ROR-intersection. +*/ + +static bool ror_intersect_add(ROR_INTERSECT_INFO *info, + ROR_SCAN_INFO* ror_scan, bool is_cpk_scan) +{ + double selectivity_mult= 1.0; + + DBUG_ENTER("ror_intersect_add"); + DBUG_PRINT("info", ("Current out_rows= %g", info->out_rows)); + DBUG_PRINT("info", ("Adding scan on %s", + info->param->table->key_info[ror_scan->keynr].name)); + DBUG_PRINT("info", ("is_cpk_scan=%d",is_cpk_scan)); + + selectivity_mult = ror_scan_selectivity(info, ror_scan); if (selectivity_mult == 1.0) { /* Don't add this scan if it doesn't improve selectivity. */ DBUG_PRINT("info", ("The scan doesn't improve selectivity.")); - DBUG_RETURN(FALSE); + DBUG_RETURN(false); } - - info->records_fract *= selectivity_mult; - ha_rows cur_scan_records= info->param->table->quick_rows[ror_scan->keynr]; + + info->out_rows *= selectivity_mult; + DBUG_PRINT("info", ("info->total_cost= %g", info->total_cost)); + if (is_cpk_scan) { - info->index_scan_costs += rows2double(cur_scan_records)* + /* + CPK scan is used to filter out rows. We apply filtering for + each record of every scan. Assuming 1/TIME_FOR_COMPARE_ROWID + per check this gives us: + */ + info->index_scan_costs += rows2double(info->index_records) / TIME_FOR_COMPARE_ROWID; } else { - info->index_records += cur_scan_records; + info->index_records += info->param->table->quick_rows[ror_scan->keynr]; info->index_scan_costs += ror_scan->index_read_cost; bitmap_union(&info->covered_fields, &ror_scan->covered_fields); - } - - if (!info->is_covering && bitmap_is_subset(&info->param->needed_fields, - &info->covered_fields)) - { - DBUG_PRINT("info", ("ROR-intersect is covering now")); - info->is_covering= TRUE; + if (!info->is_covering && bitmap_is_subset(&info->param->needed_fields, + &info->covered_fields)) + { + DBUG_PRINT("info", ("ROR-intersect is covering now")); + info->is_covering= TRUE; + } } info->total_cost= info->index_scan_costs; + DBUG_PRINT("info", ("info->total_cost= %g", info->total_cost)); if (!info->is_covering) { - ha_rows table_recs= info->param->table->file->records; - info->total_cost += - get_sweep_read_cost(info->param, - (ha_rows)(info->records_fract*table_recs)); + info->total_cost += + get_sweep_read_cost(info->param, double2rows(info->out_rows)); + DBUG_PRINT("info", ("info->total_cost= %g", info->total_cost)); } - DBUG_PRINT("info", ("New selectivity= %g", info->records_fract)); + DBUG_PRINT("info", ("New out_rows= %g", info->out_rows)); DBUG_PRINT("info", ("New cost= %g, %scovering", info->total_cost, info->is_covering?"" : "non-")); DBUG_RETURN(TRUE); @@ -2701,9 +2728,13 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info, a covering ROR-intersection) NOTES - get_key_scans_params must be called before for the same SEL_TREE before - this function can be called. + get_key_scans_params must be called before this function can be called. + + When this function is called by ROR-union construction algorithm it + assumes it is building an uncovered ROR-intersection (and thus # of full + records to be retrieved is wrong here). This is a hack. + IMPLEMENTATION The approximate best non-covering plan search algorithm is as follows: find_min_ror_intersection_scan() @@ -2717,11 +2748,11 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info, min_scan= make_scan(S); while (R is not empty) { - if (!selectivity(S + first(R) < selectivity(S))) + firstR= R - first(R); + if (!selectivity(S + firstR < selectivity(S))) continue; - + S= S + first(R); - R= R - first(R); if (cost(S) < min_cost) { min_cost= cost(S); @@ -2752,15 +2783,15 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, bool *are_all_covering) { uint idx; - double min_cost= read_time; + double min_cost= DBL_MAX; DBUG_ENTER("get_best_ror_intersect"); if ((tree->n_ror_scans < 2) || !param->table->file->records) DBUG_RETURN(NULL); /* - Collect ROR-able SEL_ARGs and create ROR_SCAN_INFO for each of them. - Also find and save clustered PK scan if there is one. + Step1: Collect ROR-able SEL_ARGs and create ROR_SCAN_INFO for each of + them. Also find and save clustered PK scan if there is one. */ ROR_SCAN_INFO **cur_ror_scan; ROR_SCAN_INFO *cpk_scan= NULL; @@ -2796,8 +2827,8 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, tree->ror_scans_end);); /* Ok, [ror_scans, ror_scans_end) is array of ptrs to initialized - ROR_SCAN_INFOs. - Now, get a minimal key scan using an approximate algorithm. + ROR_SCAN_INFO's. + Step 2: Get best ROR-intersection using an approximate algorithm. */ qsort(tree->ror_scans, tree->n_ror_scans, sizeof(ROR_SCAN_INFO*), (qsort_cmp)cmp_ror_scan_info); @@ -2814,45 +2845,41 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, intersect_scans_end= intersect_scans; /* Create and incrementally update ROR intersection. */ - ROR_INTERSECT_INFO *intersect; - if (!(intersect= ror_intersect_init(param, FALSE))) + ROR_INTERSECT_INFO *intersect, *intersect_best; + if (!(intersect= ror_intersect_init(param)) || + !(intersect_best= ror_intersect_init(param))) return NULL; - /* [intersect_scans, intersect_scans_best) will hold the best combination */ + /* [intersect_scans,intersect_scans_best) will hold the best intersection */ ROR_SCAN_INFO **intersect_scans_best; - ha_rows best_rows; - bool is_best_covering; - double best_index_scan_costs; - LINT_INIT(best_rows); /* protected by intersect_scans_best */ - LINT_INIT(is_best_covering); - LINT_INIT(best_index_scan_costs); - cur_ror_scan= tree->ror_scans; - /* Start with one scan */ intersect_scans_best= intersect_scans; while (cur_ror_scan != tree->ror_scans_end && !intersect->is_covering) { - /* S= S + first(R); */ - if (ror_intersect_add(param, intersect, *cur_ror_scan)) - *(intersect_scans_end++)= *cur_ror_scan; - /* R= R - first(R); */ - cur_ror_scan++; + /* S= S + first(R); R= R - first(R); */ + if (!ror_intersect_add(intersect, *cur_ror_scan, false)) + { + cur_ror_scan++; + continue; + } + + *(intersect_scans_end++)= *(cur_ror_scan++); if (intersect->total_cost < min_cost) { /* Local minimum found, save it */ - min_cost= intersect->total_cost; - best_rows= (ha_rows)(intersect->records_fract* - rows2double(param->table->file->records)); - /* Prevent divisons by zero */ - if (!best_rows) - best_rows= 1; - is_best_covering= intersect->is_covering; + ror_intersect_cpy(intersect_best, intersect); intersect_scans_best= intersect_scans_end; - best_index_scan_costs= intersect->index_scan_costs; + min_cost = intersect->total_cost; } } + if (intersect_scans_best == intersect_scans) + { + DBUG_PRINT("info", ("None of scans increase selectivity")); + DBUG_RETURN(NULL); + } + DBUG_EXECUTE("info",print_ror_scans_arr(param->table, "best ROR-intersection", intersect_scans, @@ -2860,48 +2887,26 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, *are_all_covering= intersect->is_covering; uint best_num= intersect_scans_best - intersect_scans; + ror_intersect_cpy(intersect, intersect_best); + /* Ok, found the best ROR-intersection of non-CPK key scans. - Check if we should add a CPK scan. - - If the obtained ROR-intersection is covering, it doesn't make sense - to add CPK scan - Clustered PK contains all fields and if we're doing - CPK scan doing other CPK scans will only add more overhead. + Check if we should add a CPK scan. If the obtained ROR-intersection is + covering, it doesn't make sense to add CPK scan. */ if (cpk_scan && !intersect->is_covering) { - /* - Handle the special case: ROR-intersect(PRIMARY, key1) is - the best, but cost(range(key1)) > cost(best_non_ror_range_scan) - */ - if (best_num == 0) - { - cur_ror_scan= tree->ror_scans; - intersect_scans_end= intersect_scans; - ror_intersect_reinit(intersect); - if (!ror_intersect_add(param, intersect, *cur_ror_scan)) - DBUG_RETURN(NULL); /* shouldn't happen actually */ - *(intersect_scans_end++)= *cur_ror_scan; - best_num++; - } - - if (ror_intersect_add(param, intersect, cpk_scan)) + if (ror_intersect_add(intersect, cpk_scan, TRUE) && + (intersect->total_cost < min_cost)) { cpk_scan_used= TRUE; - min_cost= intersect->total_cost; - best_rows= (ha_rows)(intersect->records_fract* - rows2double(param->table->file->records)); - /* Prevent divisons by zero */ - if (!best_rows) - best_rows= 1; - is_best_covering= intersect->is_covering; - best_index_scan_costs= intersect->index_scan_costs; + intersect_best= intersect; //just set pointer here } } /* Ok, return ROR-intersect plan if we have found one */ TRP_ROR_INTERSECT *trp= NULL; - if (best_num > 1 || cpk_scan_used) + if (min_cost < read_time && (cpk_scan_used || best_num > 1)) { if (!(trp= new (param->mem_root) TRP_ROR_INTERSECT)) DBUG_RETURN(trp); @@ -2911,14 +2916,18 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, DBUG_RETURN(NULL); memcpy(trp->first_scan, intersect_scans, best_num*sizeof(ROR_SCAN_INFO*)); trp->last_scan= trp->first_scan + best_num; - trp->is_covering= is_best_covering; - trp->read_cost= min_cost; + trp->is_covering= intersect_best->is_covering; + trp->read_cost= intersect_best->total_cost; + /* Prevent divisons by zero */ + ha_rows best_rows = double2rows(intersect_best->out_rows); + if (!best_rows) + best_rows= 1; trp->records= best_rows; - trp->index_scan_costs= best_index_scan_costs; - trp->cpk_scan= cpk_scan; - DBUG_PRINT("info", - ("Returning non-covering ROR-intersect plan: cost %g, records %lu", - trp->read_cost, (ulong) trp->records)); + trp->index_scan_costs= intersect_best->index_scan_costs; + trp->cpk_scan= cpk_scan_used? cpk_scan: NULL; + DBUG_PRINT("info", ("Returning non-covering ROR-intersect plan:" + "cost %g, records %lu", + trp->read_cost, (ulong) trp->records)); } DBUG_RETURN(trp); } @@ -3145,8 +3154,9 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree, found_records) + cpu_cost; - DBUG_PRINT("info",("read_time: %g found_read_time: %g", - read_time, found_read_time)); + DBUG_PRINT("info",("key %s: found_read_time: %g (cur. read_time: %g)", + param->table->key_info[keynr].name, found_read_time, + read_time)); if (read_time > found_read_time && found_records != HA_POS_ERROR /*|| read_time == DBL_MAX*/ ) @@ -5642,9 +5652,8 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() We reuse the same instance of handler so we need to call both init and reset here. */ - if (cur_quick->init()) + if (cur_quick->init() || cur_quick->reset()) DBUG_RETURN(1); - cur_quick->reset(); unique= new Unique(refpos_order_cmp, (void *)head->file, head->file->ref_length, @@ -5662,10 +5671,8 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() if (cur_quick->file->inited != handler::NONE) cur_quick->file->ha_index_end(); - if (cur_quick->init()) + if (cur_quick->init() || cur_quick->reset()) DBUG_RETURN(1); - /* QUICK_RANGE_SELECT::reset never fails */ - cur_quick->reset(); } if (result) @@ -5732,9 +5739,8 @@ int QUICK_INDEX_MERGE_SELECT::get_next() if (pk_quick_select) { doing_pk_scan= TRUE; - if ((result= pk_quick_select->init())) + if ((result= pk_quick_select->init()) || (result= pk_quick_select->reset())) DBUG_RETURN(result); - pk_quick_select->reset(); DBUG_RETURN(pk_quick_select->get_next()); } } @@ -5895,28 +5901,15 @@ int QUICK_ROR_UNION_SELECT::get_next() DBUG_RETURN(error); } - -/* - Initialize data structures needed by get_next(). - - SYNOPSIS - QUICK_RANGE_SELECT::get_next_init() - - DESCRIPTION - This is called from get_next() at its first call for an object. - It allocates memory buffers and sets size variables. - - RETURN - 0 OK. - != 0 Error. -*/ - -int QUICK_RANGE_SELECT::get_next_init(void) +int QUICK_RANGE_SELECT::reset() { uint mrange_bufsiz; byte *mrange_buff; - DBUG_ENTER("QUICK_RANGE_SELECT::get_next_init"); - + DBUG_ENTER("QUICK_RANGE_SELECT::reset"); + next=0; + range= NULL; + cur_range= (QUICK_RANGE**) ranges.buffer; + /* Do not allocate the buffers twice. */ if (multi_range_length) { @@ -5924,15 +5917,8 @@ int QUICK_RANGE_SELECT::get_next_init(void) DBUG_RETURN(0); } - /* If the ranges are not yet initialized, wait for the next call. */ - if (! ranges.elements) - { - DBUG_RETURN(0); - } - - /* - Allocate the ranges array. - */ + /* Allocate the ranges array. */ + DBUG_ASSERT(ranges.elements); multi_range_length= min(multi_range_count, ranges.elements); DBUG_ASSERT(multi_range_length > 0); while (multi_range_length && ! (multi_range= (KEY_MULTI_RANGE*) @@ -5949,9 +5935,7 @@ int QUICK_RANGE_SELECT::get_next_init(void) DBUG_RETURN(HA_ERR_OUT_OF_MEM); } - /* - Allocate the handler buffer if necessary. - */ + /* Allocate the handler buffer if necessary. */ if (file->table_flags() & HA_NEED_READ_RANGE_BUFFER) { mrange_bufsiz= min(multi_range_bufsiz, @@ -5979,9 +5963,6 @@ int QUICK_RANGE_SELECT::get_next_init(void) multi_range_buff->buffer_end= mrange_buff + mrange_bufsiz; multi_range_buff->end_of_used_area= mrange_buff; } - - /* Initialize the current QUICK_RANGE pointer. */ - cur_range= (QUICK_RANGE**) ranges.buffer; DBUG_RETURN(0); } @@ -7935,10 +7916,10 @@ int QUICK_GROUP_MIN_MAX_SELECT::reset(void) file->extra(HA_EXTRA_KEYREAD); /* We need only the key attributes */ result= file->ha_index_init(index); result= file->index_last(record); - if (quick_prefix_select) - quick_prefix_select->reset(); if (result) DBUG_RETURN(result); + if (quick_prefix_select && quick_prefix_select->reset()) + DBUG_RETURN(1); /* Save the prefix of the last group. */ key_copy(last_prefix, record, index_info, group_prefix_len); diff --git a/sql/opt_range.h b/sql/opt_range.h index 71981dfb5c7..97d646cedbe 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -59,6 +59,44 @@ class QUICK_RANGE :public Sql_alloc { /* Quick select interface. This class is a parent for all QUICK_*_SELECT and FT_SELECT classes. + + The usage scenario is as follows: + 1. Create quick select + quick= new QUICK_XXX_SELECT(...); + + 2. Perform lightweight initialization. This can be done in 2 ways: + 2.a: Regular initialization + if (quick->init()) + { + //the only valid action after failed init() call is delete + delete quick; + } + 2.b: Special initialization for quick selects merged by QUICK_ROR_*_SELECT + if (quick->init_ror_merged_scan()) + delete quick; + + 3. Perform zero, one, or more scans. + while (...) + { + // initialize quick select for scan. This may allocate + // buffers and/or prefetch rows. + if (quick->reset()) + { + //the only valid action after failed reset() call is delete + delete quick; + //abort query + } + + // perform the scan + do + { + res= quick->get_next(); + } while (res && ...) + } + + 4. Delete the select: + delete quick; + */ class QUICK_SELECT_I @@ -117,27 +155,16 @@ public: reset() should be called when it is certain that row retrieval will be necessary. This call may do heavyweight initialization like buffering first N records etc. If reset() call fails get_next() must not be called. - Note that reset() may be called several times if this quick select - executes in a subselect. + Note that reset() may be called several times if + * the quick select is executed in a subselect + * a JOIN buffer is used + RETURN 0 OK other Error code */ virtual int reset(void) = 0; - /* - Initialize get_next() for row retrieval. - SYNOPSIS - get_next_init() - - get_next_init() must be called before the first get_next(). - If get_next_init() call fails get_next() must not be called. - - RETURN - 0 OK - other Error code - */ - virtual int get_next_init() { return false; } virtual int get_next() = 0; /* get next record to retrieve */ /* Range end should be called when we have looped over the whole index */ @@ -284,18 +311,7 @@ public: ~QUICK_RANGE_SELECT(); int init(); - int reset(void) - { - next=0; - range= NULL; - cur_range= (QUICK_RANGE**) ranges.buffer; - /* - Note: in opt_range.cc there are places where it is assumed that this - function always succeeds - */ - return 0; - } - int get_next_init(void); + int reset(void); int get_next(); void range_end(); int get_next_prefix(uint prefix_length, byte *cur_prefix); @@ -310,6 +326,8 @@ public: #ifndef DBUG_OFF void dbug_dump(int indent, bool verbose); #endif +private: + /* Used only by QUICK_SELECT_DESC */ QUICK_RANGE_SELECT(const QUICK_RANGE_SELECT& org) : QUICK_SELECT_I() { bcopy(&org, this, sizeof(*this)); @@ -685,6 +703,7 @@ public: QUICK_RANGE_SELECT (thd, table, key, 1) { init(); } ~FT_SELECT() { file->ft_end(); } int init() { return error=file->ft_init(); } + int reset() { return 0; } int get_next() { return error=file->ft_read(record); } int get_type() { return QS_TYPE_FULLTEXT; } }; diff --git a/sql/procedure.h b/sql/procedure.h index 4212a9246a5..33c1288c88e 100644 --- a/sql/procedure.h +++ b/sql/procedure.h @@ -59,10 +59,18 @@ public: void set(double nr) { value=nr; } void set(longlong nr) { value=(double) nr; } void set(const char *str,uint length,CHARSET_INFO *cs) - { int err; value=my_strntod(cs,(char*) str,length,(char**)0,&err); } + { + int err_not_used; + char *end_not_used; + value= my_strntod(cs,(char*) str,length, &end_not_used, &err_not_used); + } double val_real() { return value; } longlong val_int() { return (longlong) value; } - String *val_str(String *s) { s->set(value,decimals,default_charset()); return s; } + String *val_str(String *s) + { + s->set(value,decimals,default_charset()); + return s; + } unsigned int size_of() { return sizeof(*this);} }; @@ -98,10 +106,11 @@ public: { str_value.copy(str,length,cs); } double val_real() { - int err; + int err_not_used; + char *end_not_used; CHARSET_INFO *cs=str_value.charset(); return my_strntod(cs, (char*) str_value.ptr(), str_value.length(), - (char**) 0, &err); + &end_not_used, &err_not_used); } longlong val_int() { diff --git a/sql/records.cc b/sql/records.cc index 9a506cadf0c..00da1ac1adc 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -100,19 +100,8 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table, } else if (select && select->quick) { - int error; DBUG_PRINT("info",("using rr_quick")); - - if (!table->file->inited) - table->file->ha_index_init(select->quick->index); info->read_record=rr_quick; - - if ((error= select->quick->get_next_init())) - { - /* Cannot return error code here. Instead print to error log. */ - table->file->print_error(error,MYF(ME_NOREFRESH)); - thd->fatal_error(); - } } else if (table->sort.record_pointers) { diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 951bffd698d..3cdcef7c8ee 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -1,4 +1,4 @@ -languages czech=cze latin2, danish=dan latin1, dutch=nla latin1, english=eng latin1, estonian=est latin7, french=fre latin1, german=ger latin1, greek=greek greek, hungarian=hun latin2, italian=ita latin1, japanese=jpn ujis, korean=kor euckr, norwegian-ny=norwegian-ny latin1, norwegian=nor latin1, polish=pol latin2, portuguese=por latin1, romanian=rum latin2, russian=rus koi8r, serbian=serbian cp1250, slovak=slo latin2, spanish=spa latin1, swedish=swe latin1, ukrainian=ukr koi8u; +languages czech=cze latin2, danish=dan latin1, dutch=nla latin1, english=eng latin1, estonian=est latin7, french=fre latin1, german=ger latin1, greek=greek greek, hungarian=hun latin2, italian=ita latin1, japanese=jpn ujis, japanese-sjis=jps sjis, korean=kor euckr, norwegian-ny=norwegian-ny latin1, norwegian=nor latin1, polish=pol latin2, portuguese=por latin1, romanian=rum latin2, russian=rus koi8r, serbian=serbian cp1250, slovak=slo latin2, spanish=spa latin1, swedish=swe latin1, ukrainian=ukr koi8u; default-language eng @@ -79,6 +79,7 @@ ER_CANT_CREATE_TABLE dan "Kan ikke oprette tabellen '%-.64s' (Fejlkode: %d)" nla "Kan tabel '%-.64s' niet aanmaken (Errcode: %d)" eng "Can't create table '%-.64s' (errno: %d)" + jps "'%-.64s' テーブルが作れません.(errno: %d)", est "Ei suuda luua tabelit '%-.64s' (veakood: %d)" fre "Ne peut cr馥r la table '%-.64s' (Errcode: %d)" ger "Kann Tabelle '%-.64s' nicht erzeugen (Fehler: %d)" @@ -103,6 +104,7 @@ ER_CANT_CREATE_DB dan "Kan ikke oprette databasen '%-.64s' (Fejlkode: %d)" nla "Kan database '%-.64s' niet aanmaken (Errcode: %d)" eng "Can't create database '%-.64s' (errno: %d)" + jps "'%-.64s' データベースが作れません (errno: %d)", est "Ei suuda luua andmebaasi '%-.64s' (veakood: %d)" fre "Ne peut cr馥r la base '%-.64s' (Erreur %d)" ger "Kann Datenbank '%-.64s' nicht erzeugen (Fehler: %d)" @@ -127,6 +129,7 @@ ER_DB_CREATE_EXISTS dan "Kan ikke oprette databasen '%-.64s'; databasen eksisterer" nla "Kan database '%-.64s' niet aanmaken; database bestaat reeds" eng "Can't create database '%-.64s'; database exists" + jps "'%-.64s' データベースが作れません.既にそのデータベースが存在します", est "Ei suuda luua andmebaasi '%-.64s': andmebaas juba eksisteerib" fre "Ne peut cr馥r la base '%-.64s'; elle existe d駛" ger "Kann Datenbank '%-.64s' nicht erzeugen. Datenbank '%-.64s' existiert bereits" @@ -151,6 +154,7 @@ ER_DB_DROP_EXISTS dan "Kan ikke slette (droppe) '%-.64s'; databasen eksisterer ikke" nla "Kan database '%-.64s' niet verwijderen; database bestaat niet" eng "Can't drop database '%-.64s'; database doesn't exist" + jps "'%-.64s' データベースを破棄できません. そのデータベースがないのです.", est "Ei suuda kustutada andmebaasi '%-.64s': andmebaasi ei eksisteeri" fre "Ne peut effacer la base '%-.64s'; elle n'existe pas" ger "Kann Datenbank '%-.64s' nicht lschen. Keine Datenbank '%-.64s' vorhanden" @@ -175,6 +179,7 @@ ER_DB_DROP_DELETE dan "Fejl ved sletning (drop) af databasen (kan ikke slette '%-.64s', Fejlkode %d)" nla "Fout bij verwijderen database (kan '%-.64s' niet verwijderen, Errcode: %d)" eng "Error dropping database (can't delete '%-.64s', errno: %d)" + jps "データベース破棄エラー ('%-.64s' を削除できません, errno: %d)", est "Viga andmebaasi kustutamisel (ei suuda kustutada faili '%-.64s', veakood: %d)" fre "Ne peut effacer la base '%-.64s' (erreur %d)" ger "Fehler beim Lschen der Datenbank ('%-.64s' kann nicht gelscht werden, Fehlernuumer: %d)" @@ -199,6 +204,7 @@ ER_DB_DROP_RMDIR dan "Fejl ved sletting af database (kan ikke slette folderen '%-.64s', Fejlkode %d)" nla "Fout bij verwijderen database (kan rmdir '%-.64s' niet uitvoeren, Errcode: %d)" eng "Error dropping database (can't rmdir '%-.64s', errno: %d)" + jps "データベース破棄エラー ('%-.64s' を rmdir できません, errno: %d)", est "Viga andmebaasi kustutamisel (ei suuda kustutada kataloogi '%-.64s', veakood: %d)" fre "Erreur en effa軋nt la base (rmdir '%-.64s', erreur %d)" ger "Fehler beim Lschen der Datenbank (Verzeichnis '%-.64s' kann nicht gelscht werden, Fehlernummer: %d)" @@ -223,6 +229,7 @@ ER_CANT_DELETE_FILE dan "Fejl ved sletning af '%-.64s' (Fejlkode: %d)" nla "Fout bij het verwijderen van '%-.64s' (Errcode: %d)" eng "Error on delete of '%-.64s' (errno: %d)" + jps "'%-.64s' の削除がエラー (errno: %d)", est "Viga '%-.64s' kustutamisel (veakood: %d)" fre "Erreur en effa軋nt '%-.64s' (Errcode: %d)" ger "Fehler beim Lschen von '%-.64s' (Fehler: %d)" @@ -247,6 +254,7 @@ ER_CANT_FIND_SYSTEM_REC dan "Kan ikke l誑e posten i systemfolderen" nla "Kan record niet lezen in de systeem tabel" eng "Can't read record in system table" + jps "system table のレコードを読む事ができませんでした", est "Ei suuda lugeda kirjet ssteemsest tabelist" fre "Ne peut lire un enregistrement de la table 'system'" ger "Datensatz in der Systemtabelle nicht lesbar" @@ -271,6 +279,7 @@ ER_CANT_GET_STAT dan "Kan ikke l誑e status af '%-.64s' (Fejlkode: %d)" nla "Kan de status niet krijgen van '%-.64s' (Errcode: %d)" eng "Can't get status of '%-.64s' (errno: %d)" + jps "'%-.64s' のステイタスが得られません. (errno: %d)", est "Ei suuda lugeda '%-.64s' olekut (veakood: %d)" fre "Ne peut obtenir le status de '%-.64s' (Errcode: %d)" ger "Kann Status von '%-.64s' nicht ermitteln (Fehler: %d)" @@ -295,6 +304,7 @@ ER_CANT_GET_WD dan "Kan ikke l誑e aktive folder (Fejlkode: %d)" nla "Kan de werkdirectory niet krijgen (Errcode: %d)" eng "Can't get working directory (errno: %d)" + jps "working directory を得る事ができませんでした (errno: %d)", est "Ei suuda identifitseerida jooksvat kataloogi (veakood: %d)" fre "Ne peut obtenir le r駱ertoire de travail (Errcode: %d)" ger "Kann Arbeitsverzeichnis nicht ermitteln (Fehler: %d)" @@ -319,6 +329,7 @@ ER_CANT_LOCK dan "Kan ikke l蚶e fil (Fejlkode: %d)" nla "Kan de file niet blokeren (Errcode: %d)" eng "Can't lock file (errno: %d)" + jps "ファイルをロックできません (errno: %d)", est "Ei suuda lukustada faili (veakood: %d)" fre "Ne peut verrouiller le fichier (Errcode: %d)" ger "Datei kann nicht gesperrt werden (Fehler: %d)" @@ -343,6 +354,7 @@ ER_CANT_OPEN_FILE dan "Kan ikke 蘆ne fil: '%-.64s' (Fejlkode: %d)" nla "Kan de file '%-.64s' niet openen (Errcode: %d)" eng "Can't open file: '%-.64s' (errno: %d)" + jps "'%-.64s' ファイルを開く事ができません (errno: %d)", est "Ei suuda avada faili '%-.64s' (veakood: %d)" fre "Ne peut ouvrir le fichier: '%-.64s' (Errcode: %d)" ger "Datei '%-.64s' nicht ffnen (Fehler: %d)" @@ -367,6 +379,7 @@ ER_FILE_NOT_FOUND dan "Kan ikke finde fila: '%-.64s' (Fejlkode: %d)" nla "Kan de file: '%-.64s' niet vinden (Errcode: %d)" eng "Can't find file: '%-.64s' (errno: %d)" + jps "'%-.64s' ファイルを見付ける事ができません.(errno: %d)", est "Ei suuda leida faili '%-.64s' (veakood: %d)" fre "Ne peut trouver le fichier: '%-.64s' (Errcode: %d)" ger "Kann Datei '%-.64s' nicht finden (Fehler: %d)" @@ -391,6 +404,7 @@ ER_CANT_READ_DIR dan "Kan ikke l誑e folder '%-.64s' (Fejlkode: %d)" nla "Kan de directory niet lezen van '%-.64s' (Errcode: %d)" eng "Can't read dir of '%-.64s' (errno: %d)" + jps "'%-.64s' ディレクトリが読めません.(errno: %d)", est "Ei suuda lugeda kataloogi '%-.64s' (veakood: %d)" fre "Ne peut lire le r駱ertoire de '%-.64s' (Errcode: %d)" ger "Verzeichnis von '%-.64s' nicht lesbar (Fehler: %d)" @@ -415,6 +429,7 @@ ER_CANT_SET_WD dan "Kan ikke skifte folder til '%-.64s' (Fejlkode: %d)" nla "Kan de directory niet veranderen naar '%-.64s' (Errcode: %d)" eng "Can't change dir to '%-.64s' (errno: %d)" + jps "'%-.64s' ディレクトリに chdir できません.(errno: %d)", est "Ei suuda siseneda kataloogi '%-.64s' (veakood: %d)" fre "Ne peut changer le r駱ertoire pour '%-.64s' (Errcode: %d)" ger "Kann nicht in das Verzeichnis '%-.64s' wechseln (Fehler: %d)" @@ -462,6 +477,7 @@ ER_DISK_FULL dan "Ikke mere diskplads (%s). Venter p at f frigjort plads..." nla "Schijf vol (%s). Aan het wachten totdat er ruimte vrij wordt gemaakt..." eng "Disk full (%s); waiting for someone to free some space..." + jps "Disk full (%s). 誰かが何かを減らすまでまってください...", est "Ketas t臺s (%s). Ootame kuni tekib vaba ruumi..." fre "Disque plein (%s). J'attend que quelqu'un lib鑽e de l'espace..." ger "Festplatte voll (%-.64s). Warte, bis jemand Platz schafft ..." @@ -486,6 +502,7 @@ ER_DUP_KEY 23000 dan "Kan ikke skrive, flere ens ngler i tabellen '%-.64s'" nla "Kan niet schrijven, dubbele zoeksleutel in tabel '%-.64s'" eng "Can't write; duplicate key in table '%-.64s'" + jps "table '%-.64s' に key が重複していて書きこめません", est "Ei saa kirjutada, korduv vti tabelis '%-.64s'" fre "Ecriture impossible, doublon dans une cl de la table '%-.64s'" ger "Kann nicht speichern, Grund: doppelter Schlssel in Tabelle '%-.64s'" @@ -533,6 +550,7 @@ ER_ERROR_ON_READ dan "Fejl ved l誑ning af '%-.64s' (Fejlkode: %d)" nla "Fout bij het lezen van file '%-.64s' (Errcode: %d)" eng "Error reading file '%-.64s' (errno: %d)" + jps "'%-.64s' ファイルの読み込みエラー (errno: %d)", est "Viga faili '%-.64s' lugemisel (veakood: %d)" fre "Erreur en lecture du fichier '%-.64s' (Errcode: %d)" ger "Fehler beim Lesen der Datei '%-.64s' (Fehler: %d)" @@ -557,6 +575,7 @@ ER_ERROR_ON_RENAME dan "Fejl ved omdbning af '%-.64s' til '%-.64s' (Fejlkode: %d)" nla "Fout bij het hernoemen van '%-.64s' naar '%-.64s' (Errcode: %d)" eng "Error on rename of '%-.64s' to '%-.64s' (errno: %d)" + jps "'%-.64s' を '%-.64s' に rename できません (errno: %d)", est "Viga faili '%-.64s' mbernimetamisel '%-.64s'-ks (veakood: %d)" fre "Erreur en renommant '%-.64s' en '%-.64s' (Errcode: %d)" ger "Fehler beim Umbenennen von '%-.64s' in '%-.64s' (Fehler: %d)" @@ -581,6 +600,7 @@ ER_ERROR_ON_WRITE dan "Fejl ved skriving av filen '%-.64s' (Fejlkode: %d)" nla "Fout bij het wegschrijven van file '%-.64s' (Errcode: %d)" eng "Error writing file '%-.64s' (errno: %d)" + jps "'%-.64s' ファイルを書く事ができません (errno: %d)", est "Viga faili '%-.64s' kirjutamisel (veakood: %d)" fre "Erreur d'馗riture du fichier '%-.64s' (Errcode: %d)" ger "Fehler beim Speichern der Datei '%-.64s' (Fehler: %d)" @@ -605,6 +625,7 @@ ER_FILE_USED dan "'%-.64s' er l蚶t mod opdateringer" nla "'%-.64s' is geblokeerd tegen veranderingen" eng "'%-.64s' is locked against change" + jps "'%-.64s' はロックされています", est "'%-.64s' on lukustatud muudatuste vastu" fre "'%-.64s' est verrouill contre les modifications" ger "'%-.64s' ist fr トnderungen gesperrt" @@ -629,6 +650,7 @@ ER_FILSORT_ABORT dan "Sortering afbrudt" nla "Sorteren afgebroken" eng "Sort aborted" + jps "Sort 中断", est "Sorteerimine katkestatud" fre "Tri alphab騁ique abandonn" ger "Sortiervorgang abgebrochen" @@ -653,6 +675,7 @@ ER_FORM_NOT_FOUND dan "View '%-.64s' eksisterer ikke for '%-.64s'" nla "View '%-.64s' bestaat niet voor '%-.64s'" eng "View '%-.64s' doesn't exist for '%-.64s'" + jps "View '%-.64s' が '%-.64s' に定義されていません", est "Vaade '%-.64s' ei eksisteeri '%-.64s' jaoks" fre "La vue (View) '%-.64s' n'existe pas pour '%-.64s'" ger "View '%-.64s' existiert fr '%-.64s' nicht" @@ -725,6 +748,7 @@ ER_KEY_NOT_FOUND dan "Kan ikke finde posten i '%-.64s'" nla "Kan record niet vinden in '%-.64s'" eng "Can't find record in '%-.64s'" + jps "'%-.64s'のなかにレコードが見付かりません", est "Ei suuda leida kirjet '%-.64s'-s" fre "Ne peut trouver l'enregistrement dans '%-.64s'" ger "Kann Datensatz nicht finden" @@ -749,6 +773,7 @@ ER_NOT_FORM_FILE dan "Forkert indhold i: '%-.64s'" nla "Verkeerde info in file: '%-.64s'" eng "Incorrect information in file: '%-.64s'" + jps "ファイル '%-.64s' の info が間違っているようです", est "Vigane informatsioon failis '%-.64s'" fre "Information erronn馥 dans le fichier: '%-.64s'" ger "Falsche Information in Datei '%-.64s'" @@ -773,6 +798,7 @@ ER_NOT_KEYFILE dan "Fejl i indeksfilen til tabellen '%-.64s'; prv at reparere den" nla "Verkeerde zoeksleutel file voor tabel: '%-.64s'; probeer het te repareren" eng "Incorrect key file for table '%-.64s'; try to repair it" + jps "'%-.64s' テーブルの key file が間違っているようです. 修復をしてください", est "Tabeli '%-.64s' vtmefail on vigane; proovi seda parandada" fre "Index corrompu dans la table: '%-.64s'; essayez de le r駱arer" ger "Falsche Schlssel-Datei fr Tabelle '%-.64s'. versuche zu reparieren" @@ -797,6 +823,7 @@ ER_OLD_KEYFILE dan "Gammel indeksfil for tabellen '%-.64s'; reparer den" nla "Oude zoeksleutel file voor tabel '%-.64s'; repareer het!" eng "Old key file for table '%-.64s'; repair it!" + jps "'%-.64s' テーブルは古い形式の key file のようです; 修復をしてください", est "Tabeli '%-.64s' vtmefail on aegunud; paranda see!" fre "Vieux fichier d'index pour la table '%-.64s'; r駱arez le!" ger "Alte Schlssel-Datei fr Tabelle '%-.64s'. Bitte reparieren" @@ -821,6 +848,7 @@ ER_OPEN_AS_READONLY dan "'%-.64s' er skrivebeskyttet" nla "'%-.64s' is alleen leesbaar" eng "Table '%-.64s' is read only" + jps "'%-.64s' は読み込み専用です", est "Tabel '%-.64s' on ainult lugemiseks" fre "'%-.64s' est en lecture seulement" ger "'%-.64s' ist nur lesbar" @@ -845,6 +873,7 @@ ER_OUTOFMEMORY HY001 S1001 dan "Ikke mere hukommelse. Genstart serveren og prv igen (mangler %d bytes)" nla "Geen geheugen meer. Herstart server en probeer opnieuw (%d bytes nodig)" eng "Out of memory; restart server and try again (needed %d bytes)" + jps "Out of memory. デーモンをリスタートしてみてください (%d bytes 必要)", est "M舁u sai otsa. Proovi MySQL uuesti k臺vitada (puudu j臺 %d baiti)" fre "Manque de m駑oire. Red駑arrez le d駑on et r-essayez (%d octets n馗essaires)" ger "Kein Speicher vorhanden (%d Bytes bentigt). Bitte Server neu starten" @@ -869,6 +898,7 @@ ER_OUT_OF_SORTMEMORY HY001 S1001 dan "Ikke mere sorteringshukommelse. リg sorteringshukommelse (sort buffer size) for serveren" nla "Geen geheugen om te sorteren. Verhoog de server sort buffer size" eng "Out of sort memory; increase server sort buffer size" + jps "Out of sort memory. sort buffer size が足りないようです.", est "M舁u sai sorteerimisel otsa. Suurenda MySQL-i sorteerimispuhvrit" fre "Manque de m駑oire pour le tri. Augmentez-la." ger "Kein Speicher zum Sortieren vorhanden. sort_buffer_size sollte erhht werden" @@ -893,6 +923,7 @@ ER_UNEXPECTED_EOF dan "Uventet afslutning p fil (eof) ved l誑ning af filen '%-.64s' (Fejlkode: %d)" nla "Onverwachte eof gevonden tijdens het lezen van file '%-.64s' (Errcode: %d)" eng "Unexpected EOF found when reading file '%-.64s' (errno: %d)" + jps "'%-.64s' ファイルを読み込み中に EOF が予期せぬ所で現れました. (errno: %d)", est "Ootamatu faililpum舐gend faili '%-.64s' lugemisel (veakood: %d)" fre "Fin de fichier inattendue en lisant '%-.64s' (Errcode: %d)" ger "Unerwartetes Ende beim Lesen der Datei '%-.64s' (Fehler: %d)" @@ -917,6 +948,7 @@ ER_CON_COUNT_ERROR 08004 dan "For mange forbindelser (connections)" nla "Te veel verbindingen" eng "Too many connections" + jps "接続が多すぎます", est "Liiga palju samaaegseid hendusi" fre "Trop de connections" ger "Zu viele Verbindungen" @@ -941,6 +973,7 @@ ER_OUT_OF_RESOURCES dan "Udg蘰t for tr蘚e/hukommelse" nla "Geen thread geheugen meer; controleer of mysqld of andere processen al het beschikbare geheugen gebruikt. Zo niet, dan moet u wellicht 'ulimit' gebruiken om mysqld toe te laten meer geheugen te benutten, of u kunt extra swap ruimte toevoegen" eng "Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space" + jps "Out of memory; mysqld かその他のプロセスがメモリーを全て使っているか確認してください. メモリーを使い切っていない場合、'ulimit' を設定して mysqld のメモリー使用限界量を多くするか、swap space を増やしてみてください", est "M舁u sai otsa. Vimalik, et aitab swap-i lisamine vi k舖u 'ulimit' abil MySQL-le rohkema m舁u kasutamise lubamine" fre "Manque de 'threads'/m駑oire" ger "Kein Speicher mehr vorhanden. Prfen Sie, ob mysqld oder ein anderer Prozess allen Speicher verbraucht. Wenn nicht, sollten Sie mit 'ulimit' dafr sorgen, dass mysqld mehr Speicher benutzen darf, oder mehr Swap-Speicher einrichten" @@ -965,6 +998,7 @@ ER_BAD_HOST_ERROR 08S01 dan "Kan ikke f v誡tsnavn for din adresse" nla "Kan de hostname niet krijgen van uw adres" eng "Can't get hostname for your address" + jps "その address の hostname が引けません.", est "Ei suuda lahendada IP aadressi masina nimeks" fre "Ne peut obtenir de hostname pour votre adresse" ger "Kann Hostnamen fr diese Adresse nicht erhalten" @@ -1011,6 +1045,7 @@ ER_DBACCESS_DENIED_ERROR 42000 dan "Adgang n詒tet bruger: '%-.32s'@'%-.64s' til databasen '%-.64s'" nla "Toegang geweigerd voor gebruiker: '%-.32s'@'%-.64s' naar database '%-.64s'" eng "Access denied for user '%-.32s'@'%-.64s' to database '%-.64s'" + jps "ユーザー '%-.32s'@'%-.64s' の '%-.64s' データベースへのアクセスを拒否します", est "Ligip蒿s keelatud kasutajale '%-.32s'@'%-.64s' andmebaasile '%-.64s'" fre "Acc鑚 refus pour l'utilisateur: '%-.32s'@'@%-.64s'. Base '%-.64s'" ger "Benutzer '%-.32s'@'%-.64s' hat keine Zugriffsberechtigung fr Datenbank '%-.64s'" @@ -1034,6 +1069,7 @@ ER_ACCESS_DENIED_ERROR 28000 dan "Adgang n詒tet bruger: '%-.32s'@'%-.64s' (Bruger adgangskode: %s)" nla "Toegang geweigerd voor gebruiker: '%-.32s'@'%-.64s' (Wachtwoord gebruikt: %s)" eng "Access denied for user '%-.32s'@'%-.64s' (using password: %s)" + jps "ユーザー '%-.32s'@'%-.64s' を拒否します.uUsing password: %s)", est "Ligip蒿s keelatud kasutajale '%-.32s'@'%-.64s' (kasutab parooli: %s)" fre "Acc鑚 refus pour l'utilisateur: '%-.32s'@'@%-.64s' (mot de passe: %s)" ger "Benutzer '%-.32s'@'%-.64s' hat keine Zugriffsberechtigung (verwendetes Passwort: %-.64s)" @@ -1057,6 +1093,7 @@ ER_NO_DB_ERROR 3D000 dan "Ingen database valgt" nla "Geen database geselecteerd" eng "No database selected" + jps "データベースが選択されていません.", est "Andmebaasi ei ole valitud" fre "Aucune base n'a 騁 s駘ectionn馥" ger "Keine Datenbank ausgew臧lt" @@ -1081,6 +1118,7 @@ ER_UNKNOWN_COM_ERROR 08S01 dan "Ukendt kommando" nla "Onbekend commando" eng "Unknown command" + jps "そのコマンドは何?", est "Tundmatu k舖k" fre "Commande inconnue" ger "Unbekannter Befehl" @@ -1105,6 +1143,7 @@ ER_BAD_NULL_ERROR 23000 dan "Kolonne '%-.64s' kan ikke v誡e NULL" nla "Kolom '%-.64s' kan niet null zijn" eng "Column '%-.64s' cannot be null" + jps "Column '%-.64s' は null にはできないのです", est "Tulp '%-.64s' ei saa omada nullv蒿rtust" fre "Le champ '%-.64s' ne peut 黎re vide (null)" ger "Feld '%-.64s' darf nicht NULL sein" @@ -1129,6 +1168,7 @@ ER_BAD_DB_ERROR 42000 dan "Ukendt database '%-.64s'" nla "Onbekende database '%-.64s'" eng "Unknown database '%-.64s'" + jps "'%-.64s' なんてデータベースは知りません.", est "Tundmatu andmebaas '%-.64s'" fre "Base '%-.64s' inconnue" ger "Unbekannte Datenbank '%-.64s'" @@ -1153,6 +1193,7 @@ ER_TABLE_EXISTS_ERROR 42S01 dan "Tabellen '%-.64s' findes allerede" nla "Tabel '%-.64s' bestaat al" eng "Table '%-.64s' already exists" + jps "Table '%-.64s' は既にあります", est "Tabel '%-.64s' juba eksisteerib" fre "La table '%-.64s' existe d駛" ger "Tabelle '%-.64s' bereits vorhanden" @@ -1177,6 +1218,7 @@ ER_BAD_TABLE_ERROR 42S02 dan "Ukendt tabel '%-.64s'" nla "Onbekende tabel '%-.64s'" eng "Unknown table '%-.64s'" + jps "table '%-.64s' はありません.", est "Tundmatu tabel '%-.64s'" fre "Table '%-.64s' inconnue" ger "Unbekannte Tabelle '%-.64s'" @@ -1225,6 +1267,7 @@ ER_SERVER_SHUTDOWN 08S01 dan "Database nedlukning er i gang" nla "Bezig met het stoppen van de server" eng "Server shutdown in progress" + jps "Server を shutdown 中...", est "Serveri seiskamine k臺b" fre "Arr黎 du serveur en cours" ger "Der Server wird heruntergefahren" @@ -1249,6 +1292,7 @@ ER_BAD_FIELD_ERROR 42S22 S0022 dan "Ukendt kolonne '%-.64s' i tabel %s" nla "Onbekende kolom '%-.64s' in %s" eng "Unknown column '%-.64s' in '%-.64s'" + jps "'%-.64s' column は '%-.64s' にはありません.", est "Tundmatu tulp '%-.64s' '%-.64s'-s" fre "Champ '%-.64s' inconnu dans %s" ger "Unbekanntes Tabellenfeld '%-.64s' in %-.64s" @@ -1273,6 +1317,7 @@ ER_WRONG_FIELD_WITH_GROUP 42000 S1009 dan "Brugte '%-.64s' som ikke var i group by" nla "Opdracht gebruikt '%-.64s' dat niet in de GROUP BY voorkomt" eng "'%-.64s' isn't in GROUP BY" + jps "'%-.64s' isn't in GROUP BY", est "'%-.64s' puudub GROUP BY klauslis" fre "'%-.64s' n'est pas dans 'group by'" ger "'%-.64s' ist nicht in GROUP BY vorhanden" @@ -1363,6 +1408,7 @@ ER_TOO_LONG_IDENT 42000 S1009 dan "Navnet '%-.64s' er for langt" nla "Naam voor herkenning '%-.64s' is te lang" eng "Identifier name '%-.100s' is too long" + jps "Identifier name '%-.100s' は長すぎます", est "Identifikaatori '%-.100s' nimi on liiga pikk" fre "Le nom de l'identificateur '%-.64s' est trop long" ger "Name des Bezeichners '%-.64s' ist zu lang" @@ -1387,6 +1433,7 @@ ER_DUP_FIELDNAME 42S21 S1009 dan "Feltnavnet '%-.64s' findes allerede" nla "Dubbele kolom naam '%-.64s'" eng "Duplicate column name '%-.64s'" + jps "'%-.64s' という column 名は重複してます", est "Kattuv tulba nimi '%-.64s'" fre "Nom du champ '%-.64s' d駛 utilis" ger "Doppelter Spaltenname vorhanden: '%-.64s'" @@ -1411,6 +1458,7 @@ ER_DUP_KEYNAME 42000 S1009 dan "Indeksnavnet '%-.64s' findes allerede" nla "Dubbele zoeksleutel naam '%-.64s'" eng "Duplicate key name '%-.64s'" + jps "'%-.64s' という key の名前は重複しています", est "Kattuv vtme nimi '%-.64s'" fre "Nom de clef '%-.64s' d駛 utilis" ger "Doppelter Name fr Schlssel (Key) vorhanden: '%-.64s'" @@ -1435,6 +1483,7 @@ ER_DUP_ENTRY 23000 S1009 dan "Ens v誡dier '%-.64s' for indeks %d" nla "Dubbele ingang '%-.64s' voor zoeksleutel %d" eng "Duplicate entry '%-.64s' for key %d" + jps "'%-.64s' は key %d において重複しています", est "Kattuv v蒿rtus '%-.64s' vtmele %d" fre "Duplicata du champ '%-.64s' pour la clef %d" ger "Doppelter Eintrag '%-.64s' fr Schlssel %d" @@ -1482,6 +1531,7 @@ ER_PARSE_ERROR 42000 dan "%s n誡 '%-.64s' p linje %d" nla "%s bij '%-.64s' in regel %d" eng "%s near '%-.80s' at line %d" + jps "%s : '%-.80s' 付近 : %d 行目", est "%s '%-.80s' ligidal real %d" fre "%s pr鑚 de '%-.64s' la ligne %d" ger "%s bei '%-.80s' in Zeile %d" @@ -1506,6 +1556,7 @@ ER_EMPTY_QUERY 42000 dan "Foresprgsel var tom" nla "Query was leeg" eng "Query was empty" + jps "Query が空です.", est "Thi p舐ing" fre "Query est vide" ger "Leere Abfrage" @@ -1530,6 +1581,7 @@ ER_NONUNIQ_TABLE 42000 S1009 dan "Tabellen/aliaset: '%-.64s' er ikke unikt" nla "Niet unieke waarde tabel/alias: '%-.64s'" eng "Not unique table/alias: '%-.64s'" + jps "'%-.64s' は一意の table/alias 名ではありません", est "Ei ole unikaalne tabel/alias '%-.64s'" fre "Table/alias: '%-.64s' non unique" ger "Tabellenname/Alias '%-.64s' nicht eindeutig" @@ -1577,6 +1629,7 @@ ER_MULTIPLE_PRI_KEY 42000 S1009 dan "Flere prim誡ngler specificeret" nla "Meerdere primaire zoeksleutels gedefinieerd" eng "Multiple primary key defined" + jps "複数の primary key が定義されました", est "Mitut primaarset vtit ei saa olla" fre "Plusieurs clefs primaires d馭inies" ger "Mehrfacher Prim舐schlssel (PRIMARY KEY) definiert" @@ -1601,6 +1654,7 @@ ER_TOO_MANY_KEYS 42000 S1009 dan "For mange ngler specificeret. Kun %d ngler m bruges" nla "Teveel zoeksleutels gedefinieerd. Maximaal zijn %d zoeksleutels toegestaan" eng "Too many keys specified; max %d keys allowed" + jps "key の指定が多すぎます. key は最大 %d までです", est "Liiga palju vtmeid. Maksimaalselt vib olla %d vtit" fre "Trop de clefs sont d馭inies. Maximum de %d clefs allou" ger "Zu viele Schlssel definiert. Maximal %d Schlssel erlaubt" @@ -1648,6 +1702,7 @@ ER_TOO_LONG_KEY 42000 S1009 dan "Specificeret ngle var for lang. Maksimal nglel誅gde er %d" nla "Gespecificeerde zoeksleutel was te lang. De maximale lengte is %d" eng "Specified key was too long; max key length is %d bytes" + jps "key が長すぎます. key の長さは最大 %d です", est "Vti on liiga pikk. Maksimaalne vtmepikkus on %d" fre "La cl est trop longue. Longueur maximale: %d" ger "Schlssel ist zu lang. Die maximale Schlssell舅ge betr臠t %d" @@ -1672,6 +1727,7 @@ ER_KEY_COLUMN_DOES_NOT_EXITS 42000 S1009 dan "Nglefeltet '%-.64s' eksisterer ikke i tabellen" nla "Zoeksleutel kolom '%-.64s' bestaat niet in tabel" eng "Key column '%-.64s' doesn't exist in table" + jps "Key column '%-.64s' がテーブルにありません.", est "Vtme tulp '%-.64s' puudub tabelis" fre "La cl '%-.64s' n'existe pas dans la table" ger "In der Tabelle gibt es keine Schlsselspalte '%-.64s'" @@ -1719,6 +1775,7 @@ ER_TOO_BIG_FIELDLENGTH 42000 S1009 dan "For stor feltl誅gde for kolonne '%-.64s' (maks = %d). Brug BLOB i stedet" nla "Te grote kolomlengte voor '%-.64s' (max = %d). Maak hiervoor gebruik van het type BLOB" eng "Column length too big for column '%-.64s' (max = %d); use BLOB instead" + jps "column '%-.64s' は,確保する column の大きさが多すぎます. (最大 %d まで). BLOB をかわりに使用してください.", est "Tulba '%-.64s' pikkus on liiga pikk (maksimaalne pikkus: %d). Kasuta BLOB v舁jatpi" fre "Champ '%-.64s' trop long (max = %d). Utilisez un BLOB" ger "Feldl舅ge fr Feld '%-.64s' zu gro゚ (maximal %d). BLOB-Feld verwenden!" @@ -1743,6 +1800,7 @@ ER_WRONG_AUTO_KEY 42000 S1009 dan "Der kan kun specificeres eet AUTO_INCREMENT-felt, og det skal v誡e indekseret" nla "Er kan slechts 1 autofield zijn en deze moet als zoeksleutel worden gedefinieerd." eng "Incorrect table definition; there can be only one auto column and it must be defined as a key" + jps "テーブルの定義が違います; there can be only one auto column and it must be defined as a key", est "Vigane tabelikirjeldus; Tabelis tohib olla ks auto_increment tpi tulp ning see peab olema defineeritud vtmena" fre "Un seul champ automatique est permis et il doit 黎re index" ger "Falsche Tabellendefinition. Es darf nur ein Auto-Feld geben und dieses muss als Schlssel definiert werden" @@ -1767,6 +1825,7 @@ ER_READY dan "%s: klar til tilslutninger" nla "%s: klaar voor verbindingen" eng "%s: ready for connections.\nVersion: '%s' socket: '%s' port: %d" + jps "%s: 準備完了", est "%s: ootab hendusi" fre "%s: Pr黎 pour des connections" ger "%-.64s: Bereit fr Verbindungen" @@ -1814,6 +1873,7 @@ ER_GOT_SIGNAL dan "%s: Fangede signal %d. Afslutter!!\n" nla "%s: Signaal %d. Systeem breekt af!\n" eng "%s: Got signal %d. Aborting!\n" + jps "%s: Got signal %d. 中断!\n", est "%s: sain signaali %d. Lpetan!\n" fre "%s: Re輹 le signal %d. Abandonne!\n" ger "%-.64s: Signal %d erhalten. Abbruch!\n" @@ -1838,6 +1898,7 @@ ER_SHUTDOWN_COMPLETE dan "%s: Server lukket\n" nla "%s: Afsluiten afgerond\n" eng "%s: Shutdown complete\n" + jps "%s: Shutdown 完了\n", est "%s: Lpp\n" fre "%s: Arr黎 du serveur termin饅n" ger "%-.64s: Heruntergefahren (shutdown)\n" @@ -1862,6 +1923,7 @@ ER_FORCING_CLOSE 08S01 dan "%s: Forceret nedlukning af tr蘚: %ld bruger: '%-.64s'\n" nla "%s: Afsluiten afgedwongen van thread %ld gebruiker: '%-.64s'\n" eng "%s: Forcing close of thread %ld user: '%-.32s'\n" + jps "%s: スレッド %ld 強制終了 user: '%-.64s'\n", est "%s: Sulgen juga lime %ld kasutaja: '%-.32s'\n" fre "%s: Arr黎 forc de la t稍he (thread) %ld utilisateur: '%-.64s'\n" ger "%s: Thread %ld zwangsweise beendet. Benutzer: '%-.32s'\n" @@ -1886,6 +1948,7 @@ ER_IPSOCK_ERROR 08S01 dan "Kan ikke oprette IP socket" nla "Kan IP-socket niet openen" eng "Can't create IP socket" + jps "IP socket が作れません", est "Ei suuda luua IP socketit" fre "Ne peut cr馥r la connection IP (socket)" ger "Kann IP-Socket nicht erzeugen" @@ -1910,6 +1973,7 @@ ER_NO_SUCH_INDEX 42S12 S1009 dan "Tabellen '%-.64s' har ikke den ngle, som blev brugt i CREATE INDEX. Genopret tabellen" nla "Tabel '%-.64s' heeft geen INDEX zoals deze gemaakt worden met CREATE INDEX. Maak de tabel opnieuw" eng "Table '%-.64s' has no index like the one used in CREATE INDEX; recreate the table" + jps "Table '%-.64s' はそのような index を持っていません(CREATE INDEX 実行時に指定されていません). テーブルを作り直してください", est "Tabelil '%-.64s' puuduvad vtmed. Loo tabel uuesti" fre "La table '%-.64s' n'a pas d'index comme celle utilis馥 dans CREATE INDEX. Recr馥z la table" ger "Tabelle '%-.64s' besitzt keinen wie den in CREATE INDEX verwendeten Index. Index neu anlegen" @@ -1981,6 +2045,7 @@ ER_TEXTFILE_NOT_READABLE dan "Filen '%-.64s' skal v誡e i database-folderen og kunne l誑es af alle" nla "Het bestand '%-.64s' dient in de database directory voor the komen of leesbaar voor iedereen te zijn." eng "The file '%-.64s' must be in the database directory or be readable by all" + jps "ファイル '%-.64s' は databse の directory にあるか全てのユーザーが読めるように許可されていなければなりません.", est "Fail '%-.64s' peab asuma andmebaasi kataloogis vi olema kigile loetav" fre "Le fichier '%-.64s' doit 黎re dans le r駱ertoire de la base et lisible par tous" ger "Datei '%-.64s' muss im Datenbank-Verzeichnis vorhanden und lesbar fr alle sein" @@ -2005,6 +2070,7 @@ ER_FILE_EXISTS_ERROR dan "Filen '%-.64s' eksisterer allerede" nla "Het bestand '%-.64s' bestaat reeds" eng "File '%-.80s' already exists" + jps "File '%-.64s' は既に存在します", est "Fail '%-.80s' juba eksisteerib" fre "Le fichier '%-.64s' existe d駛" ger "Datei '%-.64s' bereits vorhanden" @@ -2029,6 +2095,7 @@ ER_LOAD_INFO dan "Poster: %ld Fjernet: %ld Sprunget over: %ld Advarsler: %ld" nla "Records: %ld Verwijderd: %ld Overgeslagen: %ld Waarschuwingen: %ld" eng "Records: %ld Deleted: %ld Skipped: %ld Warnings: %ld" + jps "レコード数: %ld 削除: %ld Skipped: %ld Warnings: %ld", est "Kirjeid: %ld Kustutatud: %ld Vahele j臚tud: %ld Hoiatusi: %ld" fre "Enregistrements: %ld Effac駸: %ld Non trait駸: %ld Avertissements: %ld" ger "Datens舩ze: %ld Gelscht: %ld Ausgelassen: %ld Warnungen: %ld" @@ -2053,6 +2120,7 @@ ER_ALTER_INFO dan "Poster: %ld Ens: %ld" nla "Records: %ld Dubbel: %ld" eng "Records: %ld Duplicates: %ld" + jps "レコード数: %ld 重複: %ld", est "Kirjeid: %ld Kattuvaid: %ld" fre "Enregistrements: %ld Doublons: %ld" ger "Datens舩ze: %ld Duplikate: %ld" @@ -2101,6 +2169,7 @@ ER_CANT_REMOVE_ALL_FIELDS 42000 dan "Man kan ikke slette alle felter med ALTER TABLE. Brug DROP TABLE i stedet." nla "Het is niet mogelijk alle velden te verwijderen met ALTER TABLE. Gebruik a.u.b. DROP TABLE hiervoor!" eng "You can't delete all columns with ALTER TABLE; use DROP TABLE instead" + jps "ALTER TABLE で全ての column は削除できません. DROP TABLE を使用してください", est "ALTER TABLE kasutades ei saa kustutada kiki tulpasid. Kustuta tabel DROP TABLE abil" fre "Vous ne pouvez effacer tous les champs avec ALTER TABLE. Utilisez DROP TABLE" ger "Mit ALTER TABLE knnen nicht alle Felder auf einmal gelscht werden. Dafr DROP TABLE verwenden" @@ -2125,6 +2194,7 @@ ER_CANT_DROP_FIELD_OR_KEY 42000 dan "Kan ikke udfre DROP '%-.64s'. Undersg om feltet/nglen eksisterer." nla "Kan '%-.64s' niet weggooien. Controleer of het veld of de zoeksleutel daadwerkelijk bestaat." eng "Can't DROP '%-.64s'; check that column/key exists" + jps "'%-.64s' を破棄できませんでした; check that column/key exists", est "Ei suuda kustutada '%-.64s'. Kontrolli kas tulp/vti eksisteerib" fre "Ne peut effacer (DROP) '%-.64s'. V駻ifiez s'il existe" ger "Kann '%-.64s' nicht lschen. Existiert das Feld / der Schlssel?" @@ -2149,6 +2219,7 @@ ER_INSERT_INFO dan "Poster: %ld Ens: %ld Advarsler: %ld" nla "Records: %ld Dubbel: %ld Waarschuwing: %ld" eng "Records: %ld Duplicates: %ld Warnings: %ld" + jps "レコード数: %ld 重複数: %ld Warnings: %ld", est "Kirjeid: %ld Kattuvaid: %ld Hoiatusi: %ld" fre "Enregistrements: %ld Doublons: %ld Avertissements: %ld" ger "Datens舩ze: %ld Duplikate: %ld Warnungen: %ld" @@ -2179,6 +2250,7 @@ ER_NO_SUCH_THREAD dan "Ukendt tr蘚 id: %lu" nla "Onbekend thread id: %lu" eng "Unknown thread id: %lu" + jps "thread id: %lu はありません", est "Tundmatu lim: %lu" fre "Num駻o de t稍he inconnu: %lu" ger "Unbekannte Thread-ID: %lu" @@ -2203,6 +2275,7 @@ ER_KILL_DENIED_ERROR dan "Du er ikke ejer af tr蘚en %lu" nla "U bent geen bezitter van thread %lu" eng "You are not owner of thread %lu" + jps "thread %lu のオーナーではありません", est "Ei ole lime %lu omanik" fre "Vous n'黎es pas propri騁aire de la t稍he no: %lu" ger "Sie sind nicht Eigentmer von Thread %lu" @@ -2296,6 +2369,7 @@ ER_TABLE_NOT_LOCKED_FOR_WRITE dan "Tabellen '%-.64s' var l蚶t med READ l蚶 og kan ikke opdateres" nla "Tabel '%-.64s' was gelocked met een lock om te lezen. Derhalve kunnen geen wijzigingen worden opgeslagen." eng "Table '%-.64s' was locked with a READ lock and can't be updated" + jps "Table '%-.64s' は READ lock になっていて、更新はできません", est "Tabel '%-.64s' on lukustatud READ lukuga ning ei ole muudetav" fre "Table '%-.64s' verrouill馥 lecture (READ): modification impossible" ger "Tabelle '%-.64s' ist mit Lesesperre versehen und kann nicht aktualisiert werden" @@ -2320,6 +2394,7 @@ ER_TABLE_NOT_LOCKED dan "Tabellen '%-.64s' var ikke l蚶t med LOCK TABLES" nla "Tabel '%-.64s' was niet gelocked met LOCK TABLES" eng "Table '%-.64s' was not locked with LOCK TABLES" + jps "Table '%-.64s' は LOCK TABLES によってロックされていません", est "Tabel '%-.64s' ei ole lukustatud k舖uga LOCK TABLES" fre "Table '%-.64s' non verrouill馥: utilisez LOCK TABLES" ger "Tabelle '%-.64s' wurde nicht mit LOCK TABLES gesperrt" @@ -2368,6 +2443,7 @@ ER_WRONG_DB_NAME 42000 dan "Ugyldigt database navn '%-.64s'" nla "Databasenaam '%-.64s' is niet getoegestaan" eng "Incorrect database name '%-.100s'" + jps "指定した database 名 '%-.100s' が間違っています", est "Vigane andmebaasi nimi '%-.100s'" fre "Nom de base de donn馥 ill馮al: '%-.64s'" ger "Unerlaubter Datenbankname '%-.64s'" @@ -2392,6 +2468,7 @@ ER_WRONG_TABLE_NAME 42000 dan "Ugyldigt tabel navn '%-.64s'" nla "Niet toegestane tabelnaam '%-.64s'" eng "Incorrect table name '%-.100s'" + jps "指定した table 名 '%-.100s' はまちがっています", est "Vigane tabeli nimi '%-.100s'" fre "Nom de table ill馮al: '%-.64s'" ger "Unerlaubter Tabellenname '%-.64s'" @@ -2620,6 +2697,7 @@ ER_TABLE_MUST_HAVE_COLUMNS 42000 dan "En tabel skal have mindst een kolonne" nla "Een tabel moet minstens 1 kolom bevatten" eng "A table must have at least 1 column" + jps "テーブルは最低 1 個の column が必要です", est "Tabelis peab olema v臧emalt ks tulp" fre "Une table doit comporter au moins une colonne" ger "Eine Tabelle mu゚ mindestens 1 Spalte besitzen" @@ -2641,6 +2719,7 @@ ER_RECORD_FILE_FULL dan "Tabellen '%-.64s' er fuld" nla "De tabel '%-.64s' is vol" eng "The table '%-.64s' is full" + jps "table '%-.64s' はいっぱいです", est "Tabel '%-.64s' on t臺s" fre "La table '%-.64s' est pleine" ger "Tabelle '%-.64s' ist voll" @@ -2662,6 +2741,7 @@ ER_UNKNOWN_CHARACTER_SET 42000 dan "Ukendt tegns誥: '%-.64s'" nla "Onbekende character set: '%-.64s'" eng "Unknown character set: '%-.64s'" + jps "character set '%-.64s' はサポートしていません", est "Vigane kooditabel '%-.64s'" fre "Jeu de caract鑽es inconnu: '%-.64s'" ger "Unbekannter Zeichensatz: '%-.64s'" @@ -2683,6 +2763,7 @@ ER_TOO_MANY_TABLES dan "For mange tabeller. MySQL kan kun bruge %d tabeller i et join" nla "Teveel tabellen. MySQL kan slechts %d tabellen in een join bevatten" eng "Too many tables; MySQL can only use %d tables in a join" + jps "テーブルが多すぎます; MySQL can only use %d tables in a join", est "Liiga palju tabeleid. MySQL suudab JOINiga hendada kuni %d tabelit" fre "Trop de tables. MySQL ne peut utiliser que %d tables dans un JOIN" ger "Zu viele Tabellen. MySQL kann in einem Join maximal %d Tabellen verwenden" @@ -2704,6 +2785,7 @@ ER_TOO_MANY_FIELDS dan "For mange felter" nla "Te veel velden" eng "Too many columns" + jps "column が多すぎます", est "Liiga palju tulpasid" fre "Trop de champs" ger "Zu viele Spalten" @@ -2725,6 +2807,7 @@ ER_TOO_BIG_ROWSIZE 42000 dan "For store poster. Max post strrelse, uden BLOB's, er %d. Du m lave nogle felter til BLOB's" nla "Rij-grootte is groter dan toegestaan. Maximale rij grootte, blobs niet meegeteld, is %d. U dient sommige velden in blobs te veranderen." eng "Row size too large. The maximum row size for the used table type, not counting BLOBs, is %ld. You have to change some columns to TEXT or BLOBs" + jps "row size が大きすぎます. BLOB を含まない場合の row size の最大は %d です. いくつかの field を BLOB に変えてください.", est "Liiga pikk kirje. Kirje maksimumpikkus arvestamata BLOB-tpi v舁ju on %d. Muuda mned v舁jad BLOB-tpi v舁jadeks" fre "Ligne trop grande. Le taille maximale d'une ligne, sauf les BLOBs, est %d. Changez le type de quelques colonnes en BLOB" ger "Zeilenl舅ge zu gro゚. Die maximale Spaltenl舅ge fr den verwendeten Tabellentyp (ohne BLOB-Felder) betr臠t %d. Einige Felder mssen in BLOB oder TEXT umgewandelt werden" @@ -2746,6 +2829,7 @@ ER_STACK_OVERRUN dan "Thread stack brugt: Brugt: %ld af en %ld stak. Brug 'mysqld -O thread_stack=#' for at allokere en strre stak om ndvendigt" nla "Thread stapel overrun: Gebruikte: %ld van een %ld stack. Gebruik 'mysqld -O thread_stack=#' om een grotere stapel te definieren (indien noodzakelijk)." eng "Thread stack overrun: Used: %ld of a %ld stack. Use 'mysqld -O thread_stack=#' to specify a bigger stack if needed" + jps "Thread stack overrun: Used: %ld of a %ld stack. スタック領域を多くとりたい場合、'mysqld -O thread_stack=#' と指定してください", fre "D饕ordement de la pile des t稍hes (Thread stack). Utilis馥s: %ld pour une pile de %ld. Essayez 'mysqld -O thread_stack=#' pour indiquer une plus grande valeur" ger "Thread-Stack-ワberlauf. Benutzt: %ld von %ld Stack. 'mysqld -O thread_stack=#' verwenen, um notfalls einen gr゚eren Stack anzulegen" greek "Stack overrun thread: Used: %ld of a %ld stack. ミ碵碎硴 銛鴈鱧゚ 'mysqld -O thread_stack=#' 肓 ゚襁 ン 裙硴褥 stack 硼 裨ワ趺硅" @@ -2785,6 +2869,7 @@ ER_NULL_COLUMN_IN_INDEX 42000 dan "Kolonne '%-.32s' bruges som UNIQUE eller INDEX men er ikke defineret som NOT NULL" nla "Kolom '%-.64s' wordt gebruikt met UNIQUE of INDEX maar is niet gedefinieerd als NOT NULL" eng "Column '%-.64s' is used with UNIQUE or INDEX but is not defined as NOT NULL" + jps "Column '%-.64s' が UNIQUE か INDEX で使用されました. このカラムは NOT NULL と定義されていません.", est "Tulp '%-.64s' on kasutusel indeksina, kuid ei ole m蒿ratletud kui NOT NULL" fre "La colonne '%-.32s' fait partie d'un index UNIQUE ou INDEX mais n'est pas d馭inie comme NOT NULL" ger "Spalte '%-.64s' wurde mit UNIQUE oder INDEX benutzt, ist aber nicht als NOT NULL definiert" @@ -2809,6 +2894,7 @@ ER_CANT_FIND_UDF dan "Kan ikke l誑e funktionen '%-.64s'" nla "Kan functie '%-.64s' niet laden" eng "Can't load function '%-.64s'" + jps "function '%-.64s' を ロードできません", est "Ei suuda avada funktsiooni '%-.64s'" fre "Imposible de charger la fonction '%-.64s'" ger "Kann Funktion '%-.64s' nicht laden" @@ -2830,6 +2916,7 @@ ER_CANT_INITIALIZE_UDF dan "Kan ikke starte funktionen '%-.64s'; %-.80s" nla "Kan functie '%-.64s' niet initialiseren; %-.80s" eng "Can't initialize function '%-.64s'; %-.80s" + jps "function '%-.64s' を初期化できません; %-.80s", est "Ei suuda algv蒿rtustada funktsiooni '%-.64s'; %-.80s" fre "Impossible d'initialiser la fonction '%-.64s'; %-.80s" ger "Kann Funktion '%-.64s' nicht initialisieren: %-.80s" @@ -2851,6 +2938,7 @@ ER_UDF_NO_PATHS dan "Angivelse af sti ikke tilladt for delt bibliotek" nla "Geen pad toegestaan voor shared library" eng "No paths allowed for shared library" + jps "shared library へのパスが通っていません", est "Teegi nimes ei tohi olla kataloogi" fre "Chemin interdit pour les biblioth鑷ues partag馥s" ger "Keine Pfade gestattet fr Shared Library" @@ -2872,6 +2960,7 @@ ER_UDF_EXISTS dan "Funktionen '%-.64s' findes allerede" nla "Functie '%-.64s' bestaat reeds" eng "Function '%-.64s' already exists" + jps "Function '%-.64s' は既に定義されています", est "Funktsioon '%-.64s' juba eksisteerib" fre "La fonction '%-.64s' existe d駛" ger "Funktion '%-.64s' existiert schon" @@ -2893,6 +2982,7 @@ ER_CANT_OPEN_LIBRARY dan "Kan ikke 蘆ne delt bibliotek '%-.64s' (errno: %d %s)" nla "Kan shared library '%-.64s' niet openen (Errcode: %d %s)" eng "Can't open shared library '%-.64s' (errno: %d %-.64s)" + jps "shared library '%-.64s' を開く事ができません (errno: %d %s)", est "Ei suuda avada jagatud teeki '%-.64s' (veakood: %d %-.64s)" fre "Impossible d'ouvrir la biblioth鑷ue partag馥 '%-.64s' (errno: %d %s)" ger "Kann Shared Library '%-.64s' nicht ffnen (Fehler: %d %-.64s)" @@ -2917,6 +3007,7 @@ ER_CANT_FIND_DL_ENTRY dan "Kan ikke finde funktionen '%-.64s' i bibliotek'" nla "Kan functie '%-.64s' niet in library vinden" eng "Can't find function '%-.64s' in library'" + jps "function '%-.64s' をライブラリー中に見付ける事ができません", est "Ei leia funktsiooni '%-.64s' antud teegis" fre "Impossible de trouver la fonction '%-.64s' dans la biblioth鑷ue'" ger "Kann Funktion '%-.64s' in der Library nicht finden" @@ -2938,6 +3029,7 @@ ER_FUNCTION_NOT_DEFINED dan "Funktionen '%-.64s' er ikke defineret" nla "Functie '%-.64s' is niet gedefinieerd" eng "Function '%-.64s' is not defined" + jps "Function '%-.64s' は定義されていません", est "Funktsioon '%-.64s' ei ole defineeritud" fre "La fonction '%-.64s' n'est pas d馭inie" ger "Funktion '%-.64s' ist nicht definiert" @@ -2959,6 +3051,7 @@ ER_HOST_IS_BLOCKED dan "V誡ten er blokeret p grund af mange fejlforesprgsler. L蚶 op med 'mysqladmin flush-hosts'" nla "Host '%-.64s' is geblokkeeerd vanwege te veel verbindings fouten. Deblokkeer met 'mysqladmin flush-hosts'" eng "Host '%-.64s' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'" + jps "Host '%-.64s' は many connection error のため、拒否されました. 'mysqladmin flush-hosts' で解除してください", est "Masin '%-.64s' on blokeeritud hulgaliste hendusvigade tttu. Blokeeringu saab thistada 'mysqladmin flush-hosts' k舖uga" fre "L'hte '%-.64s' est bloqu cause d'un trop grand nombre d'erreur de connection. D饕loquer le par 'mysqladmin flush-hosts'" ger "Host '%-.64s' blockiert wegen zu vieler Verbindungsfehler. Aufheben der Blockierung mit 'mysqladmin flush-hosts'" @@ -2979,6 +3072,7 @@ ER_HOST_NOT_PRIVILEGED dan "V誡ten '%-.64s' kan ikke tilkoble denne MySQL-server" nla "Het is host '%-.64s' is niet toegestaan verbinding te maken met deze MySQL server" eng "Host '%-.64s' is not allowed to connect to this MySQL server" + jps "Host '%-.64s' は MySQL server に接続を許可されていません", est "Masinal '%-.64s' puudub ligip蒿s sellele MySQL serverile" fre "Le hte '%-.64s' n'est pas authoris se connecter ce serveur MySQL" ger "Host '%-.64s' hat keine Berechtigung, sich mit diesem MySQL-Server zu verbinden" @@ -2999,6 +3093,7 @@ ER_PASSWORD_ANONYMOUS_USER 42000 dan "Du bruger MySQL som anonym bruger. Anonyme brugere m ikke 誅dre adgangskoder" nla "U gebruikt MySQL als anonieme gebruiker en deze mogen geen wachtwoorden wijzigen" eng "You are using MySQL as an anonymous user and anonymous users are not allowed to change passwords" + jps "MySQL を anonymous users で使用している状態では、パスワードの変更はできません", est "Te kasutate MySQL-i anonmse kasutajana, kelledel pole parooli muutmise igust" fre "Vous utilisez un utilisateur anonyme et les utilisateurs anonymes ne sont pas autoris駸 changer les mots de passe" ger "Sie benutzen MySQL als anonymer Benutzer und drfen daher keine Passwrter 舅dern" @@ -3019,6 +3114,7 @@ ER_PASSWORD_NOT_ALLOWED 42000 dan "Du skal have tilladelse til at opdatere tabeller i MySQL databasen for at 誅dre andres adgangskoder" nla "U moet tabel update priveleges hebben in de mysql database om wachtwoorden voor anderen te mogen wijzigen" eng "You must have privileges to update tables in the mysql database to be able to change passwords for others" + jps "他のユーザーのパスワードを変更するためには, mysql データベースに対して update の許可がなければなりません.", est "Teiste paroolide muutmiseks on nutav tabelite muutmisigus 'mysql' andmebaasis" fre "Vous devez avoir le privil鑒e update sur les tables de la base de donn馥 mysql pour pouvoir changer les mots de passe des autres" ger "Sie bentigen die Berechtigung zum Aktualisieren von Tabellen in der Datenbank 'mysql', um die Passwrter anderer Benutzer 舅dern zu knnen" @@ -3058,6 +3154,7 @@ ER_UPDATE_INFO dan "Poster fundet: %ld ニndret: %ld Advarsler: %ld" nla "Passende rijen: %ld Gewijzigd: %ld Waarschuwingen: %ld" eng "Rows matched: %ld Changed: %ld Warnings: %ld" + jps "一致数(Rows matched): %ld 変更: %ld Warnings: %ld", est "Sobinud kirjeid: %ld Muudetud: %ld Hoiatusi: %ld" fre "Enregistrements correspondants: %ld Modifi駸: %ld Warnings: %ld" ger "Datens舩ze gefunden: %ld Ge舅dert: %ld Warnungen: %ld" @@ -3077,6 +3174,7 @@ ER_CANT_CREATE_THREAD dan "Kan ikke danne en ny tr蘚 (fejl nr. %d). Hvis computeren ikke er lbet tr for hukommelse, kan du se i brugervejledningen for en mulig operativ-system - afh誅gig fejl" nla "Kan geen nieuwe thread aanmaken (Errcode: %d). Indien er geen tekort aan geheugen is kunt u de handleiding consulteren over een mogelijke OS afhankelijke fout" eng "Can't create a new thread (errno %d); if you are not out of available memory, you can consult the manual for a possible OS-dependent bug" + jps "新規にスレッドが作れませんでした (errno %d). もし最大使用許可メモリー数を越えていないのにエラーが発生しているなら, マニュアルの中から 'possible OS-dependent bug' という文字を探してくみてださい.", est "Ei suuda luua uut lime (veakood %d). Kui m舁u ei ole otsas, on ten與liselt tegemist operatsioonissteemispetsiifilise veaga" fre "Impossible de cr馥r une nouvelle t稍he (errno %d). S'il reste de la m駑oire libre, consultez le manual pour trouver un 騅entuel bug d駱endant de l'OS" ger "Kann keinen neuen Thread erzeugen (Fehler: %d). Sollte noch Speicher verfgbar sein, bitte im Handbuch wegen mglicher Fehler im Betriebssystem nachschlagen" @@ -3138,6 +3236,7 @@ ER_INVALID_USE_OF_NULL 22004 dan "Forkert brug af nulv誡di (NULL)" nla "Foutief gebruik van de NULL waarde" eng "Invalid use of NULL value" + jps "NULL 値の使用方法が不適切です", est "NULL v蒿rtuse v蒿rkasutus" fre "Utilisation incorrecte de la valeur NULL" ger "Unerlaubte Verwendung eines NULL-Werts" @@ -3193,6 +3292,7 @@ ER_NONEXISTING_GRANT 42000 dan "Denne tilladelse findes ikke for brugeren '%-.32s' p v誡t '%-.64s'" nla "Deze toegang (GRANT) is niet toegekend voor gebruiker '%-.32s' op host '%-.64s'" eng "There is no such grant defined for user '%-.32s' on host '%-.64s'" + jps "ユーザー '%-.32s' (ホスト '%-.64s' のユーザー) は許可されていません", est "Sellist igust ei ole defineeritud kasutajale '%-.32s' masinast '%-.64s'" fre "Un tel droit n'est pas d馭ini pour l'utilisateur '%-.32s' sur l'hte '%-.64s'" ger "Fr Benutzer '%-.32s' auf Host '%-.64s' gibt es keine solche Berechtigung" @@ -3212,6 +3312,7 @@ ER_TABLEACCESS_DENIED_ERROR 42000 dan "%-.16s-kommandoen er ikke tilladt for brugeren '%-.32s'@'%-.64s' for tabellen '%-.64s'" nla "%-.16s commando geweigerd voor gebruiker: '%-.32s'@'%-.64s' voor tabel '%-.64s'" eng "%-.16s command denied to user '%-.32s'@'%-.64s' for table '%-.64s'" + jps "コマンド %-.16s は ユーザー '%-.32s'@'%-.64s' ,テーブル '%-.64s' に対して許可されていません", est "%-.16s k舖k ei ole lubatud kasutajale '%-.32s'@'%-.64s' tabelis '%-.64s'" fre "La commande '%-.16s' est interdite l'utilisateur: '%-.32s'@'@%-.64s' sur la table '%-.64s'" ger "%-.16s Befehl nicht erlaubt fr Benutzer '%-.32s'@'%-.64s' und fr Tabelle '%-.64s'" @@ -3231,6 +3332,7 @@ ER_COLUMNACCESS_DENIED_ERROR 42000 dan "%-.16s-kommandoen er ikke tilladt for brugeren '%-.32s'@'%-.64s' for kolonne '%-.64s' in tabellen '%-.64s'" nla "%-.16s commando geweigerd voor gebruiker: '%-.32s'@'%-.64s' voor kolom '%-.64s' in tabel '%-.64s'" eng "%-.16s command denied to user '%-.32s'@'%-.64s' for column '%-.64s' in table '%-.64s'" + jps "コマンド %-.16s は ユーザー '%-.32s'@'%-.64s'\n カラム '%-.64s' テーブル '%-.64s' に対して許可されていません", est "%-.16s k舖k ei ole lubatud kasutajale '%-.32s'@'%-.64s' tulbale '%-.64s' tabelis '%-.64s'" fre "La commande '%-.16s' est interdite l'utilisateur: '%-.32s'@'@%-.64s' sur la colonne '%-.64s' de la table '%-.64s'" ger "%-.16s Befehl nicht erlaubt fr Benutzer '%-.32s'@'%-.64s' und Spalte '%-.64s' in Tabelle '%-.64s'" diff --git a/sql/slave.cc b/sql/slave.cc index 0bcc1b7e852..5332dbf9c5b 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1418,7 +1418,12 @@ not always make sense; please check the manual before using it)."; values of these 2 are never used (new connections don't use them). We don't test equality of global collation_database either as it's is going to be deprecated (made read-only) in 4.1 very soon. + We don't do it for <3.23.57 because masters <3.23.50 hang on + SELECT @@unknown_var (BUG#7965 - see changelog of 3.23.50). */ + if (strncmp(mi->rli.relay_log.description_event_for_queue->server_version, + "3.23.57",7) < 0) + goto err; if (!mysql_real_query(mysql, "SELECT @@GLOBAL.COLLATION_SERVER", 32) && (master_res= mysql_store_result(mysql))) { @@ -1455,6 +1460,7 @@ be equal for replication to work"; mysql_free_result(master_res); } +err: if (errmsg) { sql_print_error(errmsg); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 48855892567..fc41643e8d4 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1853,8 +1853,8 @@ int simple_open_n_lock_tables(THD *thd, TABLE_LIST *tables) bool open_and_lock_tables(THD *thd, TABLE_LIST *tables) { - DBUG_ENTER("open_and_lock_tables"); uint counter; + DBUG_ENTER("open_and_lock_tables"); if (open_tables(thd, tables, &counter) || lock_tables(thd, tables, counter) || mysql_handle_derived(thd->lex, &mysql_derived_prepare) || @@ -1867,6 +1867,36 @@ bool open_and_lock_tables(THD *thd, TABLE_LIST *tables) /* + Open all tables in list and process derived tables + + SYNOPSIS + open_normal_and_derived_tables + thd - thread handler + tables - list of tables for open&locking + + RETURN + FALSE - ok + TRUE - error + + NOTE + This is to be used on prepare stage when you don't read any + data from the tables. +*/ + +bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables) +{ + uint counter; + DBUG_ENTER("open_normal_and_derived_tables"); + DBUG_ASSERT(!thd->fill_derived_tables()); + if (open_tables(thd, tables, &counter) || + mysql_handle_derived(thd->lex, &mysql_derived_prepare)) + DBUG_RETURN(TRUE); /* purecov: inspected */ + relink_tables_for_multidelete(thd); // Not really needed, but + DBUG_RETURN(0); +} + + +/* Let us propagate pointers to open tables from global table list to table lists for multi-delete */ @@ -2090,7 +2120,7 @@ find_field_in_table(THD *thd, TABLE_LIST *table_list, Field_translator *trans= table_list->field_translation; for (uint i= 0; i < num; i ++) { - if (strcmp(trans[i].name, name) == 0) + if (!my_strcasecmp(system_charset_info, trans[i].name, name)) { #ifndef NO_EMBEDDED_ACCESS_CHECKS if (check_grants_view && diff --git a/sql/sql_class.h b/sql/sql_class.h index a33dba023d7..f635aa62000 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -205,6 +205,7 @@ public: inline bool is_open() { return log_type != LOG_CLOSED; } inline char* get_index_fname() { return index_file_name;} inline char* get_log_fname() { return log_file_name; } + inline char* get_name() { return name; } inline pthread_mutex_t* get_log_lock() { return &LOCK_log; } inline IO_CACHE* get_log_file() { return &log_file; } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 495fa4a0bd1..2f6e74225fd 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -944,6 +944,7 @@ int yylex(void *arg, void *yythd) if ((thd->client_capabilities & CLIENT_MULTI_STATEMENTS) && (thd->command != COM_PREPARE)) { + lex->safe_to_cache_query= 0; lex->found_colon= (char*) lex->ptr; thd->server_status|= SERVER_MORE_RESULTS_EXISTS; lex->next_state= MY_LEX_END; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 9e4f6c1334c..a71b8148f8e 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -900,8 +900,12 @@ static bool mysql_test_insert(Prepared_statement *stmt, /* open temporary memory pool for temporary data allocated by derived tables & preparation procedure + Note that this is done without locks (should not be needed as we will not + access any data here) + If we would use locks, then we have to ensure we are not using + TL_WRITE_DELAYED as having two such locks can cause table corruption. */ - if (open_and_lock_tables(thd, table_list)) + if (open_normal_and_derived_tables(thd, table_list)) { DBUG_RETURN(TRUE); } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index edf950ce8d4..dba0b844de7 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7826,12 +7826,17 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, if (temp_pool_slot != MY_BIT_NONE) // we got a slot sprintf(filename, "%s_%lx_%i", tmp_file_prefix, current_pid, temp_pool_slot); - else // if we run out of slots or we are not using tempool + else + { + /* if we run out of slots or we are not using tempool */ sprintf(filename,"%s%lx_%lx_%x",tmp_file_prefix,current_pid, thd->thread_id, thd->tmp_table++); + } - if (lower_case_table_names) - my_casedn_str(files_charset_info, path); + /* + No need for change table name to lower case as we are only creating + MyISAM or HEAP tables here + */ sprintf(path, "%s%s", mysql_tmpdir, filename); if (group) @@ -10424,15 +10429,24 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, } else { - select->quick->head->file->ha_index_end(); - /* - We have verified above that select->quick is not - index_merge quick select. - */ - select->quick->index= new_ref_key; - select->quick->init(); + /* + The range optimizer constructed QUICK_RANGE for ref_key, and + we want to use instead new_ref_key as the index. We can't + just change the index of the quick select, because this may + result in an incosistent QUICK_SELECT object. Below we + create a new QUICK_SELECT from scratch so that all its + parameres are set correctly by the range optimizer. + */ + key_map new_ref_key_map; + new_ref_key_map.clear_all(); /* Force the creation of quick select */ + new_ref_key_map.set_bit(new_ref_key); /* only for new_ref_key. */ + + if (select->test_quick_select(tab->join->thd, new_ref_key_map, 0, + (tab->join->select_options & OPTION_FOUND_ROWS) ? + HA_POS_ERROR : tab->join->unit->select_limit_cnt) <= 0) + DBUG_RETURN(0); } - ref_key= new_ref_key; + ref_key= new_ref_key; } } /* Check if we get the rows in requested sorted order by using the key */ diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 2aa8a67fbab..c7b4b61ca33 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1534,25 +1534,6 @@ static bool show_status_array(THD *thd, const char *wild, } -bool mysqld_show(THD *thd, const char *wild, show_var_st *variables, - enum enum_var_type value_type, - pthread_mutex_t *mutex, - struct system_status_var *status_var, TABLE *table) -{ - DBUG_ENTER("mysqld_show"); - ha_update_statistics(); /* Export engines statistics */ - pthread_mutex_lock(mutex); - if (show_status_array(thd, wild, variables, value_type, status_var, "", table)) - goto err; - pthread_mutex_unlock(mutex); - DBUG_RETURN(FALSE); - - err: - pthread_mutex_unlock(mutex); - DBUG_RETURN(TRUE); -} - - /* collect status for all running threads */ void calc_sum_of_all_status(STATUS_VAR *to) @@ -2874,10 +2855,13 @@ int fill_open_tables(THD *thd, TABLE_LIST *tables, COND *cond) int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond) { DBUG_ENTER("fill_variables"); + int res= 0; LEX *lex= thd->lex; const char *wild= lex->wild ? lex->wild->ptr() : NullS; - int res= mysqld_show(thd, wild, init_vars, lex->option_type, - &LOCK_global_system_variables, 0, tables->table); + pthread_mutex_lock(&LOCK_global_system_variables); + res= show_status_array(thd, wild, init_vars, + lex->option_type, 0, "", tables->table); + pthread_mutex_unlock(&LOCK_global_system_variables); DBUG_RETURN(res); } @@ -2889,17 +2873,14 @@ int fill_status(THD *thd, TABLE_LIST *tables, COND *cond) const char *wild= lex->wild ? lex->wild->ptr() : NullS; int res= 0; STATUS_VAR tmp; - + ha_update_statistics(); /* Export engines statistics */ + pthread_mutex_lock(&LOCK_status); if (lex->option_type == OPT_GLOBAL) - { - pthread_mutex_lock(&LOCK_status); calc_sum_of_all_status(&tmp); - } - res= mysqld_show(thd, wild, status_vars, OPT_GLOBAL, &LOCK_status, - (lex->option_type == OPT_GLOBAL ? - &tmp: &thd->status_var), tables->table); - if (lex->option_type == OPT_GLOBAL) - pthread_mutex_unlock(&LOCK_status); + res= show_status_array(thd, wild, status_vars, OPT_GLOBAL, + (lex->option_type == OPT_GLOBAL ? + &tmp: &thd->status_var), "",tables->table); + pthread_mutex_unlock(&LOCK_status); DBUG_RETURN(res); } diff --git a/sql/sql_union.cc b/sql/sql_union.cc index ce84be47243..0a91eb4c0e1 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -478,11 +478,14 @@ bool st_select_lex_unit::exec() } res= sl->join->error; offset_limit_cnt= sl->offset_limit; - if (!res && union_result->flush()) + if (!res) { - examined_rows+= thd->examined_row_count; - thd->lex->current_select= lex_select_save; - DBUG_RETURN(TRUE); + examined_rows+= thd->examined_row_count; + if (union_result->flush()) + { + thd->lex->current_select= lex_select_save; + DBUG_RETURN(1); + } } } if (res) diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 533876b6718..e2c4b1289fd 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -948,11 +948,12 @@ frm_type_enum mysql_frm_type(char *path) { DBUG_RETURN(FRMTYPE_ERROR); } - length= my_read(file, (byte*) header, 10, MYF(MY_WME)); + length= my_read(file, (byte*) header, sizeof(header), MYF(MY_WME)); my_close(file, MYF(MY_WME)); if (length == (int) MY_FILE_ERROR) DBUG_RETURN(FRMTYPE_ERROR); - if (!strncmp(header, "TYPE=VIEW\n", 10)) + if (length < (int) sizeof(header) || + !strncmp(header, "TYPE=VIEW\n", sizeof(header))) DBUG_RETURN(FRMTYPE_VIEW); DBUG_RETURN(FRMTYPE_TABLE); // Is probably a .frm table } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 6b1456dfbd3..cc2443bd41b 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2793,7 +2793,7 @@ type: | YEAR_SYM opt_len field_options { $$=FIELD_TYPE_YEAR; } | DATE_SYM { $$=FIELD_TYPE_DATE; } | TIME_SYM { $$=FIELD_TYPE_TIME; } - | TIMESTAMP + | TIMESTAMP opt_len { if (YYTHD->variables.sql_mode & MODE_MAXDB) $$=FIELD_TYPE_DATETIME; @@ -2806,13 +2806,6 @@ type: $$=FIELD_TYPE_TIMESTAMP; } } - | TIMESTAMP '(' NUM ')' - { - LEX *lex= Lex; - lex->length= $3.str; - lex->type|= NOT_NULL_FLAG; - $$= FIELD_TYPE_TIMESTAMP; - } | DATETIME { $$=FIELD_TYPE_DATETIME; } | TINYBLOB { Lex->charset=&my_charset_bin; $$=FIELD_TYPE_TINY_BLOB; } diff --git a/sql/table.cc b/sql/table.cc index 97f17ea2417..a030da95db4 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -103,11 +103,11 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, O_RDONLY | O_SHARE, MYF(0))) < 0) - goto err_w_init; + goto err; error= 4; if (my_read(file,(byte*) head,64,MYF(MY_NABP))) - goto err_w_init; + goto err; if (memcmp(head, "TYPE=", 5) == 0) { @@ -116,9 +116,9 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, if (db_stat & NO_ERR_ON_NEW_FRM) DBUG_RETURN(5); - + file= -1; // caller can't process new .frm - goto err_w_init; + goto err; } share->blob_ptr_size= sizeof(char*); @@ -131,21 +131,21 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, share->path= strdup_root(&outparam->mem_root, name); outparam->alias= my_strdup(alias, MYF(MY_WME)); if (!share->table_name || !share->path || !outparam->alias) - goto err_not_open; + goto err; *fn_ext(share->table_name)='\0'; // Remove extension *fn_ext(share->path)='\0'; // Remove extension if (head[0] != (uchar) 254 || head[1] != 1 || (head[2] != FRM_VER && head[2] != FRM_VER+1 && ! (head[2] >= FRM_VER+3 && head[2] <= FRM_VER+4))) - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ new_field_pack_flag=head[27]; new_frm_ver= (head[2] - FRM_VER); field_pack_length= new_frm_ver < 2 ? 11 : 17; error=3; if (!(pos=get_form_pos(file,head,(TYPELIB*) 0))) - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ *fn_ext(index_file)='\0'; // Remove .frm extension share->frm_version= head[2]; @@ -166,6 +166,14 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, if (!share->table_charset) { /* unknown charset in head[38] or pre-3.23 frm */ + if (use_mb(default_charset_info)) + { + /* Warn that we may be changing the size of character columns */ + sql_print_warning("'%s' had no or invalid character set, " + "and default character set is multi-byte, " + "so character column sizes may have changed", + name); + } share->table_charset= default_charset_info; } share->db_record_offset= 1; @@ -181,7 +189,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, key_info_length= (uint) uint2korr(head+28); VOID(my_seek(file,(ulong) uint2korr(head+6),MY_SEEK_SET,MYF(0))); if (read_string(file,(gptr*) &disk_buff,key_info_length)) - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ if (disk_buff[0] & 0x80) { share->keys= keys= (disk_buff[1] << 7) | (disk_buff[0] & 0x7f); @@ -201,7 +209,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, n_length=keys*sizeof(KEY)+key_parts*sizeof(KEY_PART_INFO); if (!(keyinfo = (KEY*) alloc_root(&outparam->mem_root, n_length+uint2korr(disk_buff+4)))) - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ bzero((char*) keyinfo,n_length); outparam->key_info=keyinfo; key_part= my_reinterpret_cast(KEY_PART_INFO*) (keyinfo+keys); @@ -210,7 +218,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, ulong *rec_per_key; if (!(rec_per_key= (ulong*) alloc_root(&outparam->mem_root, sizeof(ulong*)*key_parts))) - goto err_not_open; + goto err; for (i=0 ; i < keys ; i++, keyinfo++) { @@ -279,7 +287,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, /* Allocate handler */ if (!(outparam->file= get_new_handler(outparam, share->db_type))) - goto err_not_open; + goto err; error=4; outparam->reginfo.lock_type= TL_UNLOCK; @@ -296,14 +304,14 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, share->rec_buff_length= rec_buff_length; if (!(record= (char *) alloc_root(&outparam->mem_root, rec_buff_length * records))) - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ share->default_values= record; if (my_pread(file,(byte*) record, (uint) share->reclength, (ulong) (uint2korr(head+6)+ ((uint2korr(head+14) == 0xffff ? uint4korr(head+47) : uint2korr(head+14)))), MYF(MY_NABP))) - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ if (records == 1) { @@ -332,12 +340,13 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, } #endif VOID(my_seek(file,pos,MY_SEEK_SET,MYF(0))); - if (my_read(file,(byte*) head,288,MYF(MY_NABP))) goto err_not_open; + if (my_read(file,(byte*) head,288,MYF(MY_NABP))) + goto err; if (crypted) { crypted->decode((char*) head+256,288-256); if (sint2korr(head+284) != 0) // Should be 0 - goto err_not_open; // Wrong password + goto err; // Wrong password } share->fields= uint2korr(head+258); @@ -359,13 +368,13 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, (share->fields+interval_parts+ keys+3)*sizeof(my_string)+ (n_length+int_length+com_length))))) - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ outparam->field=field_ptr; read_length=(uint) (share->fields * field_pack_length + pos+ (uint) (n_length+int_length+com_length)); if (read_string(file,(gptr*) &disk_buff,read_length)) - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ if (crypted) { crypted->decode((char*) disk_buff,read_length); @@ -398,7 +407,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, uint count= (uint) (interval->count + 1) * sizeof(uint); if (!(interval->type_lengths= (uint *) alloc_root(&outparam->mem_root, count))) - goto err_not_open; + goto err; for (count= 0; count < interval->count; count++) interval->type_lengths[count]= strlen(interval->type_names[count]); interval->type_lengths[count]= 0; @@ -459,7 +468,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, charset= &my_charset_bin; #else error= 4; // unsupported field type - goto err_not_open; + goto err; #endif } else @@ -470,7 +479,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, { error= 5; // Unknown or unavailable charset errarg= (int) strpos[14]; - goto err_not_open; + goto err; } } if (!comment_length) @@ -543,7 +552,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, if (!reg_field) // Not supported field type { error= 4; - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ } reg_field->comment=comment; if (field_type == FIELD_TYPE_BIT) @@ -616,7 +625,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, (uint) key_part->length); #ifdef EXTRA_DEBUG if (key_part->fieldnr > share->fields) - goto err_not_open; // sanity check + goto err; // sanity check #endif if (key_part->fieldnr) { // Should always be true ! @@ -767,7 +776,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, if (!(share->blob_field= save= (uint*) alloc_root(&outparam->mem_root, (uint) (share->blob_fields* sizeof(uint))))) - goto err_not_open; + goto err; for (i=0, ptr= outparam->field ; *ptr ; ptr++, i++) { if ((*ptr)->flags & BLOB_FLAG) @@ -779,25 +788,25 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, error=2; if (db_stat) { - int err; + int ha_err; unpack_filename(index_file,index_file); - if ((err=(outparam->file-> - ha_open(index_file, - (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR), - (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE : - ((db_stat & HA_WAIT_IF_LOCKED) || - (specialflag & SPECIAL_WAIT_IF_LOCKED)) ? - HA_OPEN_WAIT_IF_LOCKED : - (db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ? - HA_OPEN_ABORT_IF_LOCKED : - HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags)))) + if ((ha_err= (outparam->file-> + ha_open(index_file, + (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR), + (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE : + ((db_stat & HA_WAIT_IF_LOCKED) || + (specialflag & SPECIAL_WAIT_IF_LOCKED)) ? + HA_OPEN_WAIT_IF_LOCKED : + (db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ? + HA_OPEN_ABORT_IF_LOCKED : + HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags)))) { /* Set a flag if the table is crashed and it can be auto. repaired */ - share->crashed= ((err == HA_ERR_CRASHED_ON_USAGE) && + share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) && outparam->file->auto_repair() && !(ha_open_flags & HA_OPEN_FOR_REPAIR)); - if (err == HA_ERR_NO_SUCH_TABLE) + if (ha_err == HA_ERR_NO_SUCH_TABLE) { /* The table did not exists in storage engine, use same error message as if the .frm file didn't exist */ @@ -806,10 +815,10 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, } else { - outparam->file->print_error(err, MYF(0)); + outparam->file->print_error(ha_err, MYF(0)); error_reported= TRUE; } - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ } } share->db_low_byte_first= outparam->file->low_byte_first(); @@ -822,15 +831,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, #endif DBUG_RETURN (0); - err_w_init: - /* - Avoid problem with uninitialized data - Note that we don't have to initialize outparam->s here becasue - the caller will check if the pointer exists in case of errors - */ - bzero((char*) outparam,sizeof(*outparam)); - - err_not_open: + err: x_free((gptr) disk_buff); if (file > 0) VOID(my_close(file,MYF(MY_WME))); @@ -843,7 +844,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, outparam->file=0; // For easier errorchecking outparam->db_stat=0; hash_free(&share->name_hash); - free_root(&outparam->mem_root, MYF(0)); + free_root(&outparam->mem_root, MYF(0)); // Safe to call on bzero'd root my_free((char*) outparam->alias, MYF(MY_ALLOW_ZERO_PTR)); DBUG_RETURN (error); } /* openfrm */ |