summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <igor@olga.mysql.com>2007-04-11 15:12:49 -0700
committerunknown <igor@olga.mysql.com>2007-04-11 15:12:49 -0700
commit91d3299ce6cf7c8a8da3dc28eafbfec9bf76223c (patch)
tree745c1c31dac527903107001ecc721039f66d0e96
parent37feda2596128fec33ac0e4fe8ff0cd35efd1dec (diff)
parent7c4db88a922ba635a79d9ffc8b34a5813c66eba8 (diff)
downloadmariadb-git-91d3299ce6cf7c8a8da3dc28eafbfec9bf76223c.tar.gz
Merge olga.mysql.com:/home/igor/mysql-5.0-opt
into olga.mysql.com:/home/igor/mysql-5.1-opt mysql-test/r/distinct.result: Auto merged mysql-test/r/row.result: Auto merged mysql-test/r/select.result: Auto merged mysql-test/r/strict.result: Auto merged mysql-test/t/select.test: Auto merged mysql-test/t/strict.test: Auto merged sql/sql_select.cc: Auto merged sql/sql_table.cc: Auto merged sql/item_cmpfunc.cc: Manual merge
-rw-r--r--mysql-test/r/distinct.result14
-rw-r--r--mysql-test/r/row.result18
-rw-r--r--mysql-test/r/select.result9
-rw-r--r--mysql-test/r/strict.result5
-rw-r--r--mysql-test/t/distinct.test13
-rw-r--r--mysql-test/t/row.test25
-rw-r--r--mysql-test/t/select.test13
-rw-r--r--mysql-test/t/strict.test9
-rw-r--r--sql/item_cmpfunc.cc108
-rw-r--r--sql/sql_select.cc5
-rw-r--r--sql/sql_table.cc27
11 files changed, 202 insertions, 44 deletions
diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result
index 109ddcd02e1..20538694218 100644
--- a/mysql-test/r/distinct.result
+++ b/mysql-test/r/distinct.result
@@ -668,3 +668,17 @@ NULL
3
4
DROP TABLE t1;
+CREATE TABLE t1 (a INT, b INT);
+INSERT INTO t1 VALUES(1,1),(1,2),(1,3);
+SELECT DISTINCT a, b FROM t1;
+a b
+1 1
+1 2
+1 3
+SELECT DISTINCT a, a, b FROM t1;
+a a b
+1 1 1
+1 1 2
+1 1 3
+DROP TABLE t1;
+End of 5.0 tests
diff --git a/mysql-test/r/row.result b/mysql-test/r/row.result
index 26d616df2f3..e6dea211fdc 100644
--- a/mysql-test/r/row.result
+++ b/mysql-test/r/row.result
@@ -175,6 +175,24 @@ ROW(2,10) <=> ROW(3,4)
SELECT ROW(NULL,10) <=> ROW(3,NULL);
ROW(NULL,10) <=> ROW(3,NULL)
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)
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
diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result
index f88f046f0ac..6ffb769292f 100644
--- a/mysql-test/r/select.result
+++ b/mysql-test/r/select.result
@@ -3971,4 +3971,13 @@ t2.access_id IN (1,4) AND t.access_id IS NULL AND t2.faq_id in (265);
faq_id
265
DROP TABLE t1,t2;
+CREATE TABLE t1 (a INT, b INT, KEY inx (b,a));
+INSERT INTO t1 VALUES (1,1), (1,2), (1,3), (1,4), (1,5), (1, 6), (1,7);
+EXPLAIN SELECT COUNT(*) FROM t1 f1 INNER JOIN t1 f2
+ON ( f1.b=f2.b AND f1.a<f2.a )
+WHERE 1 AND f1.b NOT IN (100,2232,3343,51111);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE f1 index inx inx 10 NULL 7 Using where; Using index
+1 SIMPLE f2 ref inx inx 5 test.f1.b 1 Using where; Using index
+DROP TABLE t1;
End of 5.0 tests
diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result
index 74cd723e130..a2cc3ce4d75 100644
--- a/mysql-test/r/strict.result
+++ b/mysql-test/r/strict.result
@@ -1386,4 +1386,9 @@ ERROR 01000: Data truncated for column 'a' at row 1
insert into t1 values ('2E3x');
ERROR 01000: Data truncated for column 'a' at row 1
drop table t1;
+set sql_mode='traditional';
+create table t1 (f1 set('a','a'));
+ERROR HY000: Column 'f1' has duplicated value 'a' in SET
+create table t1 (f1 enum('a','a'));
+ERROR HY000: Column 'f1' has duplicated value 'a' in ENUM
End of 5.0 tests
diff --git a/mysql-test/t/distinct.test b/mysql-test/t/distinct.test
index 476e4ce7735..7310f98cd16 100644
--- a/mysql-test/t/distinct.test
+++ b/mysql-test/t/distinct.test
@@ -540,3 +540,16 @@ EXPLAIN SELECT a FROM t1 GROUP BY a;
SELECT a FROM t1 GROUP BY a;
DROP TABLE t1;
+
+#
+#Bug #27659: SELECT DISTINCT returns incorrect result set when field is
+#repeated
+#
+#
+CREATE TABLE t1 (a INT, b INT);
+INSERT INTO t1 VALUES(1,1),(1,2),(1,3);
+SELECT DISTINCT a, b FROM t1;
+SELECT DISTINCT a, a, b FROM t1;
+DROP TABLE t1;
+
+--echo End of 5.0 tests
diff --git a/mysql-test/t/row.test b/mysql-test/t/row.test
index 1d5c7a543ea..bf25359b7be 100644
--- a/mysql-test/t/row.test
+++ b/mysql-test/t/row.test
@@ -85,6 +85,31 @@ drop table t1;
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
#
diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test
index f613b836350..1f8a00409e6 100644
--- a/mysql-test/t/select.test
+++ b/mysql-test/t/select.test
@@ -3346,4 +3346,17 @@ SELECT t2.faq_id
DROP TABLE t1,t2;
+
+#
+# Bug #19372: Optimizer does not use index anymore when WHERE index NOT IN
+# () is added
+#
+CREATE TABLE t1 (a INT, b INT, KEY inx (b,a));
+
+INSERT INTO t1 VALUES (1,1), (1,2), (1,3), (1,4), (1,5), (1, 6), (1,7);
+EXPLAIN SELECT COUNT(*) FROM t1 f1 INNER JOIN t1 f2
+ ON ( f1.b=f2.b AND f1.a<f2.a )
+ WHERE 1 AND f1.b NOT IN (100,2232,3343,51111);
+DROP TABLE t1;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test
index 3ff84c35f16..fe731f4b0a1 100644
--- a/mysql-test/t/strict.test
+++ b/mysql-test/t/strict.test
@@ -1249,4 +1249,13 @@ insert into t1 values ('2000a');
insert into t1 values ('2E3x');
drop table t1;
+#
+# Bug#27069 set with identical elements are created
+#
+set sql_mode='traditional';
+--error 1291
+create table t1 (f1 set('a','a'));
+--error 1291
+create table t1 (f1 enum('a','a'));
+
--echo End of 5.0 tests
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 36326b46be6..fb17fde99da 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -69,56 +69,80 @@ static void agg_result_type(Item_result *type, Item **items, uint nitems)
/*
- Aggregates result types from the array of items.
+ Compare row signature of two expressions
- SYNOPSIS
- agg_cmp_type()
- items array of items to aggregate the type from
- nitems number of items in the array
+ SYNOPSIS:
+ cmp_row_type()
+ item1 the first expression
+ item2 the second expression
DESCRIPTION
- 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 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 Item_result agg_cmp_type(Item **items, uint nitems)
+static int cmp_row_type(Item* item1, Item* item2)
{
- uint i;
- Item_result type= items[0]->result_type();
- for (i= 1 ; i < nitems ; i++)
- type= item_cmp_type(type, items[i]->result_type());
- return type;
+ uint n= item1->cols();
+ if (item2->check_cols(n))
+ return 1;
+ for (uint i=0; i<n; i++)
+ {
+ if (item2->element_index(i)->check_cols(item1->element_index(i)->cols()) ||
+ (item1->element_index(i)->result_type() == ROW_RESULT &&
+ cmp_row_type(item1->element_index(i), item2->element_index(i))))
+ return 1;
+ }
+ return 0;
}
/*
- Collects different types for comparison of first item with each other items
+ Aggregates result types from the array of items.
- SYNOPSIS
- collect_cmp_types()
- items Array of items to collect types from
- nitems Number of items in the array
+ SYNOPSIS:
+ agg_cmp_type()
+ type [out] the aggregated type
+ items array of items to aggregate the type from
+ nitems number of items in the array
DESCRIPTION
- This function collects different result types for comparison of the first
- item in the list with each of the remaining items in the 'items' array.
+ 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
- Bitmap of collected types
+ RETURN VALUES
+ 1 type incompatibility has been detected
+ 0 otherwise
*/
-static uint collect_cmp_types(Item **items, uint nitems)
+static int agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems)
{
uint i;
- uint found_types;
- Item_result left_result= items[0]->result_type();
- DBUG_ASSERT(nitems > 1);
- found_types= 0;
- for (i= 1; i < nitems ; i++)
- found_types|= 1<< (uint)item_cmp_type(left_result,
- items[i]->result_type());
- return found_types;
+ 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;
}
@@ -1355,7 +1379,8 @@ void Item_func_between::fix_length_and_dec()
*/
if (!args[0] || !args[1] || !args[2])
return;
- cmp_type= agg_cmp_type(args, 3);
+ if ( agg_cmp_type(&cmp_type, args, 3))
+ return;
if (cmp_type == STRING_RESULT &&
agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV, 1))
return;
@@ -2060,6 +2085,23 @@ void Item_func_case::fix_length_and_dec()
return;
}
}
+
+ found_types= collect_cmp_types(agg, nagg);
+
+ for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
+ {
+ if (found_types & (1 << i) && !cmp_items[i])
+ {
+ DBUG_ASSERT((Item_result)i != ROW_RESULT);
+ if ((Item_result)i == STRING_RESULT &&
+ agg_arg_charsets(cmp_collation, agg, nagg, MY_COLL_CMP_CONV, 1))
+ return;
+ if (!(cmp_items[i]=
+ cmp_item::get_comparator((Item_result)i,
+ cmp_collation.collation)))
+ return;
+ }
+ }
}
if (else_expr_num == -1 || args[else_expr_num]->maybe_null)
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index eb6f4efccc3..42cfa8bdbd4 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -13799,9 +13799,7 @@ create_distinct_group(THD *thd, Item **ref_pointer_array,
ORDER *ord_iter;
for (ord_iter= group; ord_iter; ord_iter= ord_iter->next)
if ((*ord_iter->item)->eq(item, 1))
- break;
- if (ord_iter)
- continue;
+ goto next_item;
ORDER *ord=(ORDER*) thd->calloc(sizeof(ORDER));
if (!ord)
@@ -13816,6 +13814,7 @@ create_distinct_group(THD *thd, Item **ref_pointer_array,
*prev=ord;
prev= &ord->next;
}
+next_item:
ref_pointer_array++;
}
*prev=0;
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 0ec0a8e0f86..a6af69eabfc 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1929,10 +1929,11 @@ static int sort_keys(KEY *a, KEY *b)
which has some duplicates on its right
RETURN VALUES
- void
+ 0 ok
+ 1 Error
*/
-void check_duplicates_in_interval(const char *set_or_name,
+bool check_duplicates_in_interval(const char *set_or_name,
const char *name, TYPELIB *typelib,
CHARSET_INFO *cs, unsigned int *dup_val_count)
{
@@ -1948,6 +1949,13 @@ void check_duplicates_in_interval(const char *set_or_name,
tmp.count--;
if (find_type2(&tmp, (const char*)*cur_value, *cur_length, cs))
{
+ if ((current_thd->variables.sql_mode &
+ (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES)))
+ {
+ my_error(ER_DUPLICATED_VALUE_IN_TYPE, MYF(0),
+ name,*cur_value,set_or_name);
+ return 1;
+ }
push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_DUPLICATED_VALUE_IN_TYPE,
ER(ER_DUPLICATED_VALUE_IN_TYPE),
@@ -1955,6 +1963,7 @@ void check_duplicates_in_interval(const char *set_or_name,
(*dup_val_count)++;
}
}
+ return 0;
}
@@ -2090,9 +2099,10 @@ int prepare_create_field(create_field *sql_field,
if (sql_field->charset->state & MY_CS_BINSORT)
sql_field->pack_flag|=FIELDFLAG_BINARY;
sql_field->unireg_check=Field::INTERVAL_FIELD;
- check_duplicates_in_interval("ENUM",sql_field->field_name,
- sql_field->interval,
- sql_field->charset, &dup_val_count);
+ if (check_duplicates_in_interval("ENUM",sql_field->field_name,
+ sql_field->interval,
+ sql_field->charset, &dup_val_count))
+ DBUG_RETURN(1);
break;
case MYSQL_TYPE_SET:
sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
@@ -2100,9 +2110,10 @@ int prepare_create_field(create_field *sql_field,
if (sql_field->charset->state & MY_CS_BINSORT)
sql_field->pack_flag|=FIELDFLAG_BINARY;
sql_field->unireg_check=Field::BIT_FIELD;
- check_duplicates_in_interval("SET",sql_field->field_name,
- sql_field->interval,
- sql_field->charset, &dup_val_count);
+ if (check_duplicates_in_interval("SET",sql_field->field_name,
+ sql_field->interval,
+ sql_field->charset, &dup_val_count))
+ DBUG_RETURN(1);
/* Check that count of unique members is not more then 64 */
if (sql_field->interval->count - dup_val_count > sizeof(longlong)*8)
{