diff options
author | unknown <igor@olga.mysql.com> | 2007-04-11 15:12:49 -0700 |
---|---|---|
committer | unknown <igor@olga.mysql.com> | 2007-04-11 15:12:49 -0700 |
commit | 91d3299ce6cf7c8a8da3dc28eafbfec9bf76223c (patch) | |
tree | 745c1c31dac527903107001ecc721039f66d0e96 | |
parent | 37feda2596128fec33ac0e4fe8ff0cd35efd1dec (diff) | |
parent | 7c4db88a922ba635a79d9ffc8b34a5813c66eba8 (diff) | |
download | mariadb-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.result | 14 | ||||
-rw-r--r-- | mysql-test/r/row.result | 18 | ||||
-rw-r--r-- | mysql-test/r/select.result | 9 | ||||
-rw-r--r-- | mysql-test/r/strict.result | 5 | ||||
-rw-r--r-- | mysql-test/t/distinct.test | 13 | ||||
-rw-r--r-- | mysql-test/t/row.test | 25 | ||||
-rw-r--r-- | mysql-test/t/select.test | 13 | ||||
-rw-r--r-- | mysql-test/t/strict.test | 9 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 108 | ||||
-rw-r--r-- | sql/sql_select.cc | 5 | ||||
-rw-r--r-- | sql/sql_table.cc | 27 |
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) { |