Commit 359846f0 authored by monty@narttu.mysql.fi's avatar monty@narttu.mysql.fi

Fixed some varnings from valgrind

Set min value of max_allowed_packet to 1024
Fixed problem with UNION's without braces and SQL_CALC_FOUND_ROWS, LIMIT #,#
and ORDER BY...LIMIT
parent 4877e908
...@@ -119,6 +119,18 @@ extern void bmove_allign(gptr dst,const gptr src,uint len); ...@@ -119,6 +119,18 @@ extern void bmove_allign(gptr dst,const gptr src,uint len);
#define bmove512(A,B,C) memcpy(A,B,C) #define bmove512(A,B,C) memcpy(A,B,C)
#endif #endif
#ifdef HAVE_purify
#include <assert.h>
#define memcpy_overlap(A,B,C) \
DBUG_ASSERT((A) == (B) || ((A)+(C)) <= (B) || ((B)+(C)) <= (A)); \
bmove((byte*) key,(byte*) from,(size_t) length);
#else
#define memcpy_overlap(A,B,C) \
DBUG_ASSERT((A) == (B) || ((A)+(C)) <= (B) || ((B)+(C)) <= (A)); \
memcpy((A), (B), (C))
#endif /* HAVE_purify */
/* Prototypes for string functions */ /* Prototypes for string functions */
#if !defined(bfill) && !defined(HAVE_BFILL) #if !defined(bfill) && !defined(HAVE_BFILL)
......
...@@ -286,7 +286,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, ...@@ -286,7 +286,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
keydef->seg[0].type == (int) HA_KEYTYPE_NUM) keydef->seg[0].type == (int) HA_KEYTYPE_NUM)
keydef->seg[0].flag&= ~HA_SPACE_PACK; keydef->seg[0].flag&= ~HA_SPACE_PACK;
/* Only use HA_PACK_KEY if the first segment is a variable length key */ /* Only use HA_PACK_KEY when first segment is a variable length key */
if (!(keydef->seg[0].flag & (HA_SPACE_PACK | HA_BLOB_PART | if (!(keydef->seg[0].flag & (HA_SPACE_PACK | HA_BLOB_PART |
HA_VAR_LENGTH))) HA_VAR_LENGTH)))
{ {
......
...@@ -1218,9 +1218,10 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag, ...@@ -1218,9 +1218,10 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
register uchar **page_pos, register uchar *key) register uchar **page_pos, register uchar *key)
{ {
reg1 MI_KEYSEG *keyseg; reg1 MI_KEYSEG *keyseg;
uchar *start_key,*page=*page_pos,*page_end,*from,*from_end; uchar *start_key,*page,*page_end,*from,*from_end;
uint length,tmp; uint length,tmp;
page= *page_pos;
page_end=page+MI_MAX_KEY_BUFF+1; page_end=page+MI_MAX_KEY_BUFF+1;
start_key=key; start_key=key;
...@@ -1276,7 +1277,9 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag, ...@@ -1276,7 +1277,9 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
length-=tmp; length-=tmp;
from=page; from_end=page_end; from=page; from_end=page_end;
} }
memcpy((byte*) key,(byte*) from,(size_t) length); DBUG_PRINT("info",("key: %lx from: %lx length: %u",
key, from, length));
memcpy_overlap((byte*) key, (byte*) from, (size_t) length);
key+=length; key+=length;
from+=length; from+=length;
} }
...@@ -1998,6 +2001,9 @@ _mi_calc_bin_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key, ...@@ -1998,6 +2001,9 @@ _mi_calc_bin_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
uint length,key_length,ref_length; uint length,key_length,ref_length;
s_temp->totlength=key_length=_mi_keylength(keyinfo,key)+nod_flag; s_temp->totlength=key_length=_mi_keylength(keyinfo,key)+nod_flag;
#ifdef HAVE_purify
s_temp->n_length= s_temp->n_ref_length=0; /* For valgrind */
#endif
s_temp->key=key; s_temp->key=key;
s_temp->prev_key=org_key; s_temp->prev_key=org_key;
if (prev_key) /* If not first key in block */ if (prev_key) /* If not first key in block */
......
...@@ -887,4 +887,3 @@ void mi_end_bulk_insert(MI_INFO *info) ...@@ -887,4 +887,3 @@ void mi_end_bulk_insert(MI_INFO *info)
info->bulk_insert=0; info->bulk_insert=0;
} }
} }
...@@ -253,12 +253,6 @@ while test $# -gt 0; do ...@@ -253,12 +253,6 @@ while test $# -gt 0; do
--start-and-exit) --start-and-exit)
START_AND_EXIT=1 START_AND_EXIT=1
;; ;;
--skip-innodb)
EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --skip-innodb"
EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --skip-innodb" ;;
--skip-bdb)
EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --skip-bdb"
EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --skip-bdb" ;;
--skip-rpl) NO_SLAVE=1 ;; --skip-rpl) NO_SLAVE=1 ;;
--skip-test=*) SKIP_TEST=`$ECHO "$1" | $SED -e "s;--skip-test=;;"`;; --skip-test=*) SKIP_TEST=`$ECHO "$1" | $SED -e "s;--skip-test=;;"`;;
--do-test=*) DO_TEST=`$ECHO "$1" | $SED -e "s;--do-test=;;"`;; --do-test=*) DO_TEST=`$ECHO "$1" | $SED -e "s;--do-test=;;"`;;
......
...@@ -5,12 +5,12 @@ set net_buffer_length=100; ...@@ -5,12 +5,12 @@ set net_buffer_length=100;
SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len; SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len;
len len
1024 1024
select repeat('a',200); select repeat('a',2000);
repeat('a',200) repeat('a',2000)
NULL NULL
select @@net_buffer_length, @@max_allowed_packet; select @@net_buffer_length, @@max_allowed_packet;
@@net_buffer_length @@max_allowed_packet @@net_buffer_length @@max_allowed_packet
1024 80 1024 1024
SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len; SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len;
Got a packet bigger than 'max_allowed_packet' Got a packet bigger than 'max_allowed_packet'
set global max_allowed_packet=default; set global max_allowed_packet=default;
...@@ -20,6 +20,6 @@ set net_buffer_length=default; ...@@ -20,6 +20,6 @@ set net_buffer_length=default;
SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len; SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len;
len len
100 100
select length(repeat('a',200)); select length(repeat('a',2000));
length(repeat('a',200)) length(repeat('a',2000))
200 2000
...@@ -102,7 +102,7 @@ a b ...@@ -102,7 +102,7 @@ a b
2 b 2 b
select found_rows(); select found_rows();
found_rows() found_rows()
6 8
explain select a,b from t1 union all select a,b from t2; explain select a,b from t1 union all select a,b from t2;
table type possible_keys key key_len ref rows Extra table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 4 t1 ALL NULL NULL NULL NULL 4
...@@ -295,3 +295,128 @@ a b ...@@ -295,3 +295,128 @@ a b
5 f 5 f
6 e 6 e
drop table t1,t2,t3,t4; drop table t1,t2,t3,t4;
create table t1 (a int);
insert into t1 values (1),(2),(3);
create table t2 (a int);
insert into t2 values (3),(4),(5);
(SELECT SQL_CALC_FOUND_ROWS * FROM t1) UNION all (SELECT * FROM t2) LIMIT 1;
a
1
select found_rows();
found_rows()
6
(SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1) UNION all (SELECT * FROM t2) LIMIT 2;
a
1
3
select found_rows();
found_rows()
4
(SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1) UNION all (SELECT * FROM t2);
a
1
3
4
5
select found_rows();
found_rows()
4
(SELECT SQL_CALC_FOUND_ROWS * FROM t1) UNION all (SELECT * FROM t2 LIMIT 1);
a
1
2
3
3
select found_rows();
found_rows()
4
(SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1) UNION SELECT * FROM t2 LIMIT 1;
a
1
select found_rows();
found_rows()
4
SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1 UNION all SELECT * FROM t2 LIMIT 2;
a
1
3
select found_rows();
found_rows()
6
SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION all SELECT * FROM t2 LIMIT 2;
a
1
2
select found_rows();
found_rows()
6
SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION SELECT * FROM t2 LIMIT 2;
a
1
2
select found_rows();
found_rows()
6
SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION SELECT * FROM t2 LIMIT 100;
a
1
2
3
4
5
select found_rows();
found_rows()
6
SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 100 UNION SELECT * FROM t2;
a
1
2
3
4
5
select found_rows();
found_rows()
5
SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1 UNION SELECT * FROM t2;
a
1
3
4
5
select found_rows();
found_rows()
6
SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1 UNION SELECT * FROM t2 LIMIT 2;
a
1
3
select found_rows();
found_rows()
6
SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION SELECT * FROM t2 LIMIT 2,2;
a
3
4
select found_rows();
found_rows()
6
SELECT SQL_CALC_FOUND_ROWS * FROM t1 limit 2,2 UNION SELECT * FROM t2;
a
3
4
5
select found_rows();
found_rows()
5
SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a desc LIMIT 1;
a
5
(SELECT * FROM t1 ORDER by a) UNION ALL (SELECT * FROM t2 ORDER BY a) ORDER BY A desc LIMIT 4;
a
5
4
3
3
(SELECT * FROM t1) UNION all (SELECT SQL_CALC_FOUND_ROWS * FROM t2) LIMIT 1;
Wrong usage/placement of 'SQL_CALC_FOUND_ROWS'
drop table t1,t2;
...@@ -12,8 +12,8 @@ set global net_buffer_length=100; ...@@ -12,8 +12,8 @@ set global net_buffer_length=100;
set net_buffer_length=100; set net_buffer_length=100;
# Have to be > 1024 as min value of net_buffer_length is 1024 # Have to be > 1024 as min value of net_buffer_length is 1024
SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len; SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len;
# Should return NULL as 200 is bigger than max_allowed_packet # Should return NULL as 2000 is bigger than max_allowed_packet
select repeat('a',200); select repeat('a',2000);
# #
# Connection 2 should get error for too big packets # Connection 2 should get error for too big packets
...@@ -28,4 +28,4 @@ set max_allowed_packet=default; ...@@ -28,4 +28,4 @@ set max_allowed_packet=default;
set global net_buffer_length=default; set global net_buffer_length=default;
set net_buffer_length=default; set net_buffer_length=default;
SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len; SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len;
select length(repeat('a',200)); select length(repeat('a',2000));
...@@ -16,7 +16,7 @@ select 0,'#' union select a,b from t1 union all select a,b from t2 union select ...@@ -16,7 +16,7 @@ select 0,'#' union select a,b from t1 union all select a,b from t2 union select
select a,b from t1 union select a,b from t1; select a,b from t1 union select a,b from t1;
select 't1',b,count(*) from t1 group by b UNION select 't2',b,count(*) from t2 group by b; select 't1',b,count(*) from t1 group by b UNION select 't2',b,count(*) from t2 group by b;
#test alternate syntax for unions # Test alternate syntax for unions
(select a,b from t1 limit 2) union all (select a,b from t2 order by a) limit 4; (select a,b from t1 limit 2) union all (select a,b from t2 order by a) limit 4;
(select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1); (select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1);
(select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by b desc; (select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by b desc;
...@@ -170,3 +170,57 @@ insert into t3 (select a,b from t1) union (select a,b from t2) limit 2; ...@@ -170,3 +170,57 @@ insert into t3 (select a,b from t1) union (select a,b from t2) limit 2;
select * from t3; select * from t3;
select * from t4; select * from t4;
drop table t1,t2,t3,t4; drop table t1,t2,t3,t4;
#
# Test of SQL_CALC_FOUND_ROW handling
#
create table t1 (a int);
insert into t1 values (1),(2),(3);
create table t2 (a int);
insert into t2 values (3),(4),(5);
# Test global limits
(SELECT SQL_CALC_FOUND_ROWS * FROM t1) UNION all (SELECT * FROM t2) LIMIT 1;
select found_rows();
(SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1) UNION all (SELECT * FROM t2) LIMIT 2;
select found_rows();
# Test cases where found_rows() should return number of returned rows
(SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1) UNION all (SELECT * FROM t2);
select found_rows();
(SELECT SQL_CALC_FOUND_ROWS * FROM t1) UNION all (SELECT * FROM t2 LIMIT 1);
select found_rows();
(SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1) UNION SELECT * FROM t2 LIMIT 1;
select found_rows();
# In these case found_rows() should work
SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1 UNION all SELECT * FROM t2 LIMIT 2;
select found_rows();
SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION all SELECT * FROM t2 LIMIT 2;
select found_rows();
# The following examples will not be exact
SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION SELECT * FROM t2 LIMIT 2;
select found_rows();
SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION SELECT * FROM t2 LIMIT 100;
select found_rows();
SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 100 UNION SELECT * FROM t2;
select found_rows();
SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1 UNION SELECT * FROM t2;
select found_rows();
SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1 UNION SELECT * FROM t2 LIMIT 2;
select found_rows();
SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION SELECT * FROM t2 LIMIT 2,2;
select found_rows();
SELECT SQL_CALC_FOUND_ROWS * FROM t1 limit 2,2 UNION SELECT * FROM t2;
select found_rows();
# Test some limits with ORDER BY
SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a desc LIMIT 1;
(SELECT * FROM t1 ORDER by a) UNION ALL (SELECT * FROM t2 ORDER BY a) ORDER BY A desc LIMIT 4;
# Wrong usage
--error 1234
(SELECT * FROM t1) UNION all (SELECT SQL_CALC_FOUND_ROWS * FROM t2) LIMIT 1;
drop table t1,t2;
...@@ -4147,8 +4147,11 @@ void Field_blob::store(const char *from,uint len) ...@@ -4147,8 +4147,11 @@ void Field_blob::store(const char *from,uint len)
} }
} }
#endif /* USE_TIS620 */ #endif /* USE_TIS620 */
value.copy(from,len); if (from != value.ptr()) // For valgrind
from=value.ptr(); {
value.copy(from, len);
from= value.ptr();
}
#ifdef USE_TIS620 #ifdef USE_TIS620
my_free(th_ptr,MYF(MY_ALLOW_ZERO_PTR)); my_free(th_ptr,MYF(MY_ALLOW_ZERO_PTR));
#endif #endif
......
...@@ -28,7 +28,6 @@ InnoDB */ ...@@ -28,7 +28,6 @@ InnoDB */
#include "mysql_priv.h" #include "mysql_priv.h"
#include "slave.h" #include "slave.h"
#include "sql_cache.h"
#ifdef HAVE_INNOBASE_DB #ifdef HAVE_INNOBASE_DB
#include <m_ctype.h> #include <m_ctype.h>
......
...@@ -1045,15 +1045,18 @@ void Item_func_in::fix_length_and_dec() ...@@ -1045,15 +1045,18 @@ void Item_func_in::fix_length_and_dec()
array= new in_double(arg_count); array= new in_double(arg_count);
break; break;
} }
uint j=0; if (array && !(current_thd->fatal_error)) // If not EOM
for (uint i=0 ; i < arg_count ; i++)
{ {
array->set(j,args[i]); uint j=0;
if (!args[i]->null_value) // Skip NULL values for (uint i=0 ; i < arg_count ; i++)
j++; {
array->set(j,args[i]);
if (!args[i]->null_value) // Skip NULL values
j++;
}
if ((array->used_count=j))
array->sort();
} }
if ((array->used_count=j))
array->sort();
} }
else else
{ {
......
...@@ -300,15 +300,15 @@ void Item_sum_std::reset_field() ...@@ -300,15 +300,15 @@ void Item_sum_std::reset_field()
} }
} }
void Item_sum_std::update_field(int offset) void Item_sum_std::update_field()
{ {
double nr,old_nr,old_sqr; double nr,old_nr,old_sqr;
longlong field_count; longlong field_count;
char *res=result_field->ptr; char *res=result_field->ptr;
float8get(old_nr,res+offset); float8get(old_nr, res);
float8get(old_sqr,res+offset+sizeof(double)); float8get(old_sqr, res+sizeof(double));
field_count=sint8korr(res+offset+sizeof(double)*2); field_count=sint8korr(res+sizeof(double)*2);
nr=args[0]->val(); nr=args[0]->val();
if (!args[0]->null_value) if (!args[0]->null_value)
...@@ -619,12 +619,12 @@ void Item_sum_bit::reset_field() ...@@ -619,12 +619,12 @@ void Item_sum_bit::reset_field()
** calc next value and merge it with field_value ** calc next value and merge it with field_value
*/ */
void Item_sum_sum::update_field(int offset) void Item_sum_sum::update_field()
{ {
double old_nr,nr; double old_nr,nr;
char *res=result_field->ptr; char *res=result_field->ptr;
float8get(old_nr,res+offset); float8get(old_nr,res);
nr=args[0]->val(); nr=args[0]->val();
if (!args[0]->null_value) if (!args[0]->null_value)
{ {
...@@ -635,12 +635,12 @@ void Item_sum_sum::update_field(int offset) ...@@ -635,12 +635,12 @@ void Item_sum_sum::update_field(int offset)
} }
void Item_sum_count::update_field(int offset) void Item_sum_count::update_field()
{ {
longlong nr; longlong nr;
char *res=result_field->ptr; char *res=result_field->ptr;
nr=sint8korr(res+offset); nr=sint8korr(res);
if (!args[0]->maybe_null) if (!args[0]->maybe_null)
nr++; nr++;
else else
...@@ -653,14 +653,14 @@ void Item_sum_count::update_field(int offset) ...@@ -653,14 +653,14 @@ void Item_sum_count::update_field(int offset)
} }
void Item_sum_avg::update_field(int offset) void Item_sum_avg::update_field()
{ {
double nr,old_nr; double nr,old_nr;
longlong field_count; longlong field_count;
char *res=result_field->ptr; char *res=result_field->ptr;
float8get(old_nr,res+offset); float8get(old_nr,res);
field_count=sint8korr(res+offset+sizeof(double)); field_count=sint8korr(res+sizeof(double));
nr=args[0]->val(); nr=args[0]->val();
if (!args[0]->null_value) if (!args[0]->null_value)
...@@ -673,78 +673,66 @@ void Item_sum_avg::update_field(int offset) ...@@ -673,78 +673,66 @@ void Item_sum_avg::update_field(int offset)
int8store(res,field_count); int8store(res,field_count);
} }
void Item_sum_hybrid::update_field(int offset) void Item_sum_hybrid::update_field()
{ {
if (hybrid_type == STRING_RESULT) if (hybrid_type == STRING_RESULT)
min_max_update_str_field(offset); min_max_update_str_field();
else if (hybrid_type == INT_RESULT) else if (hybrid_type == INT_RESULT)
min_max_update_int_field(offset); min_max_update_int_field();
else else
min_max_update_real_field(offset); min_max_update_real_field();
} }
void void
Item_sum_hybrid::min_max_update_str_field(int offset) Item_sum_hybrid::min_max_update_str_field()
{ {
String *res_str=args[0]->val_str(&value); String *res_str=args[0]->val_str(&value);
if (args[0]->null_value) if (!args[0]->null_value)
result_field->copy_from_tmp(offset); // Use old value
else
{ {
res_str->strip_sp(); res_str->strip_sp();
result_field->ptr+=offset; // Get old max/min
result_field->val_str(&tmp_value,&tmp_value); result_field->val_str(&tmp_value,&tmp_value);
result_field->ptr-=offset;
if (result_field->is_null() || if (result_field->is_null() ||
(cmp_sign * (binary ? stringcmp(res_str,&tmp_value) : (cmp_sign * (binary ? stringcmp(res_str,&tmp_value) :
sortcmp(res_str,&tmp_value)) < 0)) sortcmp(res_str,&tmp_value)) < 0))
result_field->store(res_str->ptr(),res_str->length()); result_field->store(res_str->ptr(),res_str->length());
else
{ // Use old value
char *res=result_field->ptr;
memcpy(res,res+offset,result_field->pack_length());
}
result_field->set_notnull(); result_field->set_notnull();
} }
} }
void void
Item_sum_hybrid::min_max_update_real_field(int offset) Item_sum_hybrid::min_max_update_real_field()
{ {
double nr,old_nr; double nr,old_nr;
result_field->ptr+=offset;
old_nr=result_field->val_real(); old_nr=result_field->val_real();
nr=args[0]->val(); nr=args[0]->val();
if (!args[0]->null_value) if (!args[0]->null_value)
{ {
if (result_field->is_null(offset) || if (result_field->is_null(0) ||
(cmp_sign > 0 ? old_nr > nr : old_nr < nr)) (cmp_sign > 0 ? old_nr > nr : old_nr < nr))
old_nr=nr; old_nr=nr;
result_field->set_notnull(); result_field->set_notnull();
} }
else if (result_field->is_null(offset)) else if (result_field->is_null(0))
result_field->set_null(); result_field->set_null();
result_field->ptr-=offset;
result_field->store(old_nr); result_field->store(old_nr);
} }
void void
Item_sum_hybrid::min_max_update_int_field(int offset) Item_sum_hybrid::min_max_update_int_field()
{ {
longlong nr,old_nr; longlong nr,old_nr;
result_field->ptr+=offset;
old_nr=result_field->val_int(); old_nr=result_field->val_int();
nr=args[0]->val_int(); nr=args[0]->val_int();
if (!args[0]->null_value) if (!args[0]->null_value)
{ {
if (result_field->is_null(offset)) if (result_field->is_null(0))
old_nr=nr; old_nr=nr;
else else
{ {
...@@ -757,30 +745,29 @@ Item_sum_hybrid::min_max_update_int_field(int offset) ...@@ -757,30 +745,29 @@ Item_sum_hybrid::min_max_update_int_field(int offset)
} }
result_field->set_notnull(); result_field->set_notnull();
} }
else if (result_field->is_null(offset)) else if (result_field->is_null(0))
result_field->set_null(); result_field->set_null();
result_field->ptr-=offset;
result_field->store(old_nr); result_field->store(old_nr);
} }
void Item_sum_or::update_field(int offset) void Item_sum_or::update_field()
{ {
ulonglong nr; ulonglong nr;
char *res=result_field->ptr; char *res=result_field->ptr;
nr=uint8korr(res+offset); nr=uint8korr(res);
nr|= (ulonglong) args[0]->val_int(); nr|= (ulonglong) args[0]->val_int();
int8store(res,nr); int8store(res,nr);
} }
void Item_sum_and::update_field(int offset) void Item_sum_and::update_field()
{ {
ulonglong nr; ulonglong nr;
char *res=result_field->ptr; char *res=result_field->ptr;
nr=uint8korr(res+offset); nr=uint8korr(res);
nr&= (ulonglong) args[0]->val_int(); nr&= (ulonglong) args[0]->val_int();
int8store(res,nr); int8store(res,nr);
} }
......
...@@ -56,7 +56,7 @@ class Item_sum :public Item_result_field ...@@ -56,7 +56,7 @@ class Item_sum :public Item_result_field
virtual void reset()=0; virtual void reset()=0;
virtual bool add()=0; virtual bool add()=0;
virtual void reset_field()=0; virtual void reset_field()=0;
virtual void update_field(int offset)=0; virtual void update_field()=0;
virtual bool keep_field_type(void) const { return 0; } virtual bool keep_field_type(void) const { return 0; }
virtual void fix_length_and_dec() { maybe_null=1; null_value=1; } virtual void fix_length_and_dec() { maybe_null=1; null_value=1; }
virtual const char *func_name() const { return "?"; } virtual const char *func_name() const { return "?"; }
...@@ -116,7 +116,7 @@ class Item_sum_sum :public Item_sum_num ...@@ -116,7 +116,7 @@ class Item_sum_sum :public Item_sum_num
bool add(); bool add();
double val(); double val();
void reset_field(); void reset_field();
void update_field(int offset); void update_field();
void no_rows_in_result() {} void no_rows_in_result() {}
const char *func_name() const { return "sum"; } const char *func_name() const { return "sum"; }
unsigned int size_of() { return sizeof(*this);} unsigned int size_of() { return sizeof(*this);}
...@@ -141,7 +141,7 @@ class Item_sum_count :public Item_sum_int ...@@ -141,7 +141,7 @@ class Item_sum_count :public Item_sum_int
void make_const(longlong count_arg) { count=count_arg; used_table_cache=0; } void make_const(longlong count_arg) { count=count_arg; used_table_cache=0; }
longlong val_int(); longlong val_int();
void reset_field(); void reset_field();
void update_field(int offset); void update_field();
const char *func_name() const { return "count"; } const char *func_name() const { return "count"; }
unsigned int size_of() { return sizeof(*this);} unsigned int size_of() { return sizeof(*this);}
}; };
...@@ -193,7 +193,7 @@ class Item_sum_count_distinct :public Item_sum_int ...@@ -193,7 +193,7 @@ class Item_sum_count_distinct :public Item_sum_int
bool add(); bool add();
longlong val_int(); longlong val_int();
void reset_field() { return ;} // Never called void reset_field() { return ;} // Never called
void update_field(int offset) { return ; } // Never called void update_field() { return ; } // Never called
const char *func_name() const { return "count_distinct"; } const char *func_name() const { return "count_distinct"; }
bool setup(THD *thd); bool setup(THD *thd);
void no_rows_in_result() {} void no_rows_in_result() {}
...@@ -235,7 +235,7 @@ class Item_sum_avg :public Item_sum_num ...@@ -235,7 +235,7 @@ class Item_sum_avg :public Item_sum_num
bool add(); bool add();
double val(); double val();
void reset_field(); void reset_field();
void update_field(int offset); void update_field();
Item *result_item(Field *field) Item *result_item(Field *field)
{ return new Item_avg_field(this); } { return new Item_avg_field(this); }
const char *func_name() const { return "avg"; } const char *func_name() const { return "avg"; }
...@@ -273,7 +273,7 @@ class Item_sum_std :public Item_sum_num ...@@ -273,7 +273,7 @@ class Item_sum_std :public Item_sum_num
bool add(); bool add();
double val(); double val();
void reset_field(); void reset_field();
void update_field(int offset); void update_field();
Item *result_item(Field *field) Item *result_item(Field *field)
{ return new Item_std_field(this); } { return new Item_std_field(this); }
const char *func_name() const { return "std"; } const char *func_name() const { return "std"; }
...@@ -316,10 +316,10 @@ class Item_sum_hybrid :public Item_sum ...@@ -316,10 +316,10 @@ class Item_sum_hybrid :public Item_sum
void make_const() { used_table_cache=0; } void make_const() { used_table_cache=0; }
bool keep_field_type(void) const { return 1; } bool keep_field_type(void) const { return 1; }
enum Item_result result_type () const { return hybrid_type; } enum Item_result result_type () const { return hybrid_type; }
void update_field(int offset); void update_field();
void min_max_update_str_field(int offset); void min_max_update_str_field();
void min_max_update_real_field(int offset); void min_max_update_real_field();
void min_max_update_int_field(int offset); void min_max_update_int_field();
unsigned int size_of() { return sizeof(*this);} unsigned int size_of() { return sizeof(*this);}
}; };
...@@ -371,7 +371,7 @@ class Item_sum_or :public Item_sum_bit ...@@ -371,7 +371,7 @@ class Item_sum_or :public Item_sum_bit
public: public:
Item_sum_or(Item *item_par) :Item_sum_bit(item_par,LL(0)) {} Item_sum_or(Item *item_par) :Item_sum_bit(item_par,LL(0)) {}
bool add(); bool add();
void update_field(int offset); void update_field();
const char *func_name() const { return "bit_or"; } const char *func_name() const { return "bit_or"; }
unsigned int size_of() { return sizeof(*this);} unsigned int size_of() { return sizeof(*this);}
}; };
...@@ -382,7 +382,7 @@ class Item_sum_and :public Item_sum_bit ...@@ -382,7 +382,7 @@ class Item_sum_and :public Item_sum_bit
public: public:
Item_sum_and(Item *item_par) :Item_sum_bit(item_par, ~(ulonglong) LL(0)) {} Item_sum_and(Item *item_par) :Item_sum_bit(item_par, ~(ulonglong) LL(0)) {}
bool add(); bool add();
void update_field(int offset); void update_field();
const char *func_name() const { return "bit_and"; } const char *func_name() const { return "bit_and"; }
unsigned int size_of() { return sizeof(*this);} unsigned int size_of() { return sizeof(*this);}
}; };
...@@ -414,7 +414,7 @@ class Item_udf_sum : public Item_sum ...@@ -414,7 +414,7 @@ class Item_udf_sum : public Item_sum
void reset(); void reset();
bool add(); bool add();
void reset_field() {}; void reset_field() {};
void update_field(int offset_arg) {}; void update_field() {};
unsigned int size_of() { return sizeof(*this);} unsigned int size_of() { return sizeof(*this);}
}; };
...@@ -482,7 +482,7 @@ class Item_sum_udf_float :public Item_sum_num ...@@ -482,7 +482,7 @@ class Item_sum_udf_float :public Item_sum_num
double val() { return 0.0; } double val() { return 0.0; }
void reset() {} void reset() {}
bool add() { return 0; } bool add() { return 0; }
void update_field(int offset) {} void update_field() {}
}; };
...@@ -497,7 +497,7 @@ class Item_sum_udf_int :public Item_sum_num ...@@ -497,7 +497,7 @@ class Item_sum_udf_int :public Item_sum_num
double val() { return 0; } double val() { return 0; }
void reset() {} void reset() {}
bool add() { return 0; } bool add() { return 0; }
void update_field(int offset) {} void update_field() {}
}; };
...@@ -515,7 +515,7 @@ class Item_sum_udf_str :public Item_sum_num ...@@ -515,7 +515,7 @@ class Item_sum_udf_str :public Item_sum_num
enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
void reset() {} void reset() {}
bool add() { return 0; } bool add() { return 0; }
void update_field(int offset) {} void update_field() {}
}; };
#endif /* HAVE_DLOPEN */ #endif /* HAVE_DLOPEN */
...@@ -42,7 +42,7 @@ class Item_sum_unique_users :public Item_sum_num ...@@ -42,7 +42,7 @@ class Item_sum_unique_users :public Item_sum_num
void reset() {} void reset() {}
bool add() { return 0; } bool add() { return 0; }
void reset_field() {} void reset_field() {}
void update_field(int offset) {} void update_field() {}
bool fix_fields(THD *thd,struct st_table_list *tlist) { return 0;} bool fix_fields(THD *thd,struct st_table_list *tlist) { return 0;}
unsigned int size_of() { return sizeof(*this);} unsigned int size_of() { return sizeof(*this);}
}; };
...@@ -263,7 +263,8 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, ...@@ -263,7 +263,8 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
an extension for the binary log files. an extension for the binary log files.
In this case we write a standard header to it. In this case we write a standard header to it.
*/ */
if (my_b_safe_write(&log_file, (byte*) BINLOG_MAGIC, BIN_LOG_HEADER_SIZE)) if (my_b_safe_write(&log_file, (byte*) BINLOG_MAGIC,
BIN_LOG_HEADER_SIZE))
goto err; goto err;
bytes_written += BIN_LOG_HEADER_SIZE; bytes_written += BIN_LOG_HEADER_SIZE;
write_file_name_to_index_file=1; write_file_name_to_index_file=1;
......
...@@ -3833,7 +3833,7 @@ replicating a LOAD DATA INFILE command", ...@@ -3833,7 +3833,7 @@ replicating a LOAD DATA INFILE command",
"Max packetlength to send/receive from to server.", "Max packetlength to send/receive from to server.",
(gptr*) &global_system_variables.max_allowed_packet, (gptr*) &global_system_variables.max_allowed_packet,
(gptr*) &max_system_variables.max_allowed_packet, 0, GET_ULONG, (gptr*) &max_system_variables.max_allowed_packet, 0, GET_ULONG,
REQUIRED_ARG, 1024*1024L, 80, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0}, REQUIRED_ARG, 1024*1024L, 1024, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
{"max_binlog_cache_size", OPT_MAX_BINLOG_CACHE_SIZE, {"max_binlog_cache_size", OPT_MAX_BINLOG_CACHE_SIZE,
"Can be used to restrict the total size used to cache a multi-transaction query.", "Can be used to restrict the total size used to cache a multi-transaction query.",
(gptr*) &max_binlog_cache_size, (gptr*) &max_binlog_cache_size, 0, (gptr*) &max_binlog_cache_size, (gptr*) &max_binlog_cache_size, 0,
......
...@@ -215,10 +215,12 @@ int net_flush(NET *net) ...@@ -215,10 +215,12 @@ int net_flush(NET *net)
*****************************************************************************/ *****************************************************************************/
/* /*
** Write a logical packet with packet header Write a logical packet with packet header
** Format: Packet length (3 bytes), packet number(1 byte) Format: Packet length (3 bytes), packet number(1 byte)
** When compression is used a 3 byte compression length is added When compression is used a 3 byte compression length is added
** NOTE: If compression is used the original package is modified!
NOTE
If compression is used the original package is modified!
*/ */
int int
...@@ -315,8 +317,8 @@ net_write_command(NET *net,uchar command,const char *packet,ulong len) ...@@ -315,8 +317,8 @@ net_write_command(NET *net,uchar command,const char *packet,ulong len)
The cached buffer can be sent as it is with 'net_flush()'. The cached buffer can be sent as it is with 'net_flush()'.
In this code we have to be careful to not send a packet longer than In this code we have to be careful to not send a packet longer than
MAX_PACKET_LENGTH to net_real_write() if we are using the compressed protocol MAX_PACKET_LENGTH to net_real_write() if we are using the compressed
as we store the length of the compressed packet in 3 bytes. protocol as we store the length of the compressed packet in 3 bytes.
RETURN RETURN
0 ok 0 ok
...@@ -821,20 +823,23 @@ my_net_read(NET *net) ...@@ -821,20 +823,23 @@ my_net_read(NET *net)
{ {
/* We are using the compressed protocol */ /* We are using the compressed protocol */
ulong buf_length= net->buf_length; ulong buf_length;
ulong start_of_packet= net->buf_length - net->remain_in_buf; ulong start_of_packet;
ulong first_packet_offset=start_of_packet; ulong first_packet_offset;
uint read_length, multi_byte_packet=0; uint read_length, multi_byte_packet=0;
if (net->remain_in_buf) if (net->remain_in_buf)
{ {
buf_length= net->buf_length; // Data left in old packet
first_packet_offset= start_of_packet= (net->buf_length -
net->remain_in_buf);
/* Restore the character that was overwritten by the end 0 */ /* Restore the character that was overwritten by the end 0 */
net->buff[start_of_packet]=net->save_char; net->buff[start_of_packet]= net->save_char;
} }
else else
{ {
/* reuse buffer, as there is nothing in it that we need */ /* reuse buffer, as there is nothing in it that we need */
buf_length=start_of_packet=first_packet_offset=0; buf_length= start_of_packet= first_packet_offset= 0;
} }
for (;;) for (;;)
{ {
......
...@@ -7224,7 +7224,7 @@ update_tmptable_sum_func(Item_sum **func_ptr, ...@@ -7224,7 +7224,7 @@ update_tmptable_sum_func(Item_sum **func_ptr,
{ {
Item_sum *func; Item_sum *func;
while ((func= *(func_ptr++))) while ((func= *(func_ptr++)))
func->update_field(0); func->update_field();
} }
......
...@@ -31,9 +31,10 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) ...@@ -31,9 +31,10 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
ORDER *order; ORDER *order;
List<Item> item_list; List<Item> item_list;
TABLE *table; TABLE *table;
int describe=(lex->select_lex.options & SELECT_DESCRIBE) ? 1 : 0;
int res; int res;
bool found_rows_for_union= lex->select_lex.options & OPTION_FOUND_ROWS; ulonglong add_rows= 0;
ulong found_rows_for_union= lex->select_lex.options & OPTION_FOUND_ROWS;
ulong describe= lex->select_lex.options & SELECT_DESCRIBE;
TABLE_LIST result_table_list; TABLE_LIST result_table_list;
TABLE_LIST *first_table=(TABLE_LIST *)lex->select_lex.table_list.first; TABLE_LIST *first_table=(TABLE_LIST *)lex->select_lex.table_list.first;
TMP_TABLE_PARAM tmp_table_param; TMP_TABLE_PARAM tmp_table_param;
...@@ -135,14 +136,44 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) ...@@ -135,14 +136,44 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
union_result->tmp_table_param=&tmp_table_param; union_result->tmp_table_param=&tmp_table_param;
for (sl= &lex->select_lex; sl; sl=sl->next) for (sl= &lex->select_lex; sl; sl=sl->next)
{ {
ha_rows records_at_start;
lex->select=sl; lex->select=sl;
thd->offset_limit=sl->offset_limit; /* Don't use offset for the last union if there is no braces */
thd->select_limit=sl->select_limit+sl->offset_limit; if (sl != lex_sl)
{
thd->offset_limit= sl->offset_limit;
thd->select_limit=sl->select_limit+sl->offset_limit;
}
else
{
thd->offset_limit= 0;
/*
We can't use LIMIT at this stage if we are using ORDER BY for the
whole query
*/
thd->select_limit= HA_POS_ERROR;
if (! sl->order_list.first)
thd->select_limit= sl->select_limit+sl->offset_limit;
}
if (thd->select_limit < sl->select_limit) if (thd->select_limit < sl->select_limit)
thd->select_limit= HA_POS_ERROR; // no limit thd->select_limit= HA_POS_ERROR; // no limit
/*
When using braces, SQL_CALC_FOUND_ROWS affects the whole query.
We don't calculate found_rows() per union part
*/
if (thd->select_limit == HA_POS_ERROR || sl->braces) if (thd->select_limit == HA_POS_ERROR || sl->braces)
sl->options&= ~OPTION_FOUND_ROWS; sl->options&= ~OPTION_FOUND_ROWS;
else
{
/*
We are doing an union without braces. In this case
SQL_CALC_FOUND_ROWS should be done on all sub parts
*/
sl->options|= found_rows_for_union;
}
records_at_start= table->file->records;
res=mysql_select(thd, (describe && sl->linkage==NOT_A_SELECT) ? res=mysql_select(thd, (describe && sl->linkage==NOT_A_SELECT) ?
first_table : (TABLE_LIST*) sl->table_list.first, first_table : (TABLE_LIST*) sl->table_list.first,
sl->item_list, sl->item_list,
...@@ -153,10 +184,23 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) ...@@ -153,10 +184,23 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
sl->having, sl->having,
(ORDER*) NULL, (ORDER*) NULL,
sl->options | thd->options | SELECT_NO_UNLOCK | sl->options | thd->options | SELECT_NO_UNLOCK |
((describe) ? SELECT_DESCRIBE : 0), describe,
union_result); union_result);
if (res) if (res)
goto exit; goto exit;
/* Needed for the following test and for records_at_start in next loop */
table->file->info(HA_STATUS_VARIABLE);
if (found_rows_for_union & sl->options)
{
/*
This is a union without braces. Remember the number of rows that could
also have been part of the result set.
We get this from the difference of between total number of possible
rows and actual rows added to the temporary table.
*/
add_rows+= (ulonglong) (thd->limit_found_rows - (table->file->records -
records_at_start));
}
} }
if (union_result->flush()) if (union_result->flush())
{ {
...@@ -172,19 +216,14 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) ...@@ -172,19 +216,14 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
/* Create a list of fields in the temporary table */ /* Create a list of fields in the temporary table */
List_iterator<Item> it(item_list); List_iterator<Item> it(item_list);
Field **field; Field **field;
#if 0
List<Item_func_match> ftfunc_list;
ftfunc_list.empty();
#else
thd->lex.select_lex.ftfunc_list.empty(); thd->lex.select_lex.ftfunc_list.empty();
#endif
for (field=table->field ; *field ; field++) for (field=table->field ; *field ; field++)
{ {
(void) it++; (void) it++;
(void) it.replace(new Item_field(*field)); (void) it.replace(new Item_field(*field));
} }
if (!thd->fatal_error) // Check if EOM if (!thd->fatal_error) // Check if EOM
{ {
if (lex_sl) if (lex_sl)
{ {
...@@ -209,8 +248,8 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) ...@@ -209,8 +248,8 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
item_list, NULL, (describe) ? 0 : order, item_list, NULL, (describe) ? 0 : order,
(ORDER*) NULL, NULL, (ORDER*) NULL, (ORDER*) NULL, NULL, (ORDER*) NULL,
thd->options, result); thd->options, result);
if (found_rows_for_union && !res) if (!res)
thd->limit_found_rows = (ulonglong)table->file->records; thd->limit_found_rows = (ulonglong)table->file->records + add_rows;
} }
} }
......
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