List:Commits« Previous MessageNext Message »
From:igor Date:April 11 2007 8:57pm
Subject:bk commit into 5.0 tree (igor:1.2444)
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of igor. When igor 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, 2007-04-11 11:57:40-07:00, igor@stripped +3 -0
  Merge olga.mysql.com:/home/igor/dev-opt/mysql-4.1-opt-bug27484
  into  olga.mysql.com:/home/igor/mysql-5.0-opt
  MERGE: 1.1616.2877.78

  mysql-test/r/row.result@stripped, 2007-04-11 11:57:38-07:00, igor@stripped +0 -6
    Manual merge
    MERGE: 1.18.1.1

  mysql-test/t/row.test@stripped, 2007-04-11 11:44:08-07:00, igor@stripped +0 -0
    Auto merged
    MERGE: 1.16.1.2

  sql/item_cmpfunc.cc@stripped, 2007-04-11 11:57:38-07:00, igor@stripped +15 -17
    Manual merge
    MERGE: 1.111.23.18

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	igor
# Host:	olga.mysql.com
# Root:	/home/igor/mysql-5.0-opt/RESYNC

--- 1.242/sql/item_cmpfunc.cc	2007-04-11 11:57:46 -07:00
+++ 1.243/sql/item_cmpfunc.cc	2007-04-11 11:57:46 -07:00
@@ -69,6 +69,42 @@
 
 
 /*
+  Compare row signature of two expressions
+
+  SYNOPSIS:
+    cmp_row_type()
+    item1          the first expression
+    item2         the second expression
+
+  DESCRIPTION
+    The function checks that two expressions have compatible row signatures
+    i.e. that the number of columns they return are the same and that if they
+    are both row expressions then each component from the first expression has 
+    a row signature compatible with the signature of the corresponding component
+    of the second expression.
+
+  RETURN VALUES
+    1  type incompatibility has been detected
+    0  otherwise
+*/
+
+static int cmp_row_type(Item* item1, Item* item2)
+{
+  uint n= item1->cols();
+  if (item2->check_cols(n))
+    return 1;
+  for (uint i=0; i<n; i++)
+  {
+    if (item2->el(i)->check_cols(item1->el(i)->cols()) ||
+        (item1->el(i)->result_type() == ROW_RESULT &&
+         cmp_row_type(item1->el(i), item2->el(i))))
+      return 1;
+  }
+  return 0;
+}
+
+
+/*
   Aggregates result types from the array of items.
 
   SYNOPSIS:
@@ -82,14 +118,32 @@
     This function aggregates result types from the array of items. Found type
     supposed to be used later for comparison of values of these items.
     Aggregation itself is performed by the item_cmp_type() function.
+    The function also checks compatibility of row signatures for the
+    submitted items (see the spec for the cmp_row_type function). 
+
+  RETURN VALUES
+    1  type incompatibility has been detected
+    0  otherwise
 */
 
-static void agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems)
+static int agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems)
 {
   uint i;
   type[0]= items[0]->result_type();
   for (i= 1 ; i < nitems ; i++)
+  {
     type[0]= item_cmp_type(type[0], items[i]->result_type());
+    /*
+      When aggregating types of two row expressions we have to check
+      that they have the same cardinality and that each component
+      of the first row expression has a compatible row signature with
+      the signature of the corresponding component of the second row
+      expression.
+    */ 
+    if (type[0] == ROW_RESULT && cmp_row_type(items[0], items[i]))
+      return 1;     // error found: invalid usage of rows
+  }
+  return 0;
 }
 
 
@@ -1305,7 +1359,8 @@
   */
   if (!args[0] || !args[1] || !args[2])
     return;
-  agg_cmp_type(thd, &cmp_type, args, 3);
+  if ( agg_cmp_type(thd, &cmp_type, args, 3))
+    return;
   if (cmp_type == STRING_RESULT &&
       agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV, 1))
    return;
@@ -2021,7 +2076,8 @@
     for (nagg= 0; nagg < ncases/2 ; nagg++)
       agg[nagg+1]= args[nagg*2];
     nagg++;
-    agg_cmp_type(thd, &cmp_type, agg, nagg);
+    if (agg_cmp_type(thd, &cmp_type, agg, nagg))
+      return;
     if ((cmp_type == STRING_RESULT) &&
         agg_arg_charsets(cmp_collation, agg, nagg, MY_COLL_CMP_CONV, 1))
       return;
@@ -2710,7 +2766,8 @@
   uint const_itm= 1;
   THD *thd= current_thd;
   
-  agg_cmp_type(thd, &cmp_type, args, arg_count);
+  if (agg_cmp_type(thd, &cmp_type, args, arg_count))
+    return;
 
   if (cmp_type == STRING_RESULT &&
       agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1))

--- 1.25/mysql-test/r/row.result	2007-04-11 11:57:46 -07:00
+++ 1.26/mysql-test/r/row.result	2007-04-11 11:57:46 -07:00
@@ -175,12 +175,24 @@
 SELECT ROW(NULL,10) <=> ROW(3,NULL);
 ROW(NULL,10) <=> ROW(3,NULL)
 0
-SELECT ROW(1,1,1) = ROW(1,1,1) as `1`, ROW(1,1,1) = ROW(1,2,1) as `0`, ROW(1,NULL,1) =
ROW(2,2,1) as `0`, ROW(1,NULL,1) = ROW(1,2,2) as `0`, ROW(1,NULL,1) = ROW(1,2,1) as
`null` ;
-1	0	0	0	null
-1	0	0	0	NULL
-select row(NULL,1)=(2,0);
-row(NULL,1)=(2,0)
-0
+SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),ROW(1,1));
+ERROR 21000: Operand should contain 2 column(s)
+SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),ROW(1,1),ROW(1,ROW(2,3)));
+ERROR 21000: Operand should contain 2 column(s)
+SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),ROW(1,ROW(2,2,2)));
+ERROR 21000: Operand should contain 2 column(s)
+SELECT ROW(1,ROW(2,3,4)) IN (ROW(1,ROW(2,3,4)),ROW(1,ROW(2,2)));
+ERROR 21000: Operand should contain 3 column(s)
+SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),(SELECT 1,1));
+ERROR 21000: Operand should contain 2 column(s)
+SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),(SELECT 1,1),ROW(1,ROW(2,4)));
+ERROR 21000: Operand should contain 2 column(s)
+SELECT ROW(1,ROW(2,3)) IN ((SELECT 1,1),ROW(1,ROW(2,3)));
+ERROR 21000: Operand should contain 2 column(s)
+SELECT ROW(2,1) IN (ROW(21,2),ROW(ROW(1,1,3),0));
+ERROR 21000: Operand should contain 1 column(s)
+SELECT ROW(2,1) IN (ROW(ROW(1,1,3),0),ROW(21,2));
+ERROR 21000: Operand should contain 1 column(s)
 CREATE TABLE t1 (a int, b int, PRIMARY KEY (a,b));
 INSERT INTO t1 VALUES (1,1), (2,1), (3,1), (1,2), (3,2), (3,3);
 EXPLAIN SELECT * FROM t1 WHERE a=3 AND b=2;

--- 1.22/mysql-test/t/row.test	2007-04-11 11:57:46 -07:00
+++ 1.23/mysql-test/t/row.test	2007-04-11 11:57:46 -07:00
@@ -85,6 +85,31 @@
 SELECT ROW(2,10) <=> ROW(3,4);
 SELECT ROW(NULL,10) <=> ROW(3,NULL);
 
+#
+# Bug #27484: nested row expressions in IN predicate
+#
+
+--error 1241
+SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),ROW(1,1));
+--error 1241
+SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),ROW(1,1),ROW(1,ROW(2,3)));
+--error 1241
+SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),ROW(1,ROW(2,2,2)));
+--error 1241
+SELECT ROW(1,ROW(2,3,4)) IN (ROW(1,ROW(2,3,4)),ROW(1,ROW(2,2)));
+
+--error 1241
+SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),(SELECT 1,1));
+--error 1241
+SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),(SELECT 1,1),ROW(1,ROW(2,4)));
+--error 1241
+SELECT ROW(1,ROW(2,3)) IN ((SELECT 1,1),ROW(1,ROW(2,3)));
+
+--error 1241
+SELECT ROW(2,1) IN (ROW(21,2),ROW(ROW(1,1,3),0));
+--error 1241
+SELECT ROW(2,1) IN (ROW(ROW(1,1,3),0),ROW(21,2));
+
 # End of 4.1 tests
 
 #
Thread
bk commit into 5.0 tree (igor:1.2444)igor11 Apr