Commit 5229431d authored by unknown's avatar unknown

Merge bk-internal.mysql.com:/home/bk/mysql-4.1

into mysql.com:/home/my/mysql-4.1


sql/field.cc:
  Auto merged
sql/field.h:
  Auto merged
sql/handler.h:
  Auto merged
sql/opt_range.cc:
  Auto merged
sql/sql_class.cc:
  Auto merged
sql/sql_select.cc:
  Auto merged
sql/table.cc:
  Auto merged
parents a93249cb 031e7872
......@@ -670,7 +670,7 @@ report_stats () {
$ECHO "The log files in $MY_LOG_DIR may give you some hint"
$ECHO "of what when wrong."
$ECHO "If you want to report this error, please read first the documentation at"
$ECHO "http://www.mysql.com/doc/M/y/MySQL_test_suite.html"
$ECHO "http://www.mysql.com/doc/en/MySQL_test_suite.html"
fi
if test -z "$USE_RUNNING_SERVER"
......
......@@ -750,3 +750,10 @@ analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
drop table t1;
CREATE TABLE t1 (
fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
g GEOMETRY NOT NULL,
SPATIAL KEY(g)
) ENGINE=MyISAM;
INSERT INTO t1 (g) VALUES (GeomFromText('LineString(1 2, 2 3)')),(GeomFromText('LineString(1 2, 2 4)'));
drop table t1;
......@@ -76,6 +76,8 @@ delete from mysql.db where user='mysqltest_1';
delete from mysql.tables_priv where user='mysqltest_1';
delete from mysql.columns_priv where user='mysqltest_1';
flush privileges;
show grants for mysqltest_1@localhost;
ERROR 42000: There is no such grant defined for user 'mysqltest_1' on host 'localhost'
create table t1 (a int);
GRANT select,update,insert on t1 to mysqltest_1@localhost;
GRANT select (a), update (a),insert(a), references(a) on t1 to mysqltest_1@localhost;
......
......@@ -103,3 +103,16 @@ check table t1;
analyze table t1;
drop table t1;
#
# The following crashed gis
#
CREATE TABLE t1 (
fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
g GEOMETRY NOT NULL,
SPATIAL KEY(g)
) ENGINE=MyISAM;
INSERT INTO t1 (g) VALUES (GeomFromText('LineString(1 2, 2 3)')),(GeomFromText('LineString(1 2, 2 4)'));
#select * from t1 where g<GeomFromText('LineString(1 2, 2 3)');
drop table t1;
......@@ -53,6 +53,8 @@ delete from mysql.db where user='mysqltest_1';
delete from mysql.tables_priv where user='mysqltest_1';
delete from mysql.columns_priv where user='mysqltest_1';
flush privileges;
--error 1141
show grants for mysqltest_1@localhost;
#
# Test what happens when you have same table and colum level grants
......
......@@ -4359,7 +4359,7 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED);
error= 1;
}
memcpy(ptr+2,from,length);
memcpy(ptr+HA_KEY_BLOB_LENGTH,from,length);
int2store(ptr, length);
return error;
}
......@@ -4388,18 +4388,18 @@ int Field_varstring::store(longlong nr)
double Field_varstring::val_real(void)
{
int not_used;
uint length=uint2korr(ptr)+2;
uint length=uint2korr(ptr)+HA_KEY_BLOB_LENGTH;
CHARSET_INFO *cs=charset();
return my_strntod(cs,ptr+2,length,(char**)0, &not_used);
return my_strntod(cs, ptr+HA_KEY_BLOB_LENGTH, length, (char**)0, &not_used);
}
longlong Field_varstring::val_int(void)
{
int not_used;
uint length=uint2korr(ptr)+2;
uint length=uint2korr(ptr)+HA_KEY_BLOB_LENGTH;
CHARSET_INFO *cs=charset();
return my_strntoll(cs,ptr+2,length,10,NULL, &not_used);
return my_strntoll(cs,ptr+HA_KEY_BLOB_LENGTH,length,10,NULL, &not_used);
}
......@@ -4407,7 +4407,7 @@ String *Field_varstring::val_str(String *val_buffer __attribute__((unused)),
String *val_ptr)
{
uint length=uint2korr(ptr);
val_ptr->set((const char*) ptr+2,length,field_charset);
val_ptr->set((const char*) ptr+HA_KEY_BLOB_LENGTH,length,field_charset);
return val_ptr;
}
......@@ -4417,18 +4417,21 @@ int Field_varstring::cmp(const char *a_ptr, const char *b_ptr)
uint a_length=uint2korr(a_ptr);
uint b_length=uint2korr(b_ptr);
int diff;
diff=my_strnncoll(field_charset,
(const uchar*)a_ptr+2,min(a_length,b_length),
(const uchar*)b_ptr+2,min(a_length,b_length));
diff= my_strnncoll(field_charset,
(const uchar*) a_ptr+HA_KEY_BLOB_LENGTH,
min(a_length,b_length),
(const uchar*) b_ptr+HA_KEY_BLOB_LENGTH,
min(a_length,b_length));
return diff ? diff : (int) (a_length - b_length);
}
void Field_varstring::sort_string(char *to,uint length)
{
uint tot_length=uint2korr(ptr);
tot_length=my_strnxfrm(field_charset,
(unsigned char *) to, length,
(unsigned char *)ptr+2, tot_length);
tot_length= my_strnxfrm(field_charset,
(uchar*) to, length,
(uchar*) ptr+HA_KEY_BLOB_LENGTH,
tot_length);
if (tot_length < length)
field_charset->cset->fill(field_charset, to+tot_length,length-tot_length,
binary() ? (char) 0 : ' ');
......@@ -4453,7 +4456,7 @@ char *Field_varstring::pack(char *to, const char *from, uint max_length)
if (max_length > 255)
*to++= (char) (length >> 8);
if (length)
memcpy(to, from+2, length);
memcpy(to, from+HA_KEY_BLOB_LENGTH, length);
return to+length;
}
......@@ -4473,7 +4476,7 @@ const char *Field_varstring::unpack(char *to, const char *from)
to[1] = *from++;
}
if (length)
memcpy(to+2, from, length);
memcpy(to+HA_KEY_BLOB_LENGTH, from, length);
return from+length;
}
......@@ -4484,8 +4487,8 @@ int Field_varstring::pack_cmp(const char *a, const char *b, uint key_length)
uint b_length;
if (key_length > 255)
{
a_length=uint2korr(a); a+=2;
b_length=uint2korr(b); b+=2;
a_length=uint2korr(a); a+= 2;
b_length=uint2korr(b); b+= 2;
}
else
{
......@@ -4493,32 +4496,32 @@ int Field_varstring::pack_cmp(const char *a, const char *b, uint key_length)
b_length= (uint) (uchar) *b++;
}
return my_strnncoll(field_charset,
(const uchar *)a,a_length,
(const uchar *)b,b_length);
(const uchar*) a, a_length,
(const uchar*) b, b_length);
}
int Field_varstring::pack_cmp(const char *b, uint key_length)
{
char *a=ptr+2;
uint a_length=uint2korr(ptr);
char *a= ptr+HA_KEY_BLOB_LENGTH;
uint a_length= uint2korr(ptr);
uint b_length;
if (key_length > 255)
{
b_length=uint2korr(b); b+=2;
b_length=uint2korr(b); b+= 2;
}
else
{
b_length= (uint) (uchar) *b++;
}
return my_strnncoll(field_charset,
(const uchar *)a,a_length,
(const uchar *)b,b_length);
(const uchar*) a, a_length,
(const uchar*) b, b_length);
}
uint Field_varstring::packed_col_length(const char *data_ptr, uint length)
{
if (length > 255)
return uint2korr(data_ptr)+2;
return uint2korr(data_ptr)+HA_KEY_BLOB_LENGTH;
else
return (uint) ((uchar) *data_ptr)+1;
}
......@@ -4531,22 +4534,21 @@ uint Field_varstring::max_packed_col_length(uint max_length)
void Field_varstring::get_key_image(char *buff, uint length, CHARSET_INFO *cs,
imagetype type)
{
length-= HA_KEY_BLOB_LENGTH;
uint f_length=uint2korr(ptr);
if (f_length > length)
f_length= length;
int2store(buff,length);
memcpy(buff+2,ptr+2,length);
memcpy(buff+HA_KEY_BLOB_LENGTH, ptr+HA_KEY_BLOB_LENGTH, length);
#ifdef HAVE_purify
if (f_length < length)
bzero(buff+2+f_length, (length-f_length));
bzero(buff+HA_KEY_BLOB_LENGTH+f_length, (length-f_length));
#endif
}
void Field_varstring::set_key_image(char *buff,uint length, CHARSET_INFO *cs)
{
length=uint2korr(buff); // Real length is here
(void) Field_varstring::store(buff+2, length, cs);
(void) Field_varstring::store(buff+HA_KEY_BLOB_LENGTH, length, cs);
}
......@@ -4799,7 +4801,6 @@ int Field_blob::cmp_binary(const char *a_ptr, const char *b_ptr,
void Field_blob::get_key_image(char *buff,uint length,
CHARSET_INFO *cs, imagetype type)
{
length-= HA_KEY_BLOB_LENGTH;
uint32 blob_length= get_length(ptr);
char *blob;
......@@ -4838,18 +4839,18 @@ void Field_blob::get_key_image(char *buff,uint length,
Must clear this as we do a memcmp in opt_range.cc to detect
identical keys
*/
bzero(buff+2+blob_length, (length-blob_length));
bzero(buff+HA_KEY_BLOB_LENGTH+blob_length, (length-blob_length));
length=(uint) blob_length;
}
int2store(buff,length);
get_ptr(&blob);
memcpy(buff+2,blob,length);
memcpy(buff+HA_KEY_BLOB_LENGTH, blob, length);
}
void Field_blob::set_key_image(char *buff,uint length, CHARSET_INFO *cs)
{
length=uint2korr(buff);
(void) Field_blob::store(buff+2,length,cs);
length= uint2korr(buff);
(void) Field_blob::store(buff+HA_KEY_BLOB_LENGTH, length, cs);
}
......@@ -4857,16 +4858,16 @@ int Field_blob::key_cmp(const byte *key_ptr, uint max_key_length)
{
char *blob1;
uint blob_length=get_length(ptr);
max_key_length-=2;
memcpy_fixed(&blob1,ptr+packlength,sizeof(char*));
return Field_blob::cmp(blob1,min(blob_length, max_key_length),
(char*) key_ptr+2,uint2korr(key_ptr));
(char*) key_ptr+HA_KEY_BLOB_LENGTH,
uint2korr(key_ptr));
}
int Field_blob::key_cmp(const byte *a,const byte *b)
{
return Field_blob::cmp((char*) a+2,uint2korr(a),
(char*) b+2,uint2korr(b));
return Field_blob::cmp((char*) a+HA_KEY_BLOB_LENGTH, uint2korr(a),
(char*) b+HA_KEY_BLOB_LENGTH, uint2korr(b));
}
......@@ -4882,8 +4883,8 @@ void Field_blob::sort_string(char *to,uint length)
memcpy_fixed(&blob,ptr+packlength,sizeof(char*));
blob_length=my_strnxfrm(field_charset,
(unsigned char *)to, length,
(unsigned char *)blob, blob_length);
(uchar*) to, length,
(uchar*) blob, blob_length);
if (blob_length < length)
field_charset->cset->fill(field_charset, to+blob_length,
length-blob_length,
......@@ -4965,8 +4966,8 @@ int Field_blob::pack_cmp(const char *a, const char *b, uint key_length)
b_length= (uint) (uchar) *b++;
}
return my_strnncoll(field_charset,
(const uchar *)a,a_length,
(const uchar *)b,b_length);
(const uchar*) a, a_length,
(const uchar*) b, b_length);
}
......@@ -4988,8 +4989,8 @@ int Field_blob::pack_cmp(const char *b, uint key_length)
b_length= (uint) (uchar) *b++;
}
return my_strnncoll(field_charset,
(const uchar *)a,a_length,
(const uchar *)b,b_length);
(const uchar*) a, a_length,
(const uchar*) b, b_length);
}
/* Create a packed key that will be used for storage from a MySQL row */
......@@ -5025,7 +5026,7 @@ char *Field_blob::pack_key_from_key_image(char *to, const char *from,
if (max_length > 255)
*to++= (char) (length >> 8);
if (length)
memcpy(to, from+2, length);
memcpy(to, from+HA_KEY_BLOB_LENGTH, length);
return to+length;
}
......@@ -5048,11 +5049,12 @@ uint Field_blob::max_packed_col_length(uint max_length)
void Field_geom::get_key_image(char *buff, uint length, CHARSET_INFO *cs,
imagetype type)
{
length-= HA_KEY_BLOB_LENGTH;
ulong blob_length= get_length(ptr);
char *blob;
const char *dummy;
MBR mbr;
ulong blob_length= get_length(ptr);
Geometry_buffer buffer;
Geometry *gobj;
if (blob_length < SRID_SIZE)
{
......@@ -5060,8 +5062,6 @@ void Field_geom::get_key_image(char *buff, uint length, CHARSET_INFO *cs,
return;
}
get_ptr(&blob);
Geometry_buffer buffer;
Geometry *gobj;
gobj= Geometry::create_from_wkb(&buffer,
blob + SRID_SIZE, blob_length - SRID_SIZE);
if (gobj->get_mbr(&mbr, &dummy))
......@@ -5554,7 +5554,7 @@ uint32 calc_pack_length(enum_field_types type,uint32 length)
switch (type) {
case FIELD_TYPE_STRING:
case FIELD_TYPE_DECIMAL: return (length);
case FIELD_TYPE_VAR_STRING: return (length+2);
case FIELD_TYPE_VAR_STRING: return (length+HA_KEY_BLOB_LENGTH);
case FIELD_TYPE_YEAR:
case FIELD_TYPE_TINY : return 1;
case FIELD_TYPE_SHORT : return 2;
......
......@@ -212,7 +212,8 @@ class Field
{ memcpy(buff,ptr,length); }
inline void set_image(char *buff,uint length, CHARSET_INFO *cs)
{ memcpy(ptr,buff,length); }
virtual void get_key_image(char *buff,uint length, CHARSET_INFO *cs, imagetype type)
virtual void get_key_image(char *buff,uint length, CHARSET_INFO *cs,
imagetype type)
{ get_image(buff,length,cs); }
virtual void set_key_image(char *buff,uint length, CHARSET_INFO *cs)
{ set_image(buff,length,cs); }
......
......@@ -1287,3 +1287,141 @@ int ha_change_key_cache(KEY_CACHE *old_key_cache,
mi_change_key_cache(old_key_cache, new_key_cache);
return 0;
}
/*
Read first row between two ranges.
Store ranges for future calls to read_range_next
SYNOPSIS
read_range_first()
start_key Start key. Is 0 if no min range
end_key End key. Is 0 if no max range
sorted Set to 1 if result should be sorted per key
NOTES
Record is read into table->record[0]
RETURN
0 Found row
HA_ERR_END_OF_FILE No rows in range
# Error code
*/
int handler::read_range_first(const key_range *start_key,
const key_range *end_key,
bool sorted)
{
int result;
DBUG_ENTER("handler::read_range_first");
end_range= 0;
if (end_key)
{
end_range= &save_end_range;
save_end_range= *end_key;
key_compare_result_on_equal= ((end_key->flag == HA_READ_BEFORE_KEY) ? 1 :
(end_key->flag == HA_READ_AFTER_KEY) ? -1 : 0);
}
range_key_part= table->key_info[active_index].key_part;
if (!start_key) // Read first record
result= index_first(table->record[0]);
else
result= index_read(table->record[0],
start_key->key,
start_key->length,
start_key->flag);
if (result)
DBUG_RETURN((result == HA_ERR_KEY_NOT_FOUND ||
result == HA_ERR_END_OF_FILE) ? HA_ERR_END_OF_FILE :
result);
DBUG_RETURN (compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE);
}
/*
Read next row between two ranges.
SYNOPSIS
read_range_next()
eq_range Set to 1 if start_key == end_key
NOTES
Record is read into table->record[0]
RETURN
0 Found row
HA_ERR_END_OF_FILE No rows in range
# Error code
*/
int handler::read_range_next(bool eq_range)
{
int result;
DBUG_ENTER("handler::read_range_next");
if (eq_range)
result= index_next_same(table->record[0],
end_range->key,
end_range->length);
else
result= index_next(table->record[0]);
if (result)
DBUG_RETURN(result);
DBUG_RETURN(compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE);
}
/*
Compare if found key is over max-value
SYNOPSIS
compare_key
range key to compare to row
NOTES
For this to work, the row must be stored in table->record[0]
RETURN
0 Key is equal to range or 'range' == 0 (no range)
-1 Key is less than range
1 Key is larger than range
*/
int handler::compare_key(key_range *range)
{
KEY_PART_INFO *key_part= range_key_part;
uint store_length;
if (!range)
return 0; // No max range
for (const char *key=range->key, *end=key+range->length;
key < end;
key+= store_length, key_part++)
{
int cmp;
store_length= key_part->store_length;
if (key_part->null_bit)
{
if (*key)
{
if (!key_part->field->is_null())
return 1;
continue;
}
else if (key_part->field->is_null())
return 0;
key++; // Skip null byte
store_length--;
}
if ((cmp=key_part->field->key_cmp((byte*) key, key_part->length)) < 0)
return -1;
if (cmp > 0)
return 1;
}
return key_compare_result_on_equal;
}
......@@ -218,6 +218,14 @@ typedef struct st_ha_check_opt
} HA_CHECK_OPT;
typedef struct st_key_range
{
const byte *key;
uint length;
enum ha_rkey_function flag;
} key_range;
class handler :public Sql_alloc
{
protected:
......@@ -239,6 +247,12 @@ class handler :public Sql_alloc
time_t create_time; /* When table was created */
time_t check_time;
time_t update_time;
/* The following are for read_range() */
key_range save_end_range, *end_range;
KEY_PART_INFO *range_key_part;
int key_compare_result_on_equal;
uint errkey; /* Last dup key */
uint sortkey, key_used_on_scan;
uint active_index;
......@@ -250,6 +264,7 @@ class handler :public Sql_alloc
bool auto_increment_column_changed;
bool implicit_emptied; /* Can be !=0 only if HEAP */
handler(TABLE *table_arg) :table(table_arg),
ref(0), data_file_length(0), max_data_file_length(0), index_file_length(0),
delete_length(0), auto_increment_value(0),
......@@ -298,6 +313,11 @@ class handler :public Sql_alloc
{
return (my_errno=HA_ERR_WRONG_COMMAND);
}
virtual int handler::read_range_first(const key_range *start_key,
const key_range *end_key,
bool sorted);
virtual int handler::read_range_next(bool eq_range);
int handler::compare_key(key_range *range);
virtual int ft_init()
{ return -1; }
virtual FT_INFO *ft_init_ext(uint flags,uint inx,const byte *key, uint keylen)
......
This diff is collapsed.
......@@ -35,7 +35,7 @@
typedef struct st_key_part {
uint16 key,part,part_length;
uint16 key,part, store_length, length;
uint8 null_bit;
Field *field;
Field::imagetype image_type;
......@@ -68,7 +68,7 @@ class QUICK_RANGE :public Sql_alloc {
class QUICK_SELECT {
public:
bool next,dont_free;
bool next,dont_free,sorted;
int error;
uint index, max_used_key_length, used_key_parts;
TABLE *head;
......@@ -89,11 +89,20 @@ class QUICK_SELECT {
int init() { return error=file->index_init(index); }
virtual int get_next();
virtual bool reverse_sorted() { return 0; }
int cmp_next(QUICK_RANGE *range);
bool unique_key_range();
};
class QUICK_SELECT_GEOM: public QUICK_SELECT
{
public:
QUICK_SELECT_GEOM(THD *thd, TABLE *table, uint index_arg, bool no_alloc)
:QUICK_SELECT(thd, table, index_arg, no_alloc)
{};
virtual int get_next();
};
class QUICK_SELECT_DESC: public QUICK_SELECT
{
public:
......
......@@ -86,7 +86,8 @@ extern "C" void free_user_var(user_var_entry *entry)
THD::THD():user_time(0), current_statement(0), is_fatal_error(0),
last_insert_id_used(0),
insert_id_used(0), rand_used(0), in_lock_tables(0),
global_read_lock(0), bootstrap(0)
global_read_lock(0), bootstrap(0),
no_table_fix_fields_cache(0)
{
host= user= priv_user= db= ip=0;
host_or_ip= "connecting host";
......
......@@ -3746,7 +3746,8 @@ make_join_readinfo(JOIN *join, uint options)
table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD);
}
else if (!table->used_keys.is_clear_all() && ! (tab->select && tab->select->quick))
else if (!table->used_keys.is_clear_all() &&
!(tab->select && tab->select->quick))
{ // Only read index tree
tab->index=find_shortest_key(table, & table->used_keys);
tab->table->file->index_init(tab->index);
......@@ -6907,6 +6908,7 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
key_part_end=key_part+table->key_info[idx].key_parts;
key_part_map const_key_parts=table->const_key_parts[idx];
int reverse=0;
DBUG_ENTER("test_if_order_by_key");
for (; order ; order=order->next, const_key_parts>>=1)
{
......@@ -6917,25 +6919,24 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
Skip key parts that are constants in the WHERE clause.
These are already skipped in the ORDER BY by const_expression_in_where()
*/
while (const_key_parts & 1)
{
key_part++; const_key_parts>>=1;
}
for (; const_key_parts & 1 ; const_key_parts>>= 1)
key_part++;
if (key_part == key_part_end || key_part->field != field)
return 0;
DBUG_RETURN(0);
/* set flag to 1 if we can use read-next on key, else to -1 */
flag=(order->asc == !(key_part->key_part_flag & HA_REVERSE_SORT))
? 1 : -1;
flag= ((order->asc == !(key_part->key_part_flag & HA_REVERSE_SORT)) ? 1 : -1);
if (reverse && flag != reverse)
return 0;
DBUG_RETURN(0);
reverse=flag; // Remember if reverse
key_part++;
}
*used_key_parts= (uint) (key_part - table->key_info[idx].key_part);
return reverse;
DBUG_RETURN(reverse);
}
static uint find_shortest_key(TABLE *table, const key_map *usable_keys)
{
uint min_length= (uint) ~0;
......@@ -6958,18 +6959,20 @@ static uint find_shortest_key(TABLE *table, const key_map *usable_keys)
}
/*
Test if a second key is the subkey of the first one.
SYNOPSIS
is_subkey()
key_part - first key parts
ref_key_part - second key parts
ref_key_part_end - last+1 part of the second key
DESCRIPTION
Test if a second key is the subkey of the first one.
key_part First key parts
ref_key_part Second key parts
ref_key_part_end Last+1 part of the second key
NOTE
Second key MUST be shorter than the first one.
RETURN
1 - is the subkey
0 - otherwise
1 is a subkey
0 no sub key
*/
inline bool
......@@ -6983,20 +6986,21 @@ is_subkey(KEY_PART_INFO *key_part, KEY_PART_INFO *ref_key_part,
}
/*
Test if we can use one of the 'usable_keys' instead of 'ref' key for sorting
SYNOPSIS
test_if_subkey()
ref - number of key, used for WHERE clause
usable_keys - keys for testing
DESCRIPTION
Test if we can use one of the 'usable_keys' instead of 'ref' key.
ref Number of key, used for WHERE clause
usable_keys Keys for testing
RETURN
MAX_KEY - if we can't use other key
the number of found key - otherwise
MAX_KEY If we can't use other key
the number of found key Otherwise
*/
static uint
test_if_subkey(ORDER *order, TABLE *table, uint ref, uint ref_key_parts,
const key_map& usable_keys)
const key_map *usable_keys)
{
uint nr;
uint min_length= (uint) ~0;
......@@ -7007,7 +7011,7 @@ test_if_subkey(ORDER *order, TABLE *table, uint ref, uint ref_key_parts,
for (nr= 0 ; nr < table->keys ; nr++)
{
if (usable_keys.is_set(nr) &&
if (usable_keys->is_set(nr) &&
table->key_info[nr].key_length < min_length &&
table->key_info[nr].key_parts >= ref_key_parts &&
is_subkey(table->key_info[nr].key_part, ref_key_part,
......@@ -7051,12 +7055,12 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
if ((*tmp_order->item)->type() != Item::FIELD_ITEM)
{
usable_keys.clear_all();
break;
DBUG_RETURN(0);
}
usable_keys.intersect(
((Item_field*) (*tmp_order->item))->field->part_of_sortkey);
usable_keys.intersect(((Item_field*) (*tmp_order->item))->
field->part_of_sortkey);
if (usable_keys.is_clear_all())
break; // No usable keys
DBUG_RETURN(0); // No usable keys
}
ref_key= -1;
......@@ -7092,9 +7096,9 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
keys
*/
if (table->used_keys.is_set(ref_key))
usable_keys.merge(table->used_keys);
usable_keys.intersect(table->used_keys);
if ((new_ref_key= test_if_subkey(order, table, ref_key, ref_key_parts,
usable_keys)) < MAX_KEY)
&usable_keys)) < MAX_KEY)
{
/* Found key that can be used to retrieve data in sorted order */
if (tab->ref.key >= 0)
......@@ -7154,6 +7158,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
/* fall through */
}
}
else if (select && select->quick)
select->quick->sorted= 1;
DBUG_RETURN(1); /* No need to sort */
}
}
......@@ -7292,9 +7298,9 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
For impossible ranges (like when doing a lookup on NULL on a NOT NULL
field, quick will contain an empty record set.
*/
if (!(select->quick= tab->type == JT_FT ?
new FT_SELECT(thd, table, tab->ref.key) :
get_quick_select_for_ref(thd, table, &tab->ref)))
if (!(select->quick= (tab->type == JT_FT ?
new FT_SELECT(thd, table, tab->ref.key) :
get_quick_select_for_ref(thd, table, &tab->ref))))
goto err;
}
}
......
......@@ -553,7 +553,6 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
keyinfo->key_length+= HA_KEY_NULL_LENGTH;
}
if (field->type() == FIELD_TYPE_BLOB ||
field->type() == FIELD_TYPE_GEOMETRY ||
field->real_type() == FIELD_TYPE_VAR_STRING)
{
if (field->type() == FIELD_TYPE_BLOB)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment