summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <monty@narttu.mysql.fi>2003-08-20 16:25:44 +0300
committerunknown <monty@narttu.mysql.fi>2003-08-20 16:25:44 +0300
commitde5d47c35d426a84cb0fd453dfdc17012dc8ba55 (patch)
tree4d61f552796b268be72317d81fd6051dd59c7966
parent9c5c6dafa16fe5c6e77b72a0dafa310417600901 (diff)
downloadmariadb-git-de5d47c35d426a84cb0fd453dfdc17012dc8ba55.tar.gz
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 include/m_string.h: Added memcpy_overlap() to avoid warnings when using valgrind on memcpy(A,A,...) myisam/mi_create.c: Fixed comment myisam/mi_search.c: Fix warning from valgrind myisam/mi_write.c: Indentation fix mysql-test/mysql-test-run.sh: Add options handled by general skip- option mysql-test/r/packet.result: Update results after change to mysqld (min max_allowed_packet length is now 1024) mysql-test/r/union.result: Added testing of UNION with SQL_CALC_FOUND_ROWS mysql-test/t/packet.test: Update results after change to mysqld (min max_allowed_packet length is now 1024) mysql-test/t/union.test: Added testing of UNION with SQL_CALC_FOUND_ROWS sql/field.cc: Fix to remove waarning from valgrind sql/ha_innodb.cc: Remove wrong include file sql/item_cmpfunc.cc: Safety fix to handle EOM conditions in IN sql/item_sum.cc: Fixed prototype for update_field() (argument was alwys 0) sql/item_sum.h: Fixed prototype for update_field() (argument was alwys 0) sql/item_uniq.h: Fixed prototype for update_field() (argument was alwys 0) sql/log.cc: Indentation fix sql/mysqld.cc: Set min value of max_allowed_packet to 1024 (to avoid it getting set to 0) sql/net_serv.cc: Indentation changes + trivial optimization sql/sql_select.cc: Fixed prototype for update_field() (argument was alwys 0) sql/sql_union.cc: Fixed problem with UNION's without braces and - SQL_CALC_FOUND_ROWS - LIMIT #,# - ORDER BY ... LIMIT
-rw-r--r--include/m_string.h12
-rw-r--r--myisam/mi_create.c2
-rw-r--r--myisam/mi_search.c10
-rw-r--r--myisam/mi_write.c1
-rw-r--r--mysql-test/mysql-test-run.sh6
-rw-r--r--mysql-test/r/packet.result12
-rw-r--r--mysql-test/r/union.result127
-rw-r--r--mysql-test/t/packet.test6
-rw-r--r--mysql-test/t/union.test56
-rw-r--r--sql/field.cc7
-rw-r--r--sql/ha_innodb.cc1
-rw-r--r--sql/item_cmpfunc.cc17
-rw-r--r--sql/item_sum.cc67
-rw-r--r--sql/item_sum.h32
-rw-r--r--sql/item_uniq.h2
-rw-r--r--sql/log.cc3
-rw-r--r--sql/mysqld.cc2
-rw-r--r--sql/net_serv.cc27
-rw-r--r--sql/sql_select.cc2
-rw-r--r--sql/sql_union.cc65
20 files changed, 342 insertions, 115 deletions
diff --git a/include/m_string.h b/include/m_string.h
index c6943613b1a..eae0e8f3f94 100644
--- a/include/m_string.h
+++ b/include/m_string.h
@@ -119,6 +119,18 @@ extern void bmove_allign(gptr dst,const gptr src,uint len);
#define bmove512(A,B,C) memcpy(A,B,C)
#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 */
#if !defined(bfill) && !defined(HAVE_BFILL)
diff --git a/myisam/mi_create.c b/myisam/mi_create.c
index 9082c2b0d95..9f39c6f522e 100644
--- a/myisam/mi_create.c
+++ b/myisam/mi_create.c
@@ -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].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 |
HA_VAR_LENGTH)))
{
diff --git a/myisam/mi_search.c b/myisam/mi_search.c
index 32db69144d8..423b15ff8f7 100644
--- a/myisam/mi_search.c
+++ b/myisam/mi_search.c
@@ -1218,9 +1218,10 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
register uchar **page_pos, register uchar *key)
{
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;
+ page= *page_pos;
page_end=page+MI_MAX_KEY_BUFF+1;
start_key=key;
@@ -1276,7 +1277,9 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
length-=tmp;
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;
from+=length;
}
@@ -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;
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->prev_key=org_key;
if (prev_key) /* If not first key in block */
diff --git a/myisam/mi_write.c b/myisam/mi_write.c
index d39bbbf5fc7..40e2f301fce 100644
--- a/myisam/mi_write.c
+++ b/myisam/mi_write.c
@@ -887,4 +887,3 @@ void mi_end_bulk_insert(MI_INFO *info)
info->bulk_insert=0;
}
}
-
diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh
index 55adc3d88fc..bf5546483d3 100644
--- a/mysql-test/mysql-test-run.sh
+++ b/mysql-test/mysql-test-run.sh
@@ -253,12 +253,6 @@ while test $# -gt 0; do
--start-and-exit)
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-test=*) SKIP_TEST=`$ECHO "$1" | $SED -e "s;--skip-test=;;"`;;
--do-test=*) DO_TEST=`$ECHO "$1" | $SED -e "s;--do-test=;;"`;;
diff --git a/mysql-test/r/packet.result b/mysql-test/r/packet.result
index e994e4d63da..6733f2b142e 100644
--- a/mysql-test/r/packet.result
+++ b/mysql-test/r/packet.result
@@ -5,12 +5,12 @@ set net_buffer_length=100;
SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len;
len
1024
-select repeat('a',200);
-repeat('a',200)
+select repeat('a',2000);
+repeat('a',2000)
NULL
select @@net_buffer_length, @@max_allowed_packet;
@@net_buffer_length @@max_allowed_packet
-1024 80
+1024 1024
SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len;
Got a packet bigger than 'max_allowed_packet'
set global max_allowed_packet=default;
@@ -20,6 +20,6 @@ set net_buffer_length=default;
SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len;
len
100
-select length(repeat('a',200));
-length(repeat('a',200))
-200
+select length(repeat('a',2000));
+length(repeat('a',2000))
+2000
diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result
index 51d9f2d17ca..9899b8279e2 100644
--- a/mysql-test/r/union.result
+++ b/mysql-test/r/union.result
@@ -102,7 +102,7 @@ a b
2 b
select found_rows();
found_rows()
-6
+8
explain select a,b from t1 union all select a,b from t2;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 4
@@ -295,3 +295,128 @@ a b
5 f
6 e
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;
diff --git a/mysql-test/t/packet.test b/mysql-test/t/packet.test
index 5c4e7efcaf3..cbeaa04ca52 100644
--- a/mysql-test/t/packet.test
+++ b/mysql-test/t/packet.test
@@ -12,8 +12,8 @@ set global net_buffer_length=100;
set net_buffer_length=100;
# Have to be > 1024 as min value of net_buffer_length is 1024
SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len;
-# Should return NULL as 200 is bigger than max_allowed_packet
-select repeat('a',200);
+# Should return NULL as 2000 is bigger than max_allowed_packet
+select repeat('a',2000);
#
# Connection 2 should get error for too big packets
@@ -28,4 +28,4 @@ set max_allowed_packet=default;
set global net_buffer_length=default;
set net_buffer_length=default;
SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len;
-select length(repeat('a',200));
+select length(repeat('a',2000));
diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test
index 5f7eba83755..ea7bdb4ee1b 100644
--- a/mysql-test/t/union.test
+++ b/mysql-test/t/union.test
@@ -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 '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 1);
(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;
select * from t3;
select * from 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;
diff --git a/sql/field.cc b/sql/field.cc
index e56d53b1bda..592252bb294 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -4147,8 +4147,11 @@ void Field_blob::store(const char *from,uint len)
}
}
#endif /* USE_TIS620 */
- value.copy(from,len);
- from=value.ptr();
+ if (from != value.ptr()) // For valgrind
+ {
+ value.copy(from, len);
+ from= value.ptr();
+ }
#ifdef USE_TIS620
my_free(th_ptr,MYF(MY_ALLOW_ZERO_PTR));
#endif
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 09119a4eb54..3619fefdd1b 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -28,7 +28,6 @@ InnoDB */
#include "mysql_priv.h"
#include "slave.h"
-#include "sql_cache.h"
#ifdef HAVE_INNOBASE_DB
#include <m_ctype.h>
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 8c58c58a67d..7415fc5b98e 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1045,15 +1045,18 @@ void Item_func_in::fix_length_and_dec()
array= new in_double(arg_count);
break;
}
- uint j=0;
- for (uint i=0 ; i < arg_count ; i++)
+ if (array && !(current_thd->fatal_error)) // If not EOM
{
- array->set(j,args[i]);
- if (!args[i]->null_value) // Skip NULL values
- j++;
+ uint j=0;
+ for (uint i=0 ; i < arg_count ; i++)
+ {
+ 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
{
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index d88894d4fb4..08385bb9ca6 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -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;
longlong field_count;
char *res=result_field->ptr;
- float8get(old_nr,res+offset);
- float8get(old_sqr,res+offset+sizeof(double));
- field_count=sint8korr(res+offset+sizeof(double)*2);
+ float8get(old_nr, res);
+ float8get(old_sqr, res+sizeof(double));
+ field_count=sint8korr(res+sizeof(double)*2);
nr=args[0]->val();
if (!args[0]->null_value)
@@ -619,12 +619,12 @@ void Item_sum_bit::reset_field()
** 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;
char *res=result_field->ptr;
- float8get(old_nr,res+offset);
+ float8get(old_nr,res);
nr=args[0]->val();
if (!args[0]->null_value)
{
@@ -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;
char *res=result_field->ptr;
- nr=sint8korr(res+offset);
+ nr=sint8korr(res);
if (!args[0]->maybe_null)
nr++;
else
@@ -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;
longlong field_count;
char *res=result_field->ptr;
- float8get(old_nr,res+offset);
- field_count=sint8korr(res+offset+sizeof(double));
+ float8get(old_nr,res);
+ field_count=sint8korr(res+sizeof(double));
nr=args[0]->val();
if (!args[0]->null_value)
@@ -673,78 +673,66 @@ void Item_sum_avg::update_field(int offset)
int8store(res,field_count);
}
-void Item_sum_hybrid::update_field(int offset)
+void Item_sum_hybrid::update_field()
{
if (hybrid_type == STRING_RESULT)
- min_max_update_str_field(offset);
+ min_max_update_str_field();
else if (hybrid_type == INT_RESULT)
- min_max_update_int_field(offset);
+ min_max_update_int_field();
else
- min_max_update_real_field(offset);
+ min_max_update_real_field();
}
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);
- if (args[0]->null_value)
- result_field->copy_from_tmp(offset); // Use old value
- else
+ if (!args[0]->null_value)
{
res_str->strip_sp();
- result_field->ptr+=offset; // Get old max/min
result_field->val_str(&tmp_value,&tmp_value);
- result_field->ptr-=offset;
if (result_field->is_null() ||
(cmp_sign * (binary ? stringcmp(res_str,&tmp_value) :
sortcmp(res_str,&tmp_value)) < 0))
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();
}
}
void
-Item_sum_hybrid::min_max_update_real_field(int offset)
+Item_sum_hybrid::min_max_update_real_field()
{
double nr,old_nr;
- result_field->ptr+=offset;
old_nr=result_field->val_real();
nr=args[0]->val();
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))
old_nr=nr;
result_field->set_notnull();
}
- else if (result_field->is_null(offset))
+ else if (result_field->is_null(0))
result_field->set_null();
- result_field->ptr-=offset;
result_field->store(old_nr);
}
void
-Item_sum_hybrid::min_max_update_int_field(int offset)
+Item_sum_hybrid::min_max_update_int_field()
{
longlong nr,old_nr;
- result_field->ptr+=offset;
old_nr=result_field->val_int();
nr=args[0]->val_int();
if (!args[0]->null_value)
{
- if (result_field->is_null(offset))
+ if (result_field->is_null(0))
old_nr=nr;
else
{
@@ -757,30 +745,29 @@ Item_sum_hybrid::min_max_update_int_field(int offset)
}
result_field->set_notnull();
}
- else if (result_field->is_null(offset))
+ else if (result_field->is_null(0))
result_field->set_null();
- result_field->ptr-=offset;
result_field->store(old_nr);
}
-void Item_sum_or::update_field(int offset)
+void Item_sum_or::update_field()
{
ulonglong nr;
char *res=result_field->ptr;
- nr=uint8korr(res+offset);
+ nr=uint8korr(res);
nr|= (ulonglong) args[0]->val_int();
int8store(res,nr);
}
-void Item_sum_and::update_field(int offset)
+void Item_sum_and::update_field()
{
ulonglong nr;
char *res=result_field->ptr;
- nr=uint8korr(res+offset);
+ nr=uint8korr(res);
nr&= (ulonglong) args[0]->val_int();
int8store(res,nr);
}
diff --git a/sql/item_sum.h b/sql/item_sum.h
index 2369b5d1d7e..5189566fdfb 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -56,7 +56,7 @@ public:
virtual void reset()=0;
virtual bool add()=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 void fix_length_and_dec() { maybe_null=1; null_value=1; }
virtual const char *func_name() const { return "?"; }
@@ -116,7 +116,7 @@ class Item_sum_sum :public Item_sum_num
bool add();
double val();
void reset_field();
- void update_field(int offset);
+ void update_field();
void no_rows_in_result() {}
const char *func_name() const { return "sum"; }
unsigned int size_of() { return sizeof(*this);}
@@ -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; }
longlong val_int();
void reset_field();
- void update_field(int offset);
+ void update_field();
const char *func_name() const { return "count"; }
unsigned int size_of() { return sizeof(*this);}
};
@@ -193,7 +193,7 @@ class Item_sum_count_distinct :public Item_sum_int
bool add();
longlong val_int();
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"; }
bool setup(THD *thd);
void no_rows_in_result() {}
@@ -235,7 +235,7 @@ class Item_sum_avg :public Item_sum_num
bool add();
double val();
void reset_field();
- void update_field(int offset);
+ void update_field();
Item *result_item(Field *field)
{ return new Item_avg_field(this); }
const char *func_name() const { return "avg"; }
@@ -273,7 +273,7 @@ class Item_sum_std :public Item_sum_num
bool add();
double val();
void reset_field();
- void update_field(int offset);
+ void update_field();
Item *result_item(Field *field)
{ return new Item_std_field(this); }
const char *func_name() const { return "std"; }
@@ -316,10 +316,10 @@ class Item_sum_hybrid :public Item_sum
void make_const() { used_table_cache=0; }
bool keep_field_type(void) const { return 1; }
enum Item_result result_type () const { return hybrid_type; }
- void update_field(int offset);
- void min_max_update_str_field(int offset);
- void min_max_update_real_field(int offset);
- void min_max_update_int_field(int offset);
+ void update_field();
+ void min_max_update_str_field();
+ void min_max_update_real_field();
+ void min_max_update_int_field();
unsigned int size_of() { return sizeof(*this);}
};
@@ -371,7 +371,7 @@ class Item_sum_or :public Item_sum_bit
public:
Item_sum_or(Item *item_par) :Item_sum_bit(item_par,LL(0)) {}
bool add();
- void update_field(int offset);
+ void update_field();
const char *func_name() const { return "bit_or"; }
unsigned int size_of() { return sizeof(*this);}
};
@@ -382,7 +382,7 @@ class Item_sum_and :public Item_sum_bit
public:
Item_sum_and(Item *item_par) :Item_sum_bit(item_par, ~(ulonglong) LL(0)) {}
bool add();
- void update_field(int offset);
+ void update_field();
const char *func_name() const { return "bit_and"; }
unsigned int size_of() { return sizeof(*this);}
};
@@ -414,7 +414,7 @@ public:
void reset();
bool add();
void reset_field() {};
- void update_field(int offset_arg) {};
+ void update_field() {};
unsigned int size_of() { return sizeof(*this);}
};
@@ -482,7 +482,7 @@ class Item_sum_udf_float :public Item_sum_num
double val() { return 0.0; }
void reset() {}
bool add() { return 0; }
- void update_field(int offset) {}
+ void update_field() {}
};
@@ -497,7 +497,7 @@ public:
double val() { return 0; }
void reset() {}
bool add() { return 0; }
- void update_field(int offset) {}
+ void update_field() {}
};
@@ -515,7 +515,7 @@ public:
enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
void reset() {}
bool add() { return 0; }
- void update_field(int offset) {}
+ void update_field() {}
};
#endif /* HAVE_DLOPEN */
diff --git a/sql/item_uniq.h b/sql/item_uniq.h
index cc087832f49..de239d3a8ec 100644
--- a/sql/item_uniq.h
+++ b/sql/item_uniq.h
@@ -42,7 +42,7 @@ public:
void reset() {}
bool add() { return 0; }
void reset_field() {}
- void update_field(int offset) {}
+ void update_field() {}
bool fix_fields(THD *thd,struct st_table_list *tlist) { return 0;}
unsigned int size_of() { return sizeof(*this);}
};
diff --git a/sql/log.cc b/sql/log.cc
index 4dce26d23ea..7e12297d8ae 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -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.
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;
bytes_written += BIN_LOG_HEADER_SIZE;
write_file_name_to_index_file=1;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index d9ba97ad11a..b90ab1a4a3a 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -3833,7 +3833,7 @@ replicating a LOAD DATA INFILE command",
"Max packetlength to send/receive from to server.",
(gptr*) &global_system_variables.max_allowed_packet,
(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,
"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,
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index 13f786e0e75..8f0d659daf2 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -215,10 +215,12 @@ int net_flush(NET *net)
*****************************************************************************/
/*
-** Write a logical packet with packet header
-** Format: Packet length (3 bytes), packet number(1 byte)
-** When compression is used a 3 byte compression length is added
-** NOTE: If compression is used the original package is modified!
+ Write a logical packet with packet header
+ Format: Packet length (3 bytes), packet number(1 byte)
+ When compression is used a 3 byte compression length is added
+
+ NOTE
+ If compression is used the original package is modified!
*/
int
@@ -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()'.
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
- as we store the length of the compressed packet in 3 bytes.
+ MAX_PACKET_LENGTH to net_real_write() if we are using the compressed
+ protocol as we store the length of the compressed packet in 3 bytes.
RETURN
0 ok
@@ -821,20 +823,23 @@ my_net_read(NET *net)
{
/* We are using the compressed protocol */
- ulong buf_length= net->buf_length;
- ulong start_of_packet= net->buf_length - net->remain_in_buf;
- ulong first_packet_offset=start_of_packet;
+ ulong buf_length;
+ ulong start_of_packet;
+ ulong first_packet_offset;
uint read_length, multi_byte_packet=0;
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 */
- net->buff[start_of_packet]=net->save_char;
+ net->buff[start_of_packet]= net->save_char;
}
else
{
/* 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 (;;)
{
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 7922af04ea8..560f5f5dc79 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -7224,7 +7224,7 @@ update_tmptable_sum_func(Item_sum **func_ptr,
{
Item_sum *func;
while ((func= *(func_ptr++)))
- func->update_field(0);
+ func->update_field();
}
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index bd7bc7027d3..34acd79f18b 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -31,9 +31,10 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
ORDER *order;
List<Item> item_list;
TABLE *table;
- int describe=(lex->select_lex.options & SELECT_DESCRIBE) ? 1 : 0;
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 *first_table=(TABLE_LIST *)lex->select_lex.table_list.first;
TMP_TABLE_PARAM tmp_table_param;
@@ -135,14 +136,44 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
union_result->tmp_table_param=&tmp_table_param;
for (sl= &lex->select_lex; sl; sl=sl->next)
{
+ ha_rows records_at_start;
lex->select=sl;
- thd->offset_limit=sl->offset_limit;
- thd->select_limit=sl->select_limit+sl->offset_limit;
+ /* Don't use offset for the last union if there is no braces */
+ 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)
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)
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) ?
first_table : (TABLE_LIST*) sl->table_list.first,
sl->item_list,
@@ -153,10 +184,23 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
sl->having,
(ORDER*) NULL,
sl->options | thd->options | SELECT_NO_UNLOCK |
- ((describe) ? SELECT_DESCRIBE : 0),
+ describe,
union_result);
if (res)
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())
{
@@ -172,19 +216,14 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
/* Create a list of fields in the temporary table */
List_iterator<Item> it(item_list);
Field **field;
-#if 0
- List<Item_func_match> ftfunc_list;
- ftfunc_list.empty();
-#else
thd->lex.select_lex.ftfunc_list.empty();
-#endif
for (field=table->field ; *field ; field++)
{
(void) it++;
(void) it.replace(new Item_field(*field));
}
- if (!thd->fatal_error) // Check if EOM
+ if (!thd->fatal_error) // Check if EOM
{
if (lex_sl)
{
@@ -209,8 +248,8 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
item_list, NULL, (describe) ? 0 : order,
(ORDER*) NULL, NULL, (ORDER*) NULL,
thd->options, result);
- if (found_rows_for_union && !res)
- thd->limit_found_rows = (ulonglong)table->file->records;
+ if (!res)
+ thd->limit_found_rows = (ulonglong)table->file->records + add_rows;
}
}