List:Commits« Previous MessageNext Message »
From:Sergey Vojtovich Date:February 14 2008 12:47pm
Subject:bk commit into 5.0 tree (svoj:1.2570) BUG#33946
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of svoj.  When svoj does a push these changes
will be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2008-02-14 15:47:29+04:00, svoj@stripped +3 -0
  BUG#33946 - Join on Federated tables with Unique index gives error 1430
              from storage engine
  
  Federated may crash a server, return wrong result set, return
  "ERROR 1030 (HY000): Got error 1430 from storage engine" message
  when local (engine=federated) table has a key against nullable
  column.
  
  The problem was wrong implementation of function that creates
  WHERE clause for remote query from key.

  mysql-test/r/federated.result@stripped, 2008-02-14 15:47:28+04:00, svoj@stripped +18 -0
    A test case for BUG#33946.

  mysql-test/t/federated.test@stripped, 2008-02-14 15:47:28+04:00, svoj@stripped +21 -0
    A test case for BUG#33946.

  sql/ha_federated.cc@stripped, 2008-02-14 15:47:28+04:00, svoj@stripped +19 -3
    Fixed that federated adds " IS NULL " condition to a remote query,
    whereas "IS NOT NULL" requested by original query.
    
    Fixed that federated didn't check for end of key buffer, didn't
    setup key buffer pointer and remaining lenght of key buffer,
    didn't add " AND " between conditions in case original query
    has IS [NOT] NULL condition against nullable column.
    
    Fixed that federated wrongly shifts key buffer pointer by extra
    one byte when key part may be null (was: store_length + 1,
    now: store_length).

diff -Nrup a/mysql-test/r/federated.result b/mysql-test/r/federated.result
--- a/mysql-test/r/federated.result	2007-11-30 17:07:58 +04:00
+++ b/mysql-test/r/federated.result	2008-02-14 15:47:28 +04:00
@@ -2045,6 +2045,24 @@ select 1 from t1 order by a;
 drop table t1;
 drop table t1;
 drop view v1;
+CREATE TABLE t1 (a INT, b INT, KEY(a,b));
+INSERT INTO t1 VALUES(NULL,1),(1,NULL),(NULL,NULL),(1,1),(2,2);
+CREATE TABLE t1 (a INT, b INT, KEY(a,b)) ENGINE=federated
+CONNECTION='mysql://root@stripped:SLAVE_PORT/test/t1';
+SELECT * FROM t1 WHERE a IS NULL;
+a	b
+NULL	NULL
+NULL	1
+SELECT * FROM t1 WHERE a IS NOT NULL;
+a	b
+1	NULL
+1	1
+2	2
+SELECT * FROM t1 WHERE a=1 AND b=1;
+a	b
+1	1
+DROP TABLE t1;
+DROP TABLE t1;
 DROP TABLE IF EXISTS federated.t1;
 DROP DATABASE IF EXISTS federated;
 DROP TABLE IF EXISTS federated.t1;
diff -Nrup a/mysql-test/t/federated.test b/mysql-test/t/federated.test
--- a/mysql-test/t/federated.test	2007-11-30 17:07:58 +04:00
+++ b/mysql-test/t/federated.test	2008-02-14 15:47:28 +04:00
@@ -1716,5 +1716,26 @@ connection slave;
 drop table t1;
 drop view v1;
 
+#
+# BUG#33946 - Join on Federated tables with Unique index gives error 1430
+#             from storage engine
+#
+connection slave;
+CREATE TABLE t1 (a INT, b INT, KEY(a,b));
+INSERT INTO t1 VALUES(NULL,1),(1,NULL),(NULL,NULL),(1,1),(2,2);
+
+connection master;
+--replace_result $SLAVE_MYPORT SLAVE_PORT
+eval CREATE TABLE t1 (a INT, b INT, KEY(a,b)) ENGINE=federated
+CONNECTION='mysql://root@stripped:$SLAVE_MYPORT/test/t1';
+SELECT * FROM t1 WHERE a IS NULL;
+SELECT * FROM t1 WHERE a IS NOT NULL;
+SELECT * FROM t1 WHERE a=1 AND b=1;
+SELECT * FROM t1 WHERE a IS NULL AND b=1;
+SELECT * FROM t1 WHERE a IS NOT NULL AND b=1;
+DROP TABLE t1;
+
+connection slave;
+DROP TABLE t1;
 
 source include/federated_cleanup.inc;
diff -Nrup a/sql/ha_federated.cc b/sql/ha_federated.cc
--- a/sql/ha_federated.cc	2007-11-30 17:07:58 +04:00
+++ b/sql/ha_federated.cc	2008-02-14 15:47:28 +04:00
@@ -1094,10 +1094,20 @@ bool ha_federated::create_where_from_key
       {
         if (*ptr++)
         {
+          /*
+            We got "IS [NOT] NULL" condition against nullable column. We
+            distinguish between "IS NOT NULL" and "IS NULL" by flag. For
+            "IS NOT NULL" flag is set to HA_READ_KEY_EXACT.
+          */
           if (emit_key_part_name(&tmp, key_part) ||
-              tmp.append(FEDERATED_ISNULL))
+              tmp.append(ranges[i]->flag == HA_READ_KEY_EXACT ?
+                         FEDERATED_ISNULL : " IS NOT NULL "))
             DBUG_RETURN(1);
-          continue;
+          /*
+            We need to adjust pointer and length to be prepared for next
+            key part. As well as check if this was last key part.
+          */
+          goto prepare_for_next_key_part;
         }
       }
 
@@ -1199,12 +1209,18 @@ bool ha_federated::create_where_from_key
       if (tmp.append(FEDERATED_CLOSEPAREN))
         DBUG_RETURN(1);
 
+prepare_for_next_key_part:
       if (store_length >= length)
         break;
       DBUG_PRINT("info", ("remainder %d", remainder));
       DBUG_ASSERT(remainder > 1);
       length-= store_length;
-      ptr+= store_length;
+      /*
+        For nullable columns, null-byte is already skipped before, that is
+        ptr was incremented by 1. Since store_length still counts null-byte,
+        we need to subtract 1 from store_length.
+      */
+      ptr+= store_length - test(key_part->null_bit);
       if (tmp.append(FEDERATED_AND))
         DBUG_RETURN(1);
 
Thread
bk commit into 5.0 tree (svoj:1.2570) BUG#33946Sergey Vojtovich14 Feb 2008