diff options
author | unknown <holyfoot/hf@hfmain.(none)> | 2007-05-07 15:59:25 +0500 |
---|---|---|
committer | unknown <holyfoot/hf@hfmain.(none)> | 2007-05-07 15:59:25 +0500 |
commit | 42c714fd5f86a1dee317deb91f02994f97dffcef (patch) | |
tree | e059afb3677147e3bb4910d19fa4ded9f438aa17 /sql | |
parent | 2e1ce777814084a896841d789e43ce73bcdff03c (diff) | |
parent | 17da0553bbbe388ae0ffcfcd915a9a1a6d70259f (diff) | |
download | mariadb-git-42c714fd5f86a1dee317deb91f02994f97dffcef.tar.gz |
Merge bk@192.168.21.1:mysql-5.1
into mysql.com:/d2/hf/mrg/mysql-5.1-opt
sql/ha_ndbcluster.cc:
Auto merged
sql/item_func.cc:
Auto merged
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.cc | 16 | ||||
-rw-r--r-- | sql/field.h | 19 | ||||
-rw-r--r-- | sql/ha_ndbcluster.cc | 8 | ||||
-rw-r--r-- | sql/item_func.cc | 6 | ||||
-rw-r--r-- | sql/item_subselect.cc | 15 | ||||
-rw-r--r-- | sql/key.cc | 23 | ||||
-rw-r--r-- | sql/sql_parse.cc | 3 | ||||
-rw-r--r-- | sql/sql_select.cc | 64 | ||||
-rw-r--r-- | sql/sql_select.h | 1 |
9 files changed, 115 insertions, 40 deletions
diff --git a/sql/field.cc b/sql/field.cc index e8718c9e407..3ae82fe6182 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -7006,34 +7006,34 @@ Field_blob::Field_blob(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, } -void Field_blob::store_length(uint32 number) +void Field_blob::store_length(char *i_ptr, uint i_packlength, uint32 i_number) { - switch (packlength) { + switch (i_packlength) { case 1: - ptr[0]= (uchar) number; + i_ptr[0]= (uchar) i_number; break; case 2: #ifdef WORDS_BIGENDIAN if (table->s->db_low_byte_first) { - int2store(ptr,(unsigned short) number); + int2store(i_ptr,(unsigned short) i_number); } else #endif - shortstore(ptr,(unsigned short) number); + shortstore(i_ptr,(unsigned short) i_number); break; case 3: - int3store(ptr,number); + int3store(i_ptr,i_number); break; case 4: #ifdef WORDS_BIGENDIAN if (table->s->db_low_byte_first) { - int4store(ptr,number); + int4store(i_ptr,i_number); } else #endif - longstore(ptr,number); + longstore(i_ptr,i_number); } } diff --git a/sql/field.h b/sql/field.h index f9d77fe17ab..2c2640a8262 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1307,7 +1307,15 @@ public: } int reset(void) { bzero(ptr, packlength+sizeof(char*)); return 0; } void reset_fields() { bzero((char*) &value,sizeof(value)); } - void store_length(uint32 number); +#ifndef WORDS_BIGENDIAN + static +#endif + void store_length(char *i_ptr, uint i_packlength, uint32 i_number); + inline void store_length(uint32 number) + { + store_length(ptr, packlength, number); + } + inline uint32 get_length(uint row_offset=0) { return get_length(ptr+row_offset); } uint32 get_length(const char *ptr); @@ -1325,10 +1333,15 @@ public: memcpy(ptr,length,packlength); memcpy_fixed(ptr+packlength,&data,sizeof(char*)); } + void set_ptr_offset(my_ptrdiff_t ptr_diff, uint32 length,char *data) + { + char *ptr_ofs= ADD_TO_PTR(ptr,ptr_diff,char*); + store_length(ptr_ofs, packlength, length); + memcpy_fixed(ptr_ofs+packlength,&data,sizeof(char*)); + } inline void set_ptr(uint32 length,char *data) { - store_length(length); - memcpy_fixed(ptr+packlength,&data,sizeof(char*)); + set_ptr_offset(0, length, data); } uint get_key_image(char *buff,uint length, imagetype type); void set_key_image(char *buff,uint length); diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 02fbee7237f..b2a02c3b6d5 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -874,9 +874,7 @@ int get_ndb_blobs_value(TABLE* table, NdbValue* value_array, i, offset, (long) buf, len, (int)ptrdiff)); DBUG_ASSERT(len == len64); // Ugly hack assumes only ptr needs to be changed - field_blob->ptr+= ptrdiff; - field_blob->set_ptr(len, buf); - field_blob->ptr-= ptrdiff; + field_blob->set_ptr_offset(ptrdiff, len, buf); } offset+= size; } @@ -885,9 +883,7 @@ int get_ndb_blobs_value(TABLE* table, NdbValue* value_array, // have to set length even in this case char *buf= buffer + offset; // or maybe NULL uint32 len= 0; - field_blob->ptr+= ptrdiff; - field_blob->set_ptr(len, buf); - field_blob->ptr-= ptrdiff; + field_blob->set_ptr_offset(ptrdiff, len, buf); DBUG_PRINT("info", ("[%u] isNull=%d", i, isNull)); } } diff --git a/sql/item_func.cc b/sql/item_func.cc index 732c4403ca2..9219c01ccd0 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -956,7 +956,8 @@ longlong Item_func_signed::val_int() longlong value; int error; - if (args[0]->cast_to_int_type() != STRING_RESULT) + if (args[0]->cast_to_int_type() != STRING_RESULT || + args[0]->result_as_longlong()) { value= args[0]->val_int(); null_value= args[0]->null_value; @@ -995,7 +996,8 @@ longlong Item_func_unsigned::val_int() my_decimal2int(E_DEC_FATAL_ERROR, dec, 1, &value); return value; } - else if (args[0]->cast_to_int_type() != STRING_RESULT) + else if (args[0]->cast_to_int_type() != STRING_RESULT || + args[0]->result_as_longlong()) { value= args[0]->val_int(); null_value= args[0]->null_value; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 812d3c222c0..7d635ba444e 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1817,6 +1817,21 @@ int subselect_single_select_engine::exec() thd->lex->current_select= save_select; DBUG_RETURN(join->error ? join->error : 1); } + if (!select_lex->uncacheable && thd->lex->describe && + !(join->select_options & SELECT_DESCRIBE) && + join->need_tmp && item->const_item()) + { + /* + Force join->join_tmp creation, because this subquery will be replaced + by a simple select from the materialization temp table by optimize() + called by EXPLAIN and we need to preserve the initial query structure + so we can display it. + */ + select_lex->uncacheable|= UNCACHEABLE_EXPLAIN; + select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN; + if (join->init_save_join_tab()) + DBUG_RETURN(1); + } if (item->engine_changed) { DBUG_RETURN(1); diff --git a/sql/key.cc b/sql/key.cc index 19861cee134..9a3155c459e 100644 --- a/sql/key.cc +++ b/sql/key.cc @@ -214,23 +214,34 @@ void key_restore(byte *to_record, byte *from_key, KEY *key_info, } if (key_part->key_part_flag & HA_BLOB_PART) { + /* + This in fact never happens, as we have only partial BLOB + keys yet anyway, so it's difficult to find any sence to + restore the part of a record. + Maybe this branch is to be removed, but now we + have to ignore GCov compaining. + */ uint blob_length= uint2korr(from_key); + Field_blob *field= (Field_blob*) key_part->field; from_key+= HA_KEY_BLOB_LENGTH; key_length-= HA_KEY_BLOB_LENGTH; - ((Field_blob*) key_part->field)->set_ptr((ulong) blob_length, - (char*) from_key); + field->set_ptr_offset(to_record - field->table->record[0], + (ulong) blob_length, (char*) from_key); length= key_part->length; } else if (key_part->key_part_flag & HA_VAR_LENGTH_PART) { + Field *field= key_part->field; my_bitmap_map *old_map; + my_ptrdiff_t ptrdiff= to_record - field->table->record[0]; + field->move_field_offset(ptrdiff); key_length-= HA_KEY_BLOB_LENGTH; length= min(key_length, key_part->length); - old_map= dbug_tmp_use_all_columns(key_part->field->table, - key_part->field->table->write_set); - key_part->field->set_key_image((char *) from_key, length); - dbug_tmp_restore_column_map(key_part->field->table->write_set, old_map); + old_map= dbug_tmp_use_all_columns(field->table, field->table->write_set); + field->set_key_image((char *) from_key, length); + dbug_tmp_restore_column_map(field->table->write_set, old_map); from_key+= HA_KEY_BLOB_LENGTH; + field->move_field_offset(-ptrdiff); } else { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index af80ea91397..ae9a7bdde3d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4570,7 +4570,8 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, if (schema_db) { - if (want_access & ~(SELECT_ACL | EXTRA_ACL)) + if (!(sctx->master_access & FILE_ACL) && (want_access & FILE_ACL) || + (want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL))) { if (!no_errors) { diff --git a/sql/sql_select.cc b/sql/sql_select.cc index dff810e57b0..8f4fa75be91 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1436,14 +1436,13 @@ JOIN::optimize() } } - if (select_lex->uncacheable && !is_top_level_join()) - { - /* If this join belongs to an uncacheable subquery */ - if (!(tmp_join= (JOIN*)thd->alloc(sizeof(JOIN)))) - DBUG_RETURN(-1); - error= 0; // Ensure that tmp_join.error= 0 - restore_tmp(); - } + /* + If this join belongs to an uncacheable subquery save + the original join + */ + if (select_lex->uncacheable && !is_top_level_join() && + init_save_join_tab()) + DBUG_RETURN(-1); } error= 0; @@ -1505,6 +1504,27 @@ JOIN::reinit() DBUG_RETURN(0); } +/** + @brief Save the original join layout + + @details Saves the original join layout so it can be reused in + re-execution and for EXPLAIN. + + @return Operation status + @retval 0 success. + @retval 1 error occurred. +*/ + +bool +JOIN::init_save_join_tab() +{ + if (!(tmp_join= (JOIN*)thd->alloc(sizeof(JOIN)))) + return 1; + error= 0; // Ensure that tmp_join.error= 0 + restore_tmp(); + return 0; +} + bool JOIN::save_join_tab() @@ -5873,6 +5893,12 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) tab->ref.key= -1; tab->ref.key_parts=0; // Don't use ref key. join->best_positions[i].records_read= rows2double(tab->quick->records); + /* + We will use join cache here : prevent sorting of the first + table only and sort at the end. + */ + if (i != join->const_tables && join->tables > join->const_tables + 1) + join->full_join= 1; } tmp= NULL; @@ -6155,11 +6181,14 @@ make_join_readinfo(JOIN *join, ulonglong options) disable join cache because it will change the ordering of the results. Code handles sort table that is at any location (not only first after the const tables) despite the fact that it's currently prohibited. + We must disable join cache if the first non-const table alone is + ordered. If there is a temp table the ordering is done as a last + operation and doesn't prevent join cache usage. */ - if (!ordered_set && - (table == join->sort_by_table && + if (!ordered_set && !join->need_tmp && + ((table == join->sort_by_table && (!join->order || join->skip_sort_order)) || - (join->sort_by_table == (TABLE *) 1 && i != join->const_tables)) + (join->sort_by_table == (TABLE *) 1 && i != join->const_tables))) ordered_set= 1; tab->sorted= sorted; @@ -10768,7 +10797,6 @@ static enum_nested_loop_state evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, int error, my_bool *report_error) { - bool not_exists_optimize= join_tab->table->reginfo.not_exists_optimize; bool not_used_in_distinct=join_tab->not_used_in_distinct; ha_rows found_records=join->found_records; COND *select_cond= join_tab->select_cond; @@ -10805,6 +10833,8 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, first_unmatched->found= 1; for (JOIN_TAB *tab= first_unmatched; tab <= join_tab; tab++) { + if (tab->table->reginfo.not_exists_optimize) + return NESTED_LOOP_NO_MORE_ROWS; /* Check all predicates that has just been activated. */ /* Actually all predicates non-guarded by first_unmatched->found @@ -10850,8 +10880,6 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, if (found) { enum enum_nested_loop_state rc; - if (not_exists_optimize) - return NESTED_LOOP_NO_MORE_ROWS; /* A match from join_tab is found for the current partial join. */ rc= (*join_tab->next_select)(join, join_tab+1, 0); if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS) @@ -12638,6 +12666,12 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, uint nr; key_map keys; + /* + filesort() and join cache are usually faster than reading in + index order and not using join cache + */ + if (tab->type == JT_ALL && tab->join->tables > tab->join->const_tables + 1) + DBUG_RETURN(0); /* If not used with LIMIT, only use keys if the whole query can be resolved with a key; This is because filesort() is usually faster than @@ -15491,6 +15525,8 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, break; } } + if (tab->next_select == sub_select_cache) + extra.append(STRING_WITH_LEN("; Using join cache")); /* Skip initial "; "*/ const char *str= extra.ptr(); diff --git a/sql/sql_select.h b/sql/sql_select.h index ca37c7bd274..644224d1bed 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -473,6 +473,7 @@ public: void cleanup(bool full); void clear(); bool save_join_tab(); + bool init_save_join_tab(); bool send_row_on_empty_set() { return (do_send_rows && tmp_table_param.sum_func_count != 0 && |