diff options
author | heikki@hundin.mysql.fi <> | 2004-01-27 20:10:04 +0200 |
---|---|---|
committer | heikki@hundin.mysql.fi <> | 2004-01-27 20:10:04 +0200 |
commit | 9b04e7b9bb1923cff2d4fb84be9baf59ea49eb14 (patch) | |
tree | 2591c5dd6372b050f3041662e6e6e8828a54b62a /innobase | |
parent | 911a876999e85e63e26140d415e154a4a24222cd (diff) | |
download | mariadb-git-9b04e7b9bb1923cff2d4fb84be9baf59ea49eb14.tar.gz |
data0data.ic, data0data.h, row0sel.c:
Fix bug #2483 with InnoDB, UNIQUE secondary index, and NULL values in that unique index; with the IS NULL predicate, InnoDB returned only the first matching row, though there can be many
Diffstat (limited to 'innobase')
-rw-r--r-- | innobase/include/data0data.h | 8 | ||||
-rw-r--r-- | innobase/include/data0data.ic | 25 | ||||
-rw-r--r-- | innobase/row/row0sel.c | 11 |
3 files changed, 43 insertions, 1 deletions
diff --git a/innobase/include/data0data.h b/innobase/include/data0data.h index 889d148d3fe..2ec94a9517a 100644 --- a/innobase/include/data0data.h +++ b/innobase/include/data0data.h @@ -262,6 +262,14 @@ dtuple_set_types_binary( /*====================*/ dtuple_t* tuple, /* in: data tuple */ ulint n); /* in: number of fields to set */ +/************************************************************************** +Checks if a dtuple contains an SQL null value. */ +UNIV_INLINE +ibool +dtuple_contains_null( +/*=================*/ + /* out: TRUE if some field is SQL null */ + dtuple_t* tuple); /* in: dtuple */ /************************************************************** Checks that a data field is typed. Asserts an error if not. */ diff --git a/innobase/include/data0data.ic b/innobase/include/data0data.ic index d356664df21..bc5a93cb2f8 100644 --- a/innobase/include/data0data.ic +++ b/innobase/include/data0data.ic @@ -406,3 +406,28 @@ data_write_sql_null( data[j] = '\0'; } } + +/************************************************************************** +Checks if a dtuple contains an SQL null value. */ +UNIV_INLINE +ibool +dtuple_contains_null( +/*=================*/ + /* out: TRUE if some field is SQL null */ + dtuple_t* tuple) /* in: dtuple */ +{ + ulint n; + ulint i; + + n = dtuple_get_n_fields(tuple); + + for (i = 0; i < n; i++) { + if (dfield_get_len(dtuple_get_nth_field(tuple, i)) + == UNIV_SQL_NULL) { + + return(TRUE); + } + } + + return(FALSE); +}
\ No newline at end of file diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index 27d27b75a1c..fce47a8f9af 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -2818,7 +2818,16 @@ row_search_for_mysql( if (match_mode == ROW_SEL_EXACT && index->type & DICT_UNIQUE && dtuple_get_n_fields(search_tuple) - == dict_index_get_n_unique(index)) { + == dict_index_get_n_unique(index) + && (index->type & DICT_CLUSTERED + || !dtuple_contains_null(search_tuple))) { + + /* Note above that a UNIQUE secondary index can contain many + rows with the same key value if one of the columns is the SQL + null. A clustered index under MySQL can never contain null + columns because we demand that all the columns in primary key + are non-null. */ + unique_search = TRUE; /* Even if the condition is unique, MySQL seems to try to |