From 84c2e91f1e57fa0b91f8608f0490f0389baf3fdc Mon Sep 17 00:00:00 2001
From: "Sinisa@sinisa.nasamreza.org" <>
Date: Wed, 20 Aug 2003 16:14:01 +0300
Subject: [PATCH] sql_union.cc:   Fix for SQL_CALC_FOUND_ROWS in UNION's

---
 mysql-test/r/union.result | 56 ++++++++++++++++++++++++++++++++++++++-
 mysql-test/t/union.test   | 16 +++++++++++
 sql/sql_union.cc          | 16 +++++++++--
 3 files changed, 85 insertions(+), 3 deletions(-)

diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result
index 51d9f2d17c..50f689e3e4 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,57 @@ a	b
 5	f
 6	e
 drop table t1,t2,t3,t4;
+CREATE TABLE t1 (  `IdUser` int(11) NOT NULL default '0',   `IdDirectMessage` int(11) NOT NULL default '0',   `Readed` datetime default NULL,   PRIMARY KEY  (`IdUser`,`IdDirectMessage`),   KEY `IdDirectMessage` (`IdDirectMessage`), );
+CREATE TABLE  t2 (   `IdDirectMessage` int(11) NOT NULL default '0',   `MessageData` text NOT NULL,   `DateOfMessage` datetime default NULL,   PRIMARY KEY  (`IdDirectMessage`) );
+INSERT INTO  t2 (`IdDirectMessage`, `MessageData`, `DateOfMessage`) VALUES   (1,'Texto','2003-08-06 00:00:00'),   (2,'Texto','2003-08-06 00:00:00'),   (3,'Texto','2003-08-06 00:00:00'),   (4,'Texto','2003-08-06 00:00:00'),   (5,'Texto','2003-08-06 00:00:00'),   (6,'Texto','2003-08-06 00:00:00'),   (7,'Texto','2003-08-06 00:00:00'),   (8,'Texto','2003-08-06 00:00:00'),   (9,'Texto','2003-08-06 00:00:00'),   (10,'Texto','2003-08-06 00:00:00'),   (11,'Texto','2003-08-06 00:00:00'),   (12,'Texto','2003-08-06 00:00:00'),   (13,'Texto','2003-08-06 00:00:00'),   (14,'Texto','2003-08-06 00:00:00'),   (15,'Texto','2003-08-06 00:00:00'),   (16,'Texto','2003-08-06 00:00:00'),   (17,'Texto','2003-08-06 00:00:00'),   (18,'Texto','2003-08-06 00:00:00'),   (19,'Texto','2003-08-06 00:00:00'),   (20,'Texto','2003-08-06 00:00:00'),   (21,'Texto','2003-08-06 00:00:00'),   (22,'Texto','2003-08-06 00:00:00');
+INSERT INTO t1 (`IdUser`, `IdDirectMessage`, `Readed`) VALUES   (4,1,'2003-08-07 10:10:13'),   (4,2,'2003-08-07 10:10:13'),   (4,3,'2003-08-07 10:10:13'),   (4,4,'2003-08-07 10:10:13'),   (4,5,'2003-08-07 10:10:13'),   (4,6,'2003-08-07 10:10:13'),   (4,7,'2003-08-07 10:10:13'),   (4,8,'2003-08-07 10:10:13'),   (4,9,'2003-08-07 10:10:13'),   (4,10,'2003-08-07 10:10:13'),   (4,11,'2003-08-07 10:10:13'),   (4,12,'2003-08-07 10:10:13'),   (4,13,'2003-08-07 10:10:13'),   (4,14,'2003-08-07 10:10:13'),   (4,15,'2003-08-07 10:10:13'),   (4,16,'2003-08-07 10:10:13'),   (4,17,'2003-08-07 10:10:13'),   (4,18,'2003-08-07 10:10:13'),   (4,19,'2003-08-07 10:10:13'),   (4,20,'2003-08-07 10:10:13'),   (4,21,'2003-08-06 16:51:04'),   (4,22,'2003-08-06 16:51:19');
+SELECT SQL_CALC_FOUND_ROWS t2.* FROM t2 INNER JOIN t1 ON t2.IdDirectMessage = t1.IdDirectMessage WHERE IdUser = 4 AND Readed Is NULL UNION SELECT t2.* FROM t2 INNER JOIN t1 ON t2.IdDirectMessage = t1.IdDirectMessage WHERE IdUser = 4 AND NOT (t1.Readed is NULL) ORDER BY DateOfMessage Limit 0,2;
+IdDirectMessage	MessageData	DateOfMessage
+1	Texto	2003-08-06 00:00:00
+2	Texto	2003-08-06 00:00:00
+SELECT FOUND_ROWS();
+FOUND_ROWS()
+22
+SELECT SQL_CALC_FOUND_ROWS t2.* FROM t2 INNER JOIN t1 ON t2.IdDirectMessage = t1.IdDirectMessage WHERE IdUser = 4 AND Readed Is NULL UNION ALL  SELECT t2.* FROM t2 INNER JOIN t1 ON t2.IdDirectMessage = t1.IdDirectMessage WHERE IdUser = 4 AND NOT (t1.Readed is NULL) ORDER BY DateOfMessage Limit 0,2;
+IdDirectMessage	MessageData	DateOfMessage
+1	Texto	2003-08-06 00:00:00
+2	Texto	2003-08-06 00:00:00
+SELECT FOUND_ROWS();
+FOUND_ROWS()
+22
+SELECT SQL_CALC_FOUND_ROWS t2.* FROM t2 INNER JOIN t1 ON t2.IdDirectMessage = t1.IdDirectMessage WHERE IdUser = 4 AND Readed Is NULL limit 1 UNION SELECT t2.* FROM t2 INNER JOIN t1 ON t2.IdDirectMessage = t1.IdDirectMessage WHERE IdUser = 4 AND NOT (t1.Readed is NULL) ORDER BY DateOfMessage;
+IdDirectMessage	MessageData	DateOfMessage
+1	Texto	2003-08-06 00:00:00
+2	Texto	2003-08-06 00:00:00
+3	Texto	2003-08-06 00:00:00
+4	Texto	2003-08-06 00:00:00
+5	Texto	2003-08-06 00:00:00
+6	Texto	2003-08-06 00:00:00
+7	Texto	2003-08-06 00:00:00
+8	Texto	2003-08-06 00:00:00
+9	Texto	2003-08-06 00:00:00
+10	Texto	2003-08-06 00:00:00
+11	Texto	2003-08-06 00:00:00
+12	Texto	2003-08-06 00:00:00
+13	Texto	2003-08-06 00:00:00
+14	Texto	2003-08-06 00:00:00
+15	Texto	2003-08-06 00:00:00
+16	Texto	2003-08-06 00:00:00
+17	Texto	2003-08-06 00:00:00
+18	Texto	2003-08-06 00:00:00
+19	Texto	2003-08-06 00:00:00
+20	Texto	2003-08-06 00:00:00
+21	Texto	2003-08-06 00:00:00
+22	Texto	2003-08-06 00:00:00
+SELECT FOUND_ROWS();
+FOUND_ROWS()
+22
+drop table t2,t1;
+CREATE TABLE t1 (  sid int(11) NOT NULL default '0',  nazwa char(10) NOT NULL default '',  PRIMARY KEY  (sid) ) TYPE=MyISAM;
+CREATE TABLE t2 (  id int(11) NOT NULL default '0',   link int(11) default NULL,   bubu char(10) NOT NULL default '',   PRIMARY KEY  (id) ) TYPE=MyISAM;
+INSERT INTO t2 VALUES (1,2,'keke');
+SELECT bubu, nazwa, bubu  FROM t2 LEFT JOIN t1 ON sid = link WHERE id=1  UNION SELECT 'bu', null, 'bu';
+bubu	nazwa	bubu
+keke	NULL	keke
+bu	NULL	bu
+drop table t1,t2;
diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test
index 5f7eba8375..502086d0e8 100644
--- a/mysql-test/t/union.test
+++ b/mysql-test/t/union.test
@@ -170,3 +170,19 @@ 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;
+CREATE TABLE t1 (  `IdUser` int(11) NOT NULL default '0',   `IdDirectMessage` int(11) NOT NULL default '0',   `Readed` datetime default NULL,   PRIMARY KEY  (`IdUser`,`IdDirectMessage`),   KEY `IdDirectMessage` (`IdDirectMessage`), );
+CREATE TABLE  t2 (   `IdDirectMessage` int(11) NOT NULL default '0',   `MessageData` text NOT NULL,   `DateOfMessage` datetime default NULL,   PRIMARY KEY  (`IdDirectMessage`) );
+INSERT INTO  t2 (`IdDirectMessage`, `MessageData`, `DateOfMessage`) VALUES   (1,'Texto','2003-08-06 00:00:00'),   (2,'Texto','2003-08-06 00:00:00'),   (3,'Texto','2003-08-06 00:00:00'),   (4,'Texto','2003-08-06 00:00:00'),   (5,'Texto','2003-08-06 00:00:00'),   (6,'Texto','2003-08-06 00:00:00'),   (7,'Texto','2003-08-06 00:00:00'),   (8,'Texto','2003-08-06 00:00:00'),   (9,'Texto','2003-08-06 00:00:00'),   (10,'Texto','2003-08-06 00:00:00'),   (11,'Texto','2003-08-06 00:00:00'),   (12,'Texto','2003-08-06 00:00:00'),   (13,'Texto','2003-08-06 00:00:00'),   (14,'Texto','2003-08-06 00:00:00'),   (15,'Texto','2003-08-06 00:00:00'),   (16,'Texto','2003-08-06 00:00:00'),   (17,'Texto','2003-08-06 00:00:00'),   (18,'Texto','2003-08-06 00:00:00'),   (19,'Texto','2003-08-06 00:00:00'),   (20,'Texto','2003-08-06 00:00:00'),   (21,'Texto','2003-08-06 00:00:00'),   (22,'Texto','2003-08-06 00:00:00');
+INSERT INTO t1 (`IdUser`, `IdDirectMessage`, `Readed`) VALUES   (4,1,'2003-08-07 10:10:13'),   (4,2,'2003-08-07 10:10:13'),   (4,3,'2003-08-07 10:10:13'),   (4,4,'2003-08-07 10:10:13'),   (4,5,'2003-08-07 10:10:13'),   (4,6,'2003-08-07 10:10:13'),   (4,7,'2003-08-07 10:10:13'),   (4,8,'2003-08-07 10:10:13'),   (4,9,'2003-08-07 10:10:13'),   (4,10,'2003-08-07 10:10:13'),   (4,11,'2003-08-07 10:10:13'),   (4,12,'2003-08-07 10:10:13'),   (4,13,'2003-08-07 10:10:13'),   (4,14,'2003-08-07 10:10:13'),   (4,15,'2003-08-07 10:10:13'),   (4,16,'2003-08-07 10:10:13'),   (4,17,'2003-08-07 10:10:13'),   (4,18,'2003-08-07 10:10:13'),   (4,19,'2003-08-07 10:10:13'),   (4,20,'2003-08-07 10:10:13'),   (4,21,'2003-08-06 16:51:04'),   (4,22,'2003-08-06 16:51:19');
+SELECT SQL_CALC_FOUND_ROWS t2.* FROM t2 INNER JOIN t1 ON t2.IdDirectMessage = t1.IdDirectMessage WHERE IdUser = 4 AND Readed Is NULL UNION SELECT t2.* FROM t2 INNER JOIN t1 ON t2.IdDirectMessage = t1.IdDirectMessage WHERE IdUser = 4 AND NOT (t1.Readed is NULL) ORDER BY DateOfMessage Limit 0,2;
+SELECT FOUND_ROWS();
+SELECT SQL_CALC_FOUND_ROWS t2.* FROM t2 INNER JOIN t1 ON t2.IdDirectMessage = t1.IdDirectMessage WHERE IdUser = 4 AND Readed Is NULL UNION ALL  SELECT t2.* FROM t2 INNER JOIN t1 ON t2.IdDirectMessage = t1.IdDirectMessage WHERE IdUser = 4 AND NOT (t1.Readed is NULL) ORDER BY DateOfMessage Limit 0,2;
+SELECT FOUND_ROWS();
+SELECT SQL_CALC_FOUND_ROWS t2.* FROM t2 INNER JOIN t1 ON t2.IdDirectMessage = t1.IdDirectMessage WHERE IdUser = 4 AND Readed Is NULL limit 1 UNION SELECT t2.* FROM t2 INNER JOIN t1 ON t2.IdDirectMessage = t1.IdDirectMessage WHERE IdUser = 4 AND NOT (t1.Readed is NULL) ORDER BY DateOfMessage;
+SELECT FOUND_ROWS();
+drop table t2,t1;
+CREATE TABLE t1 (  sid int(11) NOT NULL default '0',  nazwa char(10) NOT NULL default '',  PRIMARY KEY  (sid) ) TYPE=MyISAM;
+CREATE TABLE t2 (  id int(11) NOT NULL default '0',   link int(11) default NULL,   bubu char(10) NOT NULL default '',   PRIMARY KEY  (id) ) TYPE=MyISAM;
+INSERT INTO t2 VALUES (1,2,'keke');
+SELECT bubu, nazwa, bubu  FROM t2 LEFT JOIN t1 ON sid = link WHERE id=1  UNION SELECT 'bu', null, 'bu';
+drop table t1,t2;
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index bd7bc7027d..81a4806ab6 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -32,7 +32,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
   List<Item> item_list;
   TABLE *table;
   int describe=(lex->select_lex.options & SELECT_DESCRIBE) ? 1 : 0;
-  int res;
+  int res, add_rows=0;
   bool found_rows_for_union= lex->select_lex.options & OPTION_FOUND_ROWS;
   TABLE_LIST result_table_list;
   TABLE_LIST *first_table=(TABLE_LIST *)lex->select_lex.table_list.first;
@@ -135,6 +135,7 @@ 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)
   {
+    unsigned int rows;
     lex->select=sl;
     thd->offset_limit=sl->offset_limit;
     thd->select_limit=sl->select_limit+sl->offset_limit;
@@ -142,6 +143,11 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
       thd->select_limit= HA_POS_ERROR;		// no limit
     if (thd->select_limit == HA_POS_ERROR || sl->braces)
       sl->options&= ~OPTION_FOUND_ROWS;
+    else if (found_rows_for_union)
+    {
+      rows= thd->select_limit;
+      sl->options|= OPTION_FOUND_ROWS;
+    }
 
     res=mysql_select(thd, (describe && sl->linkage==NOT_A_SELECT) ?
 		     first_table :  (TABLE_LIST*) sl->table_list.first,
@@ -155,6 +161,8 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
 		     sl->options | thd->options | SELECT_NO_UNLOCK |
 		     ((describe) ? SELECT_DESCRIBE : 0),
 		     union_result);
+    if (found_rows_for_union  && !sl->braces && sl->options & OPTION_FOUND_ROWS)
+      add_rows+= (thd->limit_found_rows > rows) ?  thd->limit_found_rows - rows : 0;
     if (res)
       goto exit;
   }
@@ -210,7 +218,11 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
 		       (ORDER*) NULL, NULL, (ORDER*) NULL,
 		       thd->options, result);
       if (found_rows_for_union && !res)
-	thd->limit_found_rows = (ulonglong)table->file->records;
+      {
+	thd->limit_found_rows= table->file->records;
+	if (!last_sl->braces)
+	  thd->limit_found_rows+= add_rows;
+      }
     }
   }
 
-- 
2.30.9