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