mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
sql_union.cc:
Fix for SQL_CALC_FOUND_ROWS in UNION's
This commit is contained in:
@ -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,57 @@ 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 ( `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;
|
||||||
|
@ -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 t3;
|
||||||
select * from t4;
|
select * from t4;
|
||||||
drop table t1,t2,t3,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;
|
||||||
|
@ -32,7 +32,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
|
|||||||
List<Item> item_list;
|
List<Item> item_list;
|
||||||
TABLE *table;
|
TABLE *table;
|
||||||
int describe=(lex->select_lex.options & SELECT_DESCRIBE) ? 1 : 0;
|
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;
|
bool found_rows_for_union= lex->select_lex.options & OPTION_FOUND_ROWS;
|
||||||
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;
|
||||||
@ -135,6 +135,7 @@ 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)
|
||||||
{
|
{
|
||||||
|
unsigned int rows;
|
||||||
lex->select=sl;
|
lex->select=sl;
|
||||||
thd->offset_limit=sl->offset_limit;
|
thd->offset_limit=sl->offset_limit;
|
||||||
thd->select_limit=sl->select_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
|
thd->select_limit= HA_POS_ERROR; // no limit
|
||||||
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 if (found_rows_for_union)
|
||||||
|
{
|
||||||
|
rows= thd->select_limit;
|
||||||
|
sl->options|= OPTION_FOUND_ROWS;
|
||||||
|
}
|
||||||
|
|
||||||
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,
|
||||||
@ -155,6 +161,8 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
|
|||||||
sl->options | thd->options | SELECT_NO_UNLOCK |
|
sl->options | thd->options | SELECT_NO_UNLOCK |
|
||||||
((describe) ? SELECT_DESCRIBE : 0),
|
((describe) ? SELECT_DESCRIBE : 0),
|
||||||
union_result);
|
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)
|
if (res)
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
@ -210,7 +218,11 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
|
|||||||
(ORDER*) NULL, NULL, (ORDER*) NULL,
|
(ORDER*) NULL, NULL, (ORDER*) NULL,
|
||||||
thd->options, result);
|
thd->options, result);
|
||||||
if (found_rows_for_union && !res)
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user