List:Commits« Previous MessageNext Message »
From:Jan Wedvik Date:August 17 2010 12:04pm
Subject:bzr push into mysql-5.1-telco-7.0-spj-scan-vs-scan branch (jan.wedvik:3224
to 3225)
View as plain text  
 3225 Jan Wedvik	2010-08-17
      This commit fixes a regression that could cause core dumps when doing an
      ordered scan with a lookup child where all result rows from the parent
      where eliminated by the inner join (i.e. no results from the child).
      The code did in some places assum that an empty batch would also have to
      be the final batch. But the batch can also be empty due to inner join
      row elimination.
      
      The commit also adds a regression test for this fix.

    modified:
      mysql-test/suite/ndb/r/ndb_join_pushdown.result
      mysql-test/suite/ndb/t/ndb_join_pushdown.test
      storage/ndb/src/ndbapi/NdbQueryOperation.cpp
 3224 Jan Wedvik	2010-08-17
      This is a refactoring of commit http://lists.mysql.com/commits/115164 .
      Dbspj::LookupData has been simplified such that is uses two rather than three
      fields to keep track of the state of a lookup operation with a scan ancestor.
      Also, a regression test for scan-lookup-scan has been added.

    modified:
      mysql-test/suite/ndb/r/ndb_join_pushdown.result
      mysql-test/suite/ndb/t/ndb_join_pushdown.test
      storage/ndb/src/kernel/blocks/dbspj/Dbspj.hpp
      storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp
=== modified file 'mysql-test/suite/ndb/r/ndb_join_pushdown.result'
--- a/mysql-test/suite/ndb/r/ndb_join_pushdown.result	2010-08-17 08:02:00 +0000
+++ b/mysql-test/suite/ndb/r/ndb_join_pushdown.result	2010-08-17 12:04:13 +0000
@@ -3323,4 +3323,30 @@ pk	u	a	b	pk	u	a	b	pk	u	a	b
 0	1	10	20	1	2	20	30	0	1	10	20
 1	2	20	30	2	3	30	40	1	2	20	30
 drop table t1;
+create table t1 (pk int primary key, u int not null) engine=ndb;
+insert into t1 values (0,-1), (1,-1), (2,-1), (3,-1), (4,-1), (5,-1), (6,-1), 
+(7,-1), (8,-1), (9,-1), (10,-1), (11,-1), (12,-1), (13,-1), (14,-1), (15,-1), 
+(16,-1), (17,-1), (18,-1), (19,-1), (20,-1), (21,-1), (22,-1), (23,-1), 
+(24,-1), (25,-1), (26,-1), (27,-1), (28,-1), (29,-1), (30,-1), (31,-1), 
+(32,-1), (33,-1), (34,-1), (35,-1), (36,-1), (37,-1), (38,-1), (39,-1), 
+(40,-1), (41,-1), (42,-1), (43,-1), (44,-1), (45,-1), (46,-1), (47,-1), 
+(48,-1), (49,-1), (50,-1), (51,-1), (52,-1), (53,-1), (54,-1), (55,-1), 
+(56,-1), (57,-1), (58,-1), (59,-1), (60,-1), (61,-1), (62,-1), (63,-1), 
+(64,-1), (65,-1), (66,-1), (67,-1), (68,-1), (69,-1), (70,-1), (71,-1), 
+(72,-1), (73,-1), (74,-1), (75,-1), (76,-1), (77,-1), (78,-1), (79,-1), 
+(80,-1), (81,-1), (82,-1), (83,-1), (84,-1), (85,-1), (86,-1), (87,-1), 
+(88,-1), (89,-1), (90,-1), (91,-1), (92,-1), (93,-1), (94,-1), (95,-1), 
+(96,-1), (97,-1), (98,-1), (99,-1), (100,-1), (101,-1), (102,-1), (103,-1), 
+(104,-1), (105,-1), (106,-1), (107,-1), (108,-1), (109,-1), (110,-1), 
+(111,-1), (112,-1), (113,-1), (114,-1), (115,-1), (116,-1), (117,-1), 
+(118,-1), (119,-1), (120,-1), (121,-1), (122,-1), (123,-1), (124,-1), 
+(125,-1), (126,-1), (127,-1), (128,-1), (129,-1), (130,-1), (131,-1), 
+(132,-1), (133,-1), (134,-1), (135,-1), (136,-1), (137,-1), (138,-1), (139,-1);
+explain select * from t1 as x join t1 as y on x.u=y.pk order by(x.pk);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	x	index	NULL	PRIMARY	4	NULL	140	Parent of 2 pushed join@1
+1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	4	test.x.u	1	Child of pushed join@1
+select * from t1 as x join t1 as y on x.u=y.pk order by(x.pk);
+pk	u	pk	u
+drop table t1;
 set ndb_join_pushdown = @save_ndb_join_pushdown;

=== modified file 'mysql-test/suite/ndb/t/ndb_join_pushdown.test'
--- a/mysql-test/suite/ndb/t/ndb_join_pushdown.test	2010-08-17 08:02:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_join_pushdown.test	2010-08-17 12:04:13 +0000
@@ -2352,6 +2352,32 @@ select * from t1 as x join t1 as y join 
 
 drop table t1;
 
+# Test sorted scan where inner join eliminates all rows (known regression).
+create table t1 (pk int primary key, u int not null) engine=ndb;
+
+insert into t1 values (0,-1), (1,-1), (2,-1), (3,-1), (4,-1), (5,-1), (6,-1), 
+(7,-1), (8,-1), (9,-1), (10,-1), (11,-1), (12,-1), (13,-1), (14,-1), (15,-1), 
+(16,-1), (17,-1), (18,-1), (19,-1), (20,-1), (21,-1), (22,-1), (23,-1), 
+(24,-1), (25,-1), (26,-1), (27,-1), (28,-1), (29,-1), (30,-1), (31,-1), 
+(32,-1), (33,-1), (34,-1), (35,-1), (36,-1), (37,-1), (38,-1), (39,-1), 
+(40,-1), (41,-1), (42,-1), (43,-1), (44,-1), (45,-1), (46,-1), (47,-1), 
+(48,-1), (49,-1), (50,-1), (51,-1), (52,-1), (53,-1), (54,-1), (55,-1), 
+(56,-1), (57,-1), (58,-1), (59,-1), (60,-1), (61,-1), (62,-1), (63,-1), 
+(64,-1), (65,-1), (66,-1), (67,-1), (68,-1), (69,-1), (70,-1), (71,-1), 
+(72,-1), (73,-1), (74,-1), (75,-1), (76,-1), (77,-1), (78,-1), (79,-1), 
+(80,-1), (81,-1), (82,-1), (83,-1), (84,-1), (85,-1), (86,-1), (87,-1), 
+(88,-1), (89,-1), (90,-1), (91,-1), (92,-1), (93,-1), (94,-1), (95,-1), 
+(96,-1), (97,-1), (98,-1), (99,-1), (100,-1), (101,-1), (102,-1), (103,-1), 
+(104,-1), (105,-1), (106,-1), (107,-1), (108,-1), (109,-1), (110,-1), 
+(111,-1), (112,-1), (113,-1), (114,-1), (115,-1), (116,-1), (117,-1), 
+(118,-1), (119,-1), (120,-1), (121,-1), (122,-1), (123,-1), (124,-1), 
+(125,-1), (126,-1), (127,-1), (128,-1), (129,-1), (130,-1), (131,-1), 
+(132,-1), (133,-1), (134,-1), (135,-1), (136,-1), (137,-1), (138,-1), (139,-1);
+
+explain select * from t1 as x join t1 as y on x.u=y.pk order by(x.pk);
+select * from t1 as x join t1 as y on x.u=y.pk order by(x.pk);
+
+drop table t1;
 
 set ndb_join_pushdown = @save_ndb_join_pushdown;
 

=== modified file 'storage/ndb/src/ndbapi/NdbQueryOperation.cpp'
--- a/storage/ndb/src/ndbapi/NdbQueryOperation.cpp	2010-08-17 07:32:36 +0000
+++ b/storage/ndb/src/ndbapi/NdbQueryOperation.cpp	2010-08-17 12:04:13 +0000
@@ -2904,9 +2904,14 @@ NdbQueryImpl::OrderedFragSet::add(NdbRoo
   {
     if(m_size+m_completedFrags < m_capacity)
     {
-      if(!frag.isEmpty())
+      // We have not yet received the first batch for each fragment.
+      if(frag.isEmpty() && frag.finalBatchReceived())
+      {
+        // This is the first and final batch for this fragment, and it is empty.
+        m_completedFrags++;
+      }
+      else
       {
-        // Frag is non-empty.
         int current = 0;
         // Insert the new frag such that the array remains sorted.
         while(current<m_size && compare(frag, *m_array[current])==1)
@@ -2921,12 +2926,6 @@ NdbQueryImpl::OrderedFragSet::add(NdbRoo
         assert(m_size <= m_capacity);
         assert(verifySortOrder());
       }
-      else
-      {
-        // First batch is empty, therefore it should also be the final batch. 
-        assert(frag.finalBatchReceived());
-        m_completedFrags++;
-      }
     }
     else
     {
@@ -2948,9 +2947,6 @@ NdbQueryImpl::OrderedFragSet::getEmpty()
 {
   // This method is not applicable to unordered scans.
   assert(m_ordering!=NdbQueryOptions::ScanOrdering_unordered);
-  // The first frag should be empty when calling this method.
-  assert(m_size==0 || m_array[0]->isEmpty());
-  assert(verifySortOrder());
   if(m_completedFrags==m_capacity)
   {
     assert(m_size==0);


Attachment: [text/bzr-bundle] bzr/jan.wedvik@sun.com-20100817120413-6zv4h97o4rmjcr3z.bundle
Thread
bzr push into mysql-5.1-telco-7.0-spj-scan-vs-scan branch (jan.wedvik:3224to 3225) Jan Wedvik17 Aug