Bug #29717 INSERT INTO SELECT inserts values even if

 SELECT statement itself returns empty.

As a result of this bug 'SELECT AGGREGATE_FUNCTION(fld) ... GROUP BY'
can return one row instead of an empty result set.

When GROUP BY only has fields of constant tables
(with a single row), the optimizer deletes the group_list.
After that we lose the information about whether we had an
GROUP BY statement. Though it's important
as SELECT min(x) from empty_table; and
   SELECT min(x) from empty_table GROUP BY y; have to return
different results - the first query should return one row,
second - an empty result set.
So here we add the 'group_optimized_away' flag to remember this case
when GROUP BY exists in the query and is removed
by the optimizer, and check this flag in end_send_group()
parent 40fb6443
...@@ -818,3 +818,20 @@ a ...@@ -818,3 +818,20 @@ a
2 2
1 1
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (
f1 int(10) unsigned NOT NULL auto_increment primary key,
f2 varchar(100) NOT NULL default ''
);
CREATE TABLE t2 (
f1 varchar(10) NOT NULL default '',
f2 char(3) NOT NULL default '',
PRIMARY KEY (`f1`),
KEY `k1` (`f2`,`f1`)
);
INSERT INTO t1 values(NULL, '');
INSERT INTO `t2` VALUES ('486878','WDT'),('486910','WDT');
SELECT SQL_BUFFER_RESULT avg(t2.f1) FROM t1, t2 where t2.f2 = 'SIR' GROUP BY t1.f1;
avg(t2.f1)
SELECT avg(t2.f1) FROM t1, t2 where t2.f2 = 'SIR' GROUP BY t1.f1;
avg(t2.f1)
DROP TABLE t1, t2;
...@@ -690,3 +690,29 @@ CREATE TABLE t1 (a int PRIMARY KEY); ...@@ -690,3 +690,29 @@ CREATE TABLE t1 (a int PRIMARY KEY);
INSERT INTO t1 values (1), (2); INSERT INTO t1 values (1), (2);
INSERT INTO t1 SELECT a + 2 FROM t1 LIMIT 1; INSERT INTO t1 SELECT a + 2 FROM t1 LIMIT 1;
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (
f1 int(10) unsigned NOT NULL auto_increment PRIMARY KEY,
f2 varchar(100) NOT NULL default ''
);
CREATE TABLE t2 (
f1 varchar(10) NOT NULL default '',
f2 char(3) NOT NULL default '',
PRIMARY KEY (`f1`),
KEY `k1` (`f2`, `f1`)
);
INSERT INTO t1 values(NULL, '');
INSERT INTO `t2` VALUES ('486878','WDT'),('486910','WDT');
SELECT COUNT(*) FROM t1;
COUNT(*)
1
SELECT min(t2.f1) FROM t1, t2 where t2.f2 = 'SIR' GROUP BY t1.f1;
min(t2.f1)
INSERT INTO t1 (f2)
SELECT min(t2.f1) FROM t1, t2 where t2.f2 = 'SIR' GROUP BY t1.f1;
SELECT COUNT(*) FROM t1;
COUNT(*)
1
SELECT * FROM t1;
f1 f2
1
DROP TABLE t1, t2;
...@@ -633,4 +633,27 @@ SELECT a FROM t1 ORDER BY 'a' DESC; ...@@ -633,4 +633,27 @@ SELECT a FROM t1 ORDER BY 'a' DESC;
SELECT a FROM t1 ORDER BY "a" DESC; SELECT a FROM t1 ORDER BY "a" DESC;
SELECT a FROM t1 ORDER BY `a` DESC; SELECT a FROM t1 ORDER BY `a` DESC;
DROP TABLE t1; DROP TABLE t1;
#
# Bug #29717 INSERT INTO SELECT inserts values even if SELECT statement itself
# returns empty
#
CREATE TABLE t1 (
f1 int(10) unsigned NOT NULL auto_increment primary key,
f2 varchar(100) NOT NULL default ''
);
CREATE TABLE t2 (
f1 varchar(10) NOT NULL default '',
f2 char(3) NOT NULL default '',
PRIMARY KEY (`f1`),
KEY `k1` (`f2`,`f1`)
);
INSERT INTO t1 values(NULL, '');
INSERT INTO `t2` VALUES ('486878','WDT'),('486910','WDT');
SELECT SQL_BUFFER_RESULT avg(t2.f1) FROM t1, t2 where t2.f2 = 'SIR' GROUP BY t1.f1;
SELECT avg(t2.f1) FROM t1, t2 where t2.f2 = 'SIR' GROUP BY t1.f1;
DROP TABLE t1, t2;
# End of 4.1 tests # End of 4.1 tests
...@@ -239,4 +239,32 @@ INSERT INTO t1 SELECT a + 2 FROM t1 LIMIT 1; ...@@ -239,4 +239,32 @@ INSERT INTO t1 SELECT a + 2 FROM t1 LIMIT 1;
DROP TABLE t1; DROP TABLE t1;
#
# Bug #29717 INSERT INTO SELECT inserts values even if SELECT statement itself returns empty
#
CREATE TABLE t1 (
f1 int(10) unsigned NOT NULL auto_increment PRIMARY KEY,
f2 varchar(100) NOT NULL default ''
);
CREATE TABLE t2 (
f1 varchar(10) NOT NULL default '',
f2 char(3) NOT NULL default '',
PRIMARY KEY (`f1`),
KEY `k1` (`f2`, `f1`)
);
INSERT INTO t1 values(NULL, '');
INSERT INTO `t2` VALUES ('486878','WDT'),('486910','WDT');
SELECT COUNT(*) FROM t1;
SELECT min(t2.f1) FROM t1, t2 where t2.f2 = 'SIR' GROUP BY t1.f1;
INSERT INTO t1 (f2)
SELECT min(t2.f1) FROM t1, t2 where t2.f2 = 'SIR' GROUP BY t1.f1;
SELECT COUNT(*) FROM t1;
SELECT * FROM t1;
DROP TABLE t1, t2;
# End of 4.1 tests # End of 4.1 tests
...@@ -777,6 +777,7 @@ JOIN::optimize() ...@@ -777,6 +777,7 @@ JOIN::optimize()
order=0; // The output has only one row order=0; // The output has only one row
simple_order=1; simple_order=1;
select_distinct= 0; // No need in distinct for 1 row select_distinct= 0; // No need in distinct for 1 row
group_optimized_away= 1;
} }
calc_group_buffer(this, group_list); calc_group_buffer(this, group_list);
...@@ -6896,7 +6897,8 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), ...@@ -6896,7 +6897,8 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (!join->first_record || end_of_records || if (!join->first_record || end_of_records ||
(idx=test_if_group_changed(join->group_fields)) >= 0) (idx=test_if_group_changed(join->group_fields)) >= 0)
{ {
if (join->first_record || (end_of_records && !join->group)) if (join->first_record ||
(end_of_records && !join->group && !join->group_optimized_away))
{ {
if (join->procedure) if (join->procedure)
join->procedure->end_group(); join->procedure->end_group();
......
...@@ -180,6 +180,14 @@ class JOIN :public Sql_alloc ...@@ -180,6 +180,14 @@ class JOIN :public Sql_alloc
ROLLUP rollup; // Used with rollup ROLLUP rollup; // Used with rollup
bool select_distinct; // Set if SELECT DISTINCT bool select_distinct; // Set if SELECT DISTINCT
/*
If we have the GROUP BY statement in the query,
but the group_list was emptied by optimizer, this
flag is TRUE.
It happens when fields in the GROUP BY are from
constant table
*/
bool group_optimized_away;
/* /*
simple_xxxxx is set if ORDER/GROUP BY doesn't include any references simple_xxxxx is set if ORDER/GROUP BY doesn't include any references
...@@ -276,6 +284,7 @@ class JOIN :public Sql_alloc ...@@ -276,6 +284,7 @@ class JOIN :public Sql_alloc
ref_pointer_array_size= 0; ref_pointer_array_size= 0;
zero_result_cause= 0; zero_result_cause= 0;
optimized= 0; optimized= 0;
group_optimized_away= 0;
fields_list= fields_arg; fields_list= fields_arg;
bzero((char*) &keyuse,sizeof(keyuse)); bzero((char*) &keyuse,sizeof(keyuse));
......
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