summaryrefslogtreecommitdiff
path: root/mysql-test/t/subselect3.test
diff options
context:
space:
mode:
authorunknown <gkodinov/kgeorge@macbook.local>2007-03-20 19:46:02 +0200
committerunknown <gkodinov/kgeorge@macbook.local>2007-03-20 19:46:02 +0200
commit9c89dd654e90d85fefc2459711063b680ed10f24 (patch)
tree910911efb4f7c49f4623fc917f9e7d62b984a2c7 /mysql-test/t/subselect3.test
parenta30830460794651c0e9fc5ec4779cf77680514ee (diff)
downloadmariadb-git-9c89dd654e90d85fefc2459711063b680ed10f24.tar.gz
Bug #24484:
To correctly decide which predicates can be evaluated with a given table the optimizer must know the exact set of tables that a predicate depends on. If that mask is too wide (refer to non-existing tables) the optimizer can erroneously skip a predicate. One such case of wrong table usage mask were the aggregate functions. The have a all-1 mask (meaning depend on all tables, including non-existent ones). Fixed by making a real used_tables mask for the aggregates. The mask is constructed in the following way : 1. OR the table dependency masks of all the arguments of the aggregate. 2. If all the arguments of the function are from the local name resolution context and it is evaluated in the same name resolution context where it is referenced all the tables from that name resolution context are OR-ed to the dependency mask. This is to denote that an aggregate function depends on the number of rows it processes. 3. Handle correctly the case of an aggregate function optimization (such that the aggregate function can be pre-calculated and made a constant). Made sure that an aggregate function is never a constant (unless subject of a specific optimization and pre-calculation). One other flaw was revealed and fixed in the process : references were not calling the recalculation method for used_tables of their targets. mysql-test/r/subselect3.result: Bug #24484: test case mysql-test/t/subselect3.test: Bug #24484: test case sql/item.h: Bug #24484: Item_ref must update the used tables. sql/item_sum.cc: Bug #24484: correct calculation of used_tables for aggregates. sql/item_sum.h: Bug #24484: correct calculation of used_tables for aggregates. sql/opt_range.cc: Bug #24484: fixed ref resolution in loose index scan sql/sql_base.cc: Bug #24484: moved counting of leaf tables inside setup_tables_and_check_access. sql/sql_class.h: Bug #24484: changed table count to more narrow type. sql/sql_insert.cc: Bug #24484: moved counting of leaf tables inside setup_tables_and_check_access. Substract the first table (and its subtables) of an INSERT statement from leaf_count. sql/sql_select.cc: Bug #24484: correct check for aggregates
Diffstat (limited to 'mysql-test/t/subselect3.test')
-rw-r--r--mysql-test/t/subselect3.test41
1 files changed, 41 insertions, 0 deletions
diff --git a/mysql-test/t/subselect3.test b/mysql-test/t/subselect3.test
index ed8480ba464..e3703c0da16 100644
--- a/mysql-test/t/subselect3.test
+++ b/mysql-test/t/subselect3.test
@@ -489,3 +489,44 @@ select a, b, (a,b) in (select a, min(b) from t2 group by a) Z from t1;
drop table t1,t2;
+#
+# Bug #24484: Aggregate function used in column list subquery gives erroneous
+# error
+#
+CREATE TABLE t1 (a int, b INT, c CHAR(10) NOT NULL, PRIMARY KEY (a, b));
+INSERT INTO t1 VALUES (1,1,'a'), (1,2,'b'), (1,3,'c'), (1,4,'d'), (1,5,'e'),
+ (2,1,'f'), (2,2,'g'), (2,3,'h'), (3,4,'i'),(3,3,'j'), (3,2,'k'), (3,1,'l'),
+ (1,9,'m');
+CREATE TABLE t2 (a int, b INT, c CHAR(10) NOT NULL, PRIMARY KEY (a, b));
+INSERT INTO t2 SELECT * FROM t1;
+
+# Gives error, but should work since it is (a, b) is the PK so only one
+# given match possible
+SELECT a, MAX(b), (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b))
+ as test FROM t1 GROUP BY a;
+SELECT * FROM t1 GROUP by t1.a
+ HAVING (MAX(t1.b) > (SELECT MAX(t2.b) FROM t2 WHERE t2.c < t1.c
+ HAVING MAX(t2.b+t1.a) < 10));
+SELECT a, AVG(b), (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=AVG(t1.b))
+ AS test FROM t1 GROUP BY a;
+
+SELECT a,b,c FROM t1 WHERE b in (9,3,4) ORDER BY b,c;
+
+SELECT a, MAX(b),
+ (SELECT COUNT(DISTINCT t.c) FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b)
+ LIMIT 1)
+ as cnt,
+ (SELECT t.b FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b) LIMIT 1)
+ as t_b,
+ (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b) LIMIT 1)
+ as t_b,
+ (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b) ORDER BY t.c LIMIT 1)
+ as t_b
+ FROM t1 GROUP BY a;
+
+SELECT a, MAX(b),
+ (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b) LIMIT 1) as test
+ FROM t1 GROUP BY a;
+
+
+DROP TABLE t1, t2;