From: Date: December 6 2004 6:18pm Subject: bk commit into 5.0 tree (monty:1.1720) List-Archive: http://lists.mysql.com/internals/19384 Message-Id: <20041206171842.9910A48FA0@narttu.mysql.com> Below is the list of changes that have just been committed into a local 5.0 repository of monty. When monty 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://www.mysql.com/doc/I/n/Installing_source_tree.html ChangeSet 1.1720 04/12/06 19:18:35 monty@stripped +83 -0 Merge with new VARCHAR code strings/ctype-ucs2.c 1.34 04/12/06 19:18:30 monty@stripped +4 -4 Added new argument to my_strnncollsp_ucs2() Simply code strings/ctype-tis620.c 1.79 04/12/06 19:18:30 monty@stripped +2 -3 Merge with VARCHAR code strings/ctype-mb.c 1.35 04/12/06 19:18:30 monty@stripped +0 -3 Don't pad my_like_range with max_str for simple LIKE expression sql/table.h 1.79 04/12/06 19:18:30 monty@stripped +1 -1 Merge with VARCHAR code sql/sql_update.cc 1.132 04/12/06 19:18:30 monty@stripped +0 -0 Merge with VARCHAR code sql/sql_table.cc 1.200 04/12/06 19:18:30 monty@stripped +0 -1 Merge with VARCHAR code sql/sql_parse.cc 1.374 04/12/06 19:18:30 monty@stripped +4 -12 Merge with VARCHAR code sql/sql_acl.cc 1.115 04/12/06 19:18:30 monty@stripped +35 -51 Merge with VARCHAR code sql/item.cc 1.98 04/12/06 19:18:30 monty@stripped +0 -9 Merge with VARCHAR code sql/field.cc 1.207 04/12/06 19:18:30 monty@stripped +2 -4 Merge with VARCHAR code mysql-test/t/innodb.test 1.68 04/12/06 19:18:30 monty@stripped +8 -8 Merge with VARCHAR code mysql-test/t/heap.test 1.20 04/12/06 19:18:30 monty@stripped +21 -21 Merge with VARCHAR code mysql-test/t/bdb.test 1.41 04/12/06 19:18:30 monty@stripped +9 -9 Merge with VARCHAR code mysql-test/r/select.result.es 1.3 04/12/06 19:18:30 monty@stripped +1 -1 Merge with VARCHAR code mysql-test/r/innodb.result 1.85 04/12/06 19:18:30 monty@stripped +2 -2 Merge with VARCHAR code mysql-test/r/heap.result 1.27 04/12/06 19:18:30 monty@stripped +16 -16 Merge with VARCHAR code mysql-test/r/bdb.result 1.35 04/12/06 19:18:30 monty@stripped +7 -7 Merge with VARCHAR code tests/client_test.c 1.83 04/12/06 18:04:41 monty@stripped +0 -0 Auto merged strings/decimal.c 1.32 04/12/06 18:04:40 monty@stripped +0 -0 Auto merged strings/ctype-win1250ch.c 1.43 04/12/06 18:04:40 monty@stripped +0 -0 Auto merged strings/ctype-utf8.c 1.79 04/12/06 18:04:40 monty@stripped +0 -0 Auto merged strings/ctype-uca.c 1.27 04/12/06 18:04:40 monty@stripped +0 -0 Auto merged strings/ctype-czech.c 1.53 04/12/06 18:04:40 monty@stripped +0 -0 Auto merged sql/table.cc 1.131 04/12/06 18:04:40 monty@stripped +0 -0 Auto merged sql/structs.h 1.42 04/12/06 18:04:40 monty@stripped +0 -0 Auto merged sql/sql_yacc.yy 1.316 04/12/06 18:04:40 monty@stripped +0 -0 Auto merged sql/sql_select.cc 1.261 04/12/06 18:04:39 monty@stripped +2 -3 Auto merged sql/sql_help.cc 1.37 04/12/06 18:04:39 monty@stripped +0 -0 Auto merged sql/sql_base.cc 1.196 04/12/06 18:04:39 monty@stripped +0 -0 Auto merged sql/protocol.cc 1.86 04/12/06 18:04:39 monty@stripped +0 -0 Auto merged sql/opt_sum.cc 1.40 04/12/06 18:04:39 monty@stripped +0 -0 Auto merged sql/opt_range.cc 1.132 04/12/06 18:04:39 monty@stripped +0 -0 Auto merged sql/item_sum.cc 1.111 04/12/06 18:04:39 monty@stripped +0 -0 Auto merged sql/item_cmpfunc.cc 1.128 04/12/06 18:04:38 monty@stripped +0 -0 Auto merged sql/handler.h 1.114 04/12/06 18:04:38 monty@stripped +0 -0 Auto merged sql/ha_ndbcluster.cc 1.121 04/12/06 18:04:38 monty@stripped +0 -0 Auto merged sql/ha_myisam.cc 1.138 04/12/06 18:04:38 monty@stripped +0 -0 Auto merged sql/ha_innodb.h 1.73 04/12/06 18:04:38 monty@stripped +0 -0 Auto merged sql/ha_innodb.cc 1.128 04/12/06 18:04:38 monty@stripped +0 -0 Auto merged sql/ha_heap.cc 1.50 04/12/06 18:04:38 monty@stripped +0 -0 Auto merged sql/field_conv.cc 1.35 04/12/06 18:04:38 monty@stripped +0 -0 Auto merged sql/field.h 1.124 04/12/06 18:04:38 monty@stripped +0 -0 Auto merged scripts/mysql_fix_privilege_tables.sh 1.31 04/12/06 18:04:38 monty@stripped +0 -0 Auto merged ndb/src/common/util/NdbSqlUtil.cpp 1.12 04/12/06 18:04:38 monty@stripped +0 -0 Auto merged mysql-test/t/type_blob.test 1.24 04/12/06 18:04:38 monty@stripped +0 -0 Auto merged mysql-test/t/strict.test 1.7 04/12/06 18:04:38 monty@stripped +0 -0 Auto merged mysql-test/t/ps_1general.test 1.9 04/12/06 18:04:38 monty@stripped +0 -0 Auto merged mysql-test/t/myisam.test 1.36 04/12/06 18:04:38 monty@stripped +0 -0 Auto merged mysql-test/t/endspace.test 1.4 04/12/06 18:04:37 monty@stripped +0 -0 Auto merged mysql-test/t/ctype_ucs.test 1.18 04/12/06 18:04:37 monty@stripped +0 -0 Auto merged mysql-test/r/type_blob.result 1.43 04/12/06 18:04:37 monty@stripped +0 -0 Auto merged mysql-test/r/subselect.result 1.93 04/12/06 18:04:37 monty@stripped +0 -0 Auto merged mysql-test/r/strict.result 1.10 04/12/06 18:04:37 monty@stripped +0 -0 Auto merged mysql-test/r/select.result 1.44 04/12/06 18:04:37 monty@stripped +0 -0 Auto merged mysql-test/r/ps_6bdb.result 1.12 04/12/06 18:04:37 monty@stripped +0 -0 Auto merged mysql-test/r/ps_5merge.result 1.12 04/12/06 18:04:37 monty@stripped +0 -0 Auto merged mysql-test/r/ps_4heap.result 1.11 04/12/06 18:04:37 monty@stripped +0 -0 Auto merged mysql-test/r/ps_3innodb.result 1.14 04/12/06 18:04:37 monty@stripped +0 -0 Auto merged mysql-test/r/ps_2myisam.result 1.12 04/12/06 18:04:37 monty@stripped +0 -0 Auto merged mysql-test/r/ps_1general.result 1.15 04/12/06 18:04:37 monty@stripped +0 -0 Auto merged mysql-test/r/ps.result 1.34 04/12/06 18:04:37 monty@stripped +0 -0 Auto merged mysql-test/r/order_by.result 1.46 04/12/06 18:04:37 monty@stripped +0 -0 Auto merged mysql-test/r/mysqldump.result 1.24 04/12/06 18:04:37 monty@stripped +0 -0 Auto merged mysql-test/r/myisam.result 1.48 04/12/06 18:04:37 monty@stripped +0 -0 Auto merged mysql-test/r/ctype_ucs.result 1.18 04/12/06 18:04:36 monty@stripped +0 -0 Auto merged mysql-test/r/ctype_tis620.result 1.8 04/12/06 18:04:36 monty@stripped +0 -0 Auto merged myisam/mi_write.c 1.47 04/12/06 18:04:36 monty@stripped +0 -0 Auto merged myisam/mi_create.c 1.38 04/12/06 18:04:36 monty@stripped +0 -0 Auto merged myisam/mi_check.c 1.126 04/12/06 18:04:36 monty@stripped +0 -0 Auto merged libmysqld/Makefile.am 1.49 04/12/06 18:04:36 monty@stripped +0 -0 Auto merged libmysql/libmysql.c 1.180 04/12/06 18:04:36 monty@stripped +0 -0 Auto merged include/m_ctype.h 1.103 04/12/06 18:04:36 monty@stripped +0 -0 Auto merged include/decimal.h 1.10 04/12/06 18:04:36 monty@stripped +0 -0 Auto merged heap/hp_write.c 1.20 04/12/06 18:04:36 monty@stripped +0 -0 Auto merged heap/hp_hash.c 1.37 04/12/06 18:04:36 monty@stripped +0 -0 Auto merged heap/hp_delete.c 1.13 04/12/06 18:04:36 monty@stripped +0 -0 Auto merged heap/hp_create.c 1.15 04/12/06 18:04:36 monty@stripped +0 -0 Auto merged client/mysqltest.c 1.122 04/12/06 18:04:36 monty@stripped +0 -0 Auto merged client/mysqldump.c 1.157 04/12/06 18:04:36 monty@stripped +0 -0 Auto merged BitKeeper/deleted/.del-ha_isammrg.cc~dc682e4755d77a2e 1.21 04/12/06 18:04:36 monty@stripped +0 -0 Auto merged BitKeeper/deleted/.del-ha_isam.cc~4dce65904db2675e 1.36 04/12/06 18:04:35 monty@stripped +0 -0 Auto merged BitKeeper/deleted/.del-acinclude.m4~f4ab416bac5003 1.125 04/12/06 18:04:35 monty@stripped +0 -0 Auto merged configure.in 1.235 04/12/06 18:04:35 monty@stripped +0 -0 Auto merged BitKeeper/deleted/.del-ha_isammrg.cc~dc682e4755d77a2e 1.20 04/12/06 18:04:35 monty@stripped +0 -0 Merge rename: sql/ha_isammrg.cc -> BitKeeper/deleted/.del-ha_isammrg.cc~dc682e4755d77a2e BitKeeper/deleted/.del-ha_isam.cc~4dce65904db2675e 1.35 04/12/06 18:04:35 monty@stripped +0 -0 Merge rename: sql/ha_isam.cc -> BitKeeper/deleted/.del-ha_isam.cc~4dce65904db2675e BitKeeper/deleted/.del-acinclude.m4~f4ab416bac5003 1.119.1.2 04/12/06 18:04:35 monty@stripped +0 -0 Merge rename: acinclude.m4 -> BitKeeper/deleted/.del-acinclude.m4~f4ab416bac5003 # 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: monty # Host: narttu.mysql.fi # Root: /home/my/mysql-5.0/RESYNC --- 1.119.1.1/acinclude.m4 2004-12-06 01:59:52 +02:00 +++ 1.125/BitKeeper/deleted/.del-acinclude.m4~f4ab416bac5003 2004-12-06 18:04:35 +02:00 @@ -1597,9 +1597,14 @@ --with-ndb-docs Include the NDB Cluster ndbapi and mgmapi documentation], [ndb_docs="$withval"], [ndb_docs=no]) + AC_ARG_WITH([ndb-port], + [ + --with-ndb-port Port for NDB Cluster management server], + [ndb_port="$withval"], + [ndb_port="default"]) AC_ARG_WITH([ndb-port-base], [ - --with-ndb-port-base Base port for NDB Cluster], + --with-ndb-port-base Base port for NDB Cluster transporters], [ndb_port_base="$withval"], [ndb_port_base="default"]) @@ -1656,6 +1661,7 @@ have_ndbcluster=no ndbcluster_includes= ndbcluster_libs= + ndb_mgmclient_libs= case "$ndbcluster" in yes ) AC_MSG_RESULT([Using NDB Cluster]) @@ -1664,6 +1670,7 @@ ndbcluster_includes="-I../ndb/include -I../ndb/include/ndbapi" ndbcluster_libs="\$(top_builddir)/ndb/src/.libs/libndbclient.a" ndbcluster_system_libs="" + ndb_mgmclient_libs="\$(top_builddir)/ndb/src/mgmclient/libndbmgmclient.la" MYSQL_CHECK_NDB_OPTIONS ;; * ) @@ -1675,6 +1682,7 @@ AC_SUBST(ndbcluster_includes) AC_SUBST(ndbcluster_libs) AC_SUBST(ndbcluster_system_libs) + AC_SUBST(ndb_mgmclient_libs) ]) dnl --------------------------------------------------------------------------- --- 1.156/client/mysqldump.c 2004-12-06 11:38:51 +02:00 +++ 1.157/client/mysqldump.c 2004-12-06 18:04:36 +02:00 @@ -1623,12 +1623,13 @@ we'll dump in hex only BLOB columns. */ is_blob= (opt_hex_blob && field->charsetnr == 63 && - (field->type == FIELD_TYPE_STRING || - field->type == FIELD_TYPE_VAR_STRING || - field->type == FIELD_TYPE_BLOB || - field->type == FIELD_TYPE_LONG_BLOB || - field->type == FIELD_TYPE_MEDIUM_BLOB || - field->type == FIELD_TYPE_TINY_BLOB)) ? 1 : 0; + (field->type == MYSQL_TYPE_STRING || + field->type == MYSQL_TYPE_VAR_STRING || + field->type == MYSQL_TYPE_VARCHAR || + field->type == MYSQL_TYPE_BLOB || + field->type == MYSQL_TYPE_LONG_BLOB || + field->type == MYSQL_TYPE_MEDIUM_BLOB || + field->type == MYSQL_TYPE_TINY_BLOB)) ? 1 : 0; if (extended_insert) { ulong length = lengths[i]; --- 1.234/configure.in 2004-12-06 02:05:20 +02:00 +++ 1.235/configure.in 2004-12-06 18:04:35 +02:00 @@ -2420,7 +2420,6 @@ AC_SUBST(readline_link) AC_SUBST(readline_h_ln_cmd) -MYSQL_CHECK_ISAM MYSQL_CHECK_BDB MYSQL_CHECK_INNODB MYSQL_CHECK_EXAMPLEDB @@ -2480,12 +2479,6 @@ # # Configuration for optional table handlers # - - if test X"$have_isam" != Xno - then - sql_server_dirs="$sql_server_dirs isam merge" - AC_CONFIG_FILES(isam/Makefile merge/Makefile) - fi if test X"$have_berkeley_db" != Xno; then if test X"$have_berkeley_db" != Xyes; then --- 1.14/heap/hp_create.c 2004-12-02 13:06:11 +02:00 +++ 1.15/heap/hp_create.c 2004-12-06 18:04:36 +02:00 @@ -76,9 +76,21 @@ case HA_KEYTYPE_UINT24: case HA_KEYTYPE_INT8: keyinfo->seg[j].flag|= HA_SWAP_KEY; + break; + case HA_KEYTYPE_VARBINARY: + /* Case-insensitiveness is handled in coll->hash_sort */ + keyinfo->seg[j].type= HA_KEYTYPE_VARTEXT; + /* fall_through */ + case HA_KEYTYPE_VARTEXT: + if (!my_binary_compare(keyinfo->seg[j].charset)) + keyinfo->flag|= HA_END_SPACE_KEY; + keyinfo->flag|= HA_VAR_LENGTH_KEY; + break; default: break; } + if (keyinfo->seg[j].flag & HA_END_SPACE_ARE_EQUAL) + keyinfo->flag|= HA_END_SPACE_KEY; } keyinfo->length= length; length+= keyinfo->rb_tree.size_of_element + @@ -89,7 +101,9 @@ if (keyinfo->algorithm == HA_KEY_ALG_BTREE) { key_segs++; /* additional HA_KEYTYPE_END segment */ - if (keyinfo->flag & HA_NULL_PART_KEY) + if (keyinfo->flag & HA_VAR_LENGTH_KEY) + keyinfo->get_key_length= hp_rb_var_key_length; + else if (keyinfo->flag & HA_NULL_PART_KEY) keyinfo->get_key_length= hp_rb_null_key_length; else keyinfo->get_key_length= hp_rb_key_length; --- 1.12/heap/hp_delete.c 2004-10-12 17:21:20 +03:00 +++ 1.13/heap/hp_delete.c 2004-12-06 18:04:36 +02:00 @@ -123,7 +123,7 @@ while (pos->ptr_to_rec != recpos) { - if (flag && !hp_rec_key_cmp(keyinfo, record, pos->ptr_to_rec)) + if (flag && !hp_rec_key_cmp(keyinfo, record, pos->ptr_to_rec, 0)) last_ptr=pos; /* Previous same key */ gpos=pos; if (!(pos=pos->next_key)) --- 1.36/heap/hp_hash.c 2004-11-16 20:36:27 +02:00 +++ 1.37/heap/hp_hash.c 2004-12-06 18:04:36 +02:00 @@ -262,14 +262,27 @@ if (seg->type == HA_KEYTYPE_TEXT) { CHARSET_INFO *cs= seg->charset; - uint char_length= (uint) ((uchar*) key - pos); + uint length= seg->length; if (cs->mbmaxlen > 1) { - uint length= char_length; + uint char_length; char_length= my_charpos(cs, pos, pos + length, length/cs->mbmaxlen); - set_if_smaller(char_length, length); /* QQ: ok to remove? */ + set_if_smaller(length, char_length); } - cs->coll->hash_sort(cs, pos, char_length, &nr, &nr2); + cs->coll->hash_sort(cs, pos, length, &nr, &nr2); + } + else if (seg->type == HA_KEYTYPE_VARTEXT) + { + CHARSET_INFO *cs= seg->charset; + uint length= uint2korr(pos); + if (cs->mbmaxlen > 1) + { + uint char_length; + char_length= my_charpos(cs, pos +2, pos +2 + length, + seg->length/cs->mbmaxlen); + set_if_smaller(length, char_length); + } + cs->coll->hash_sort(cs, pos+2, length, &nr, &nr2); } else { @@ -314,6 +327,19 @@ } cs->coll->hash_sort(cs, pos, char_length, &nr, &nr2); } + else if (seg->type == HA_KEYTYPE_VARTEXT) + { + CHARSET_INFO *cs= seg->charset; + uint length= uint2korr(pos); + if (cs->mbmaxlen > 1) + { + uint char_length; + char_length= my_charpos(cs, pos + 2 , pos + 2 + length, + seg->length/cs->mbmaxlen); + set_if_smaller(length, char_length); + } + cs->coll->hash_sort(cs, pos+2, length, &nr, &nr2); + } else { for (; pos < end ; pos++) @@ -366,6 +392,11 @@ { seg->charset->hash_sort(seg->charset,pos,((uchar*)key)-pos,&nr,NULL); } + else if (seg->type == HA_KEYTYPE_VARTEXT) + { + uint length= uint2korr(pos); + seg->charset->hash_sort(seg->charset, pos+2, length, &nr, NULL); + } else { for ( ; pos < (uchar*) key ; pos++) @@ -400,6 +431,11 @@ { seg->charset->hash_sort(seg->charset,pos,((uchar*)key)-pos,&nr,NULL); } + else if (seg->type == HA_KEYTYPE_VARTEXT) + { + uint length= uint2korr(pos); + seg->charset->hash_sort(seg->charset, pos+2, length, &nr, NULL); + } else { for ( ; pos < end ; pos++) @@ -415,9 +451,28 @@ #endif - /* Compare keys for two records. Returns 0 if they are identical */ +/* + Compare keys for two records. Returns 0 if they are identical + + SYNOPSIS + hp_rec_key_cmp() + keydef Key definition + rec1 Record to compare + rec2 Other record to compare + diff_if_only_endspace_difference + Different number of end space is significant + + NOTES + diff_if_only_endspace_difference is used to allow us to insert + 'a' and 'a ' when there is an an unique key. + + RETURN + 0 Key is identical + <> 0 Key differes +*/ -int hp_rec_key_cmp(HP_KEYDEF *keydef, const byte *rec1, const byte *rec2) +int hp_rec_key_cmp(HP_KEYDEF *keydef, const byte *rec1, const byte *rec2, + my_bool diff_if_only_endspace_difference) { HA_KEYSEG *seg,*endseg; @@ -442,9 +497,9 @@ { uint char_length= seg->length / cs->mbmaxlen; char_length1= my_charpos(cs, pos1, pos1 + seg->length, char_length); - set_if_smaller(char_length1, seg->length); /* QQ: ok to remove? */ + set_if_smaller(char_length1, seg->length); char_length2= my_charpos(cs, pos2, pos2 + seg->length, char_length); - set_if_smaller(char_length2, seg->length); /* QQ: ok to remove? */ + set_if_smaller(char_length2, seg->length); } else { @@ -452,7 +507,30 @@ } if (seg->charset->coll->strnncollsp(seg->charset, pos1,char_length1, - pos2,char_length2)) + pos2,char_length2, 0)) + return 1; + } + else if (seg->type == HA_KEYTYPE_VARTEXT) + { + uchar *pos1= (uchar*)rec1 + seg->start; + uchar *pos2= (uchar*)rec2 + seg->start; + uint char_length1= uint2korr(pos1); + uint char_length2= uint2korr(pos2); + CHARSET_INFO *cs= seg->charset; + if (cs->mbmaxlen > 1) + { + uint char_length= seg->length / cs->mbmaxlen; + char_length1= my_charpos(cs, pos1, pos1 + char_length1, char_length); + set_if_smaller(char_length1, seg->length); + char_length2= my_charpos(cs, pos2, pos2 + char_length2, char_length); + set_if_smaller(char_length2, seg->length); + } + + if (cs->coll->strnncollsp(seg->charset, + pos1+2, char_length1, + pos2+2, char_length2, + seg->flag & HA_END_SPACE_ARE_EQUAL ? + 0 : diff_if_only_endspace_difference)) return 1; } else @@ -504,7 +582,31 @@ if (seg->charset->coll->strnncollsp(seg->charset, (uchar*) pos, char_length_rec, - (uchar*) key, char_length_key)) + (uchar*) key, char_length_key, 0)) + return 1; + } + else if (seg->type == HA_KEYTYPE_VARTEXT) + { + uchar *pos= (uchar*) rec + seg->start; + CHARSET_INFO *cs= seg->charset; + uint char_length_rec= uint2korr(pos); + uint char_length_key= uint2korr(key); + + if (cs->mbmaxlen > 1) + { + uint char_length= seg->length / cs->mbmaxlen; + char_length_key= my_charpos(cs, key+2, key +2 + char_length_key, + char_length); + set_if_smaller(char_length_key, seg->length); + char_length_rec= my_charpos(cs, pos +2 , pos + 2 + char_length_rec, + char_length); + set_if_smaller(char_length_rec, seg->length); + } + + + if (cs->coll->strnncollsp(seg->charset, + (uchar*) pos+2, char_length_rec, + (uchar*) key+2, char_length_key, 0)) return 1; } else @@ -541,6 +643,13 @@ } } +#define FIX_LENGTH(cs, pos, length, char_length) \ + do { \ + if (length > char_length) \ + char_length= my_charpos(cs, pos, pos+length, char_length); \ + set_if_smaller(char_length,length); \ + } while(0) + uint hp_rb_make_key(HP_KEYDEF *keydef, byte *key, const byte *rec, byte *recpos) @@ -593,6 +702,24 @@ } continue; } + + if (seg->flag & HA_VAR_LENGTH_PART) + { + uchar *pos= (uchar*) rec + seg->start; + uint length= seg->length; + uint tmp_length= uint2korr(pos); + CHARSET_INFO *cs= seg->charset; + char_length= length/cs->mbmaxlen; + + pos+=2; /* Skip VARCHAR length */ + set_if_smaller(length,tmp_length); + FIX_LENGTH(cs, pos, length, char_length); + store_key_length_inc(key,char_length); + memcpy((byte*) key,(byte*) pos,(size_t) char_length); + key+= char_length; + continue; + } + char_length= seg->length; if (seg->charset->mbmaxlen > 1) { @@ -643,6 +770,23 @@ } continue; } + if (seg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART)) + { + /* Length of key-part used with heap_rkey() always 2 */ + uint tmp_length=uint2korr(old); + uint length= seg->length; + CHARSET_INFO *cs= seg->charset; + char_length= length/cs->mbmaxlen; + + k_len-= 2+length; + old+= 2; + set_if_smaller(length,tmp_length); /* Safety */ + FIX_LENGTH(cs, old, length, char_length); + store_key_length_inc(key,char_length); + memcpy((byte*) key, old,(size_t) char_length); + key+= char_length; + continue; + } char_length= seg->length; if (seg->charset->mbmaxlen > 1) { @@ -682,6 +826,27 @@ return key - start_key; } + +uint hp_rb_var_key_length(HP_KEYDEF *keydef, const byte *key) +{ + const byte *start_key= key; + HA_KEYSEG *seg, *endseg; + + for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++) + { + uint length= seg->length; + if (seg->null_bit && !*key++) + continue; + if (seg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART)) + { + get_key_length(length, key); + } + key+= length; + } + return key - start_key; +} + + /* Test if any of the key parts are NULL. Return: --- 1.19/heap/hp_write.c 2004-10-12 17:21:20 +03:00 +++ 1.20/heap/hp_write.c 2004-12-06 18:04:36 +02:00 @@ -105,7 +105,7 @@ custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos); if (keyinfo->flag & HA_NOSAME) { - custom_arg.search_flag= SEARCH_FIND | SEARCH_SAME; + custom_arg.search_flag= SEARCH_FIND | SEARCH_SAME | SEARCH_UPDATE; keyinfo->rb_tree.flag= TREE_NO_DUPS; } else @@ -369,7 +369,7 @@ pos=empty; do { - if (! hp_rec_key_cmp(keyinfo, record, pos->ptr_to_rec)) + if (! hp_rec_key_cmp(keyinfo, record, pos->ptr_to_rec, 1)) { DBUG_RETURN(my_errno=HA_ERR_FOUND_DUPP_KEY); } --- 1.102/include/m_ctype.h 2004-11-22 09:58:35 +02:00 +++ 1.103/include/m_ctype.h 2004-12-06 18:04:36 +02:00 @@ -106,7 +106,8 @@ int (*strnncoll)(struct charset_info_st *, const uchar *, uint, const uchar *, uint, my_bool); int (*strnncollsp)(struct charset_info_st *, - const uchar *, uint, const uchar *, uint); + const uchar *, uint, const uchar *, uint, + my_bool diff_if_only_endspace_difference); int (*strnxfrm)(struct charset_info_st *, uchar *, uint, const uchar *, uint); my_bool (*like_range)(struct charset_info_st *, @@ -259,7 +260,8 @@ const uchar *, uint, my_bool); extern int my_strnncollsp_simple(CHARSET_INFO *, const uchar *, uint, - const uchar *, uint); + const uchar *, uint, + my_bool diff_if_only_endspace_difference); extern void my_hash_sort_simple(CHARSET_INFO *cs, const uchar *key, uint len, --- 1.179/libmysql/libmysql.c 2004-11-20 19:31:42 +02:00 +++ 1.180/libmysql/libmysql.c 2004-12-06 18:04:36 +02:00 @@ -3151,6 +3151,7 @@ case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_BLOB: + case MYSQL_TYPE_VARCHAR: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_STRING: param->store_param_func= store_param_str; @@ -4035,6 +4036,7 @@ DBUG_ASSERT(param->buffer_length != 0); param->fetch_result= fetch_result_bin; break; + case MYSQL_TYPE_VARCHAR: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_STRING: DBUG_ASSERT(param->buffer_length != 0); @@ -4099,6 +4101,7 @@ case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_BLOB: + case MYSQL_TYPE_VARCHAR: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_STRING: param->skip_result= skip_result_string; --- 1.125/myisam/mi_check.c 2004-11-12 19:15:43 +02:00 +++ 1.126/myisam/mi_check.c 2004-12-06 18:04:36 +02:00 @@ -2033,7 +2033,7 @@ sort_param.key_length+=keyseg[i].length; if (keyseg[i].flag & HA_SPACE_PACK) sort_param.key_length+=get_pack_length(keyseg[i].length); - if (keyseg[i].flag & (HA_BLOB_PART | HA_VAR_LENGTH)) + if (keyseg[i].flag & (HA_BLOB_PART | HA_VAR_LENGTH_PART)) sort_param.key_length+=2 + test(keyseg[i].length >= 127); if (keyseg[i].flag & HA_NULL_PART) sort_param.key_length++; @@ -2442,7 +2442,7 @@ sort_param[i].key_length+=keyseg->length; if (keyseg->flag & HA_SPACE_PACK) sort_param[i].key_length+=get_pack_length(keyseg->length); - if (keyseg->flag & (HA_BLOB_PART | HA_VAR_LENGTH)) + if (keyseg->flag & (HA_BLOB_PART | HA_VAR_LENGTH_PART)) sort_param[i].key_length+=2 + test(keyseg->length >= 127); if (keyseg->flag & HA_NULL_PART) sort_param[i].key_length++; --- 1.37/myisam/mi_create.c 2004-11-23 16:03:07 +02:00 +++ 1.38/myisam/mi_create.c 2004-12-06 18:04:36 +02:00 @@ -276,8 +276,7 @@ goto err; #endif /*HAVE_SPATIAL*/ } - else - if (keydef->flag & HA_FULLTEXT) + else if (keydef->flag & HA_FULLTEXT) { keydef->flag=HA_FULLTEXT | HA_PACK_KEY | HA_VAR_LENGTH_KEY; options|=HA_OPTION_PACK_KEYS; /* Using packed keys */ @@ -311,7 +310,7 @@ /* Only use HA_PACK_KEY when first segment is a variable length key */ if (!(keydef->seg[0].flag & (HA_SPACE_PACK | HA_BLOB_PART | - HA_VAR_LENGTH))) + HA_VAR_LENGTH_PART))) { /* pack relative to previous key */ keydef->flag&= ~HA_PACK_KEY; @@ -345,12 +344,18 @@ case HA_KEYTYPE_UINT24: case HA_KEYTYPE_INT8: keyseg->flag|= HA_SWAP_KEY; - /* fall through */ + break; + case HA_KEYTYPE_VARTEXT: + case HA_KEYTYPE_VARBINARY: + if (!(keyseg->flag & HA_BLOB_PART)) + keyseg->flag|= HA_VAR_LENGTH_PART; + break; default: break; } if (keyseg->flag & HA_SPACE_PACK) { + DBUG_ASSERT(!(keyseg->flag & HA_VAR_LENGTH_PART)); keydef->flag |= HA_SPACE_PACK_USED | HA_VAR_LENGTH_KEY; options|=HA_OPTION_PACK_KEYS; /* Using packed keys */ length++; /* At least one length byte */ @@ -361,7 +366,7 @@ length+=2; } } - if (keyseg->flag & (HA_VAR_LENGTH | HA_BLOB_PART)) + if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART)) { keydef->flag|=HA_VAR_LENGTH_KEY; length++; /* At least one length byte */ --- 1.46/myisam/mi_write.c 2004-11-25 00:16:06 +02:00 +++ 1.47/myisam/mi_write.c 2004-12-06 18:04:36 +02:00 @@ -248,7 +248,7 @@ comp_flag=SEARCH_BIGGER; /* Put after same key */ else if (keyinfo->flag & (HA_NOSAME|HA_FULLTEXT)) { - comp_flag=SEARCH_FIND | SEARCH_UPDATE; /* No dupplicates */ + comp_flag=SEARCH_FIND | SEARCH_UPDATE; /* No duplicates */ if (keyinfo->flag & HA_NULL_ARE_EQUAL) comp_flag|= SEARCH_NULL_ARE_EQUAL; } --- 1.30/scripts/mysql_fix_privilege_tables.sh 2004-11-28 21:40:01 +02:00 +++ 1.31/scripts/mysql_fix_privilege_tables.sh 2004-12-06 18:04:38 +02:00 @@ -13,7 +13,7 @@ port="" socket="" database="mysql" -bindir="" +bindir="." pkgdatadir="@pkgdatadir@" file=mysql_fix_privilege_tables.sql @@ -74,6 +74,7 @@ # Get first arguments from the my.cfg file, groups [mysqld] and # [mysql_install_db], and then merge with the command line arguments +print_defaults=my_print_defaults for dir in ./bin @bindir@ @bindir@ extra $bindir/../bin $bindir/../extra do if test -x $dir/my_print_defaults --- 1.206/sql/field.cc 2004-12-06 02:05:21 +02:00 +++ 1.207/sql/field.cc 2004-12-06 19:18:30 +02:00 @@ -429,8 +429,7 @@ copy->length-=table->blob_ptr_size; return copy->length; } - else if (!zero_pack() && (type() == FIELD_TYPE_STRING && copy->length > 4 || - type() == FIELD_TYPE_VAR_STRING)) + else if (!zero_pack() && (type() == FIELD_TYPE_STRING && copy->length >= 4)) copy->strip=1; /* Remove end space */ else copy->strip=0; @@ -479,6 +478,26 @@ return test(table->file->index_flags(idx, part, 1) & HA_READ_RANGE); } + +Field *Field::new_field(MEM_ROOT *root, struct st_table *new_table) +{ + Field *tmp; + if (!(tmp= (Field*) memdup_root(root,(char*) this,size_of()))) + return 0; + + if (tmp->table->maybe_null) + tmp->flags&= ~NOT_NULL_FLAG; + tmp->table= new_table; + tmp->key_start.init(0); + tmp->part_of_key.init(0); + tmp->part_of_sortkey.init(0); + tmp->unireg_check=Field::NONE; + tmp->flags&= (NOT_NULL_FLAG | BLOB_FLAG | UNSIGNED_FLAG | + ZEROFILL_FLAG | BINARY_FLAG | ENUM_FLAG | SET_FLAG); + tmp->reset_fields(); + return tmp; +} + /**************************************************************************** Field_null, a field that always return NULL ****************************************************************************/ @@ -4432,7 +4451,7 @@ return field_charset->coll->strnncollsp(field_charset, (const uchar*) a_ptr, field_length, (const uchar*) b_ptr, - field_length); + field_length, 0); } if (field_charset->mbmaxlen != 1) { @@ -4461,20 +4480,22 @@ { THD *thd= table->in_use; CHARSET_INFO *cs=res.charset(); - ulong length= cs->cset->snprintf(cs,(char*) res.ptr(), - res.alloced_length(), "%s(%d)", - (field_length > 3 && - (table->db_options_in_use & - HA_OPTION_PACK_RECORD) ? - (has_charset() ? "varchar" : "varbinary") : + ulong length; + + length= cs->cset->snprintf(cs,(char*) res.ptr(), + res.alloced_length(), "%s(%d)", + ((type() == MYSQL_TYPE_VAR_STRING && + !thd->variables.new_mode) ? + (has_charset() ? "varchar" : "varbinary") : (has_charset() ? "char" : "binary")), - (int) field_length / charset()->mbmaxlen); + (int) field_length / charset()->mbmaxlen); res.length(length); if ((thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)) && has_charset() && (charset()->state & MY_CS_BINSORT)) res.append(" binary"); } + char *Field_string::pack(char *to, const char *from, uint max_length) { uint length= min(field_length,max_length); @@ -4508,10 +4529,27 @@ } -int Field_string::pack_cmp(const char *a, const char *b, uint length) +/* + Compare two packed keys + + SYNOPSIS + pack_cmp() + a New key + b Original key + length Key length + insert_or_update 1 if this is an insert or update + + RETURN + < 0 a < b + 0 a = b + > 0 a > b +*/ + +int Field_string::pack_cmp(const char *a, const char *b, uint length, + my_bool insert_or_update) { uint a_length, b_length; - if (field_length > 255) + if (length > 255) { a_length= uint2korr(a); b_length= uint2korr(b); @@ -4523,29 +4561,51 @@ a_length= (uint) (uchar) *a++; b_length= (uint) (uchar) *b++; } - return my_strnncoll(field_charset, - (const uchar*)a,a_length, - (const uchar*)b,b_length); + return field_charset->coll->strnncollsp(field_charset, + (const uchar*) a, a_length, + (const uchar*) b, b_length, + insert_or_update); } -int Field_string::pack_cmp(const char *b, uint length) +/* + Compare a packed key against row + + SYNOPSIS + pack_cmp() + key Original key + length Key length. (May be less than field length) + insert_or_update 1 if this is an insert or update + + RETURN + < 0 row < key + 0 row = key + > 0 row > key +*/ + +int Field_string::pack_cmp(const char *key, uint length, + my_bool insert_or_update) { - uint b_length; - if (field_length > 255) + uint row_length, key_length; + char *end; + if (length > 255) { - b_length= uint2korr(b); - b+= 2; + key_length= uint2korr(key); + key+= 2; } else - b_length= (uint) (uchar) *b++; - char *end= ptr + field_length; + key_length= (uint) (uchar) *key++; + + /* Only use 'length' of key, not field_length */ + end= ptr + length; while (end > ptr && end[-1] == ' ') end--; - uint a_length = (uint) (end - ptr); - return my_strnncoll(field_charset, - (const uchar*)ptr,a_length, - (const uchar*)b, b_length); + row_length= (uint) (end - ptr); + + return field_charset->coll->strnncollsp(field_charset, + (const uchar*) ptr, row_length, + (const uchar*) key, key_length, + insert_or_update); } @@ -4553,16 +4613,31 @@ { if (length > 255) return uint2korr(data_ptr)+2; - else - return (uint) ((uchar) *data_ptr)+1; + return (uint) ((uchar) *data_ptr)+1; } + uint Field_string::max_packed_col_length(uint max_length) { return (max_length > 255 ? 2 : 1)+max_length; } +Field *Field_string::new_field(MEM_ROOT *root, struct st_table *new_table) +{ + if (type() != MYSQL_TYPE_VAR_STRING || table == new_table) + return Field::new_field(root, new_table); + + /* + Old VARCHAR field which should be modified to a VARCHAR on copy + This is done to ensure that ALTER TABLE will convert old VARCHAR fields + to now VARCHAR fields. + */ + return new Field_varstring(field_length, maybe_null(), + field_name, new_table, + charset()); +} + /**************************************************************************** ** VARCHAR type (Not available for the end user yet) ****************************************************************************/ @@ -4571,7 +4646,7 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs) { int error= 0; - uint32 not_used; + uint32 not_used, copy_length; char buff[80]; String tmpstr(buff,sizeof(buff), &my_charset_bin); @@ -4585,15 +4660,21 @@ if (conv_errors) error= 1; } - if (length > field_length) - { - length=field_length; + /* + Make sure we don't break a multibyte sequence + as well as don't copy a malformed data. + */ + copy_length= field_charset->cset->well_formed_len(field_charset, + from,from+length, + field_length/ + field_charset->mbmaxlen); + memcpy(ptr + HA_KEY_BLOB_LENGTH, from, copy_length); + int2store(ptr, copy_length); + + if (copy_length < length) error= 1; - } if (error) set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1); - memcpy(ptr+HA_KEY_BLOB_LENGTH,from,length); - int2store(ptr, length); return error; } @@ -4640,17 +4721,49 @@ uint a_length=uint2korr(a_ptr); uint b_length=uint2korr(b_ptr); int diff; - diff= my_strnncoll(field_charset, - (const uchar*) a_ptr+HA_KEY_BLOB_LENGTH, - min(a_length,b_length), - (const uchar*) b_ptr+HA_KEY_BLOB_LENGTH, - min(a_length,b_length)); - return diff ? diff : (int) (a_length - b_length); + diff= field_charset->coll->strnncollsp(field_charset, + (const uchar*) a_ptr+ + HA_KEY_BLOB_LENGTH, + a_length, + (const uchar*) b_ptr+ + HA_KEY_BLOB_LENGTH, + b_length,0); + return diff; +} + + +int Field_varstring::key_cmp(const byte *key_ptr, uint max_key_length) +{ + char *blob1; + uint length= uint2korr(ptr); + CHARSET_INFO *cs= charset(); + uint char_length= max_key_length / cs->mbmaxlen; + + char_length= my_charpos(cs, ptr + HA_KEY_BLOB_LENGTH, + ptr + HA_KEY_BLOB_LENGTH + length, char_length); + set_if_smaller(length, char_length); + return cs->coll->strnncollsp(cs, + (const uchar*) ptr+2, length, + (const uchar*) key_ptr+HA_KEY_BLOB_LENGTH, + uint2korr(key_ptr), 0); } + +int Field_varstring::key_cmp(const byte *a,const byte *b) +{ + CHARSET_INFO *cs= charset(); + return cs->coll->strnncollsp(cs, + (const uchar*) a + HA_KEY_BLOB_LENGTH, + uint2korr(a), + (const uchar*) b + HA_KEY_BLOB_LENGTH, + uint2korr(b), + 0); +} + + void Field_varstring::sort_string(char *to,uint length) { - uint tot_length=uint2korr(ptr); + uint tot_length= uint2korr(ptr); tot_length= my_strnxfrm(field_charset, (uchar*) to, length, (uchar*) ptr+HA_KEY_BLOB_LENGTH, @@ -4670,9 +4783,11 @@ res.length(length); } + char *Field_varstring::pack(char *to, const char *from, uint max_length) { uint length=uint2korr(from); + set_if_smaller(max_length, field_length); if (length > max_length) length=max_length; *to++= (char) (length & 255); @@ -4687,12 +4802,14 @@ char *Field_varstring::pack_key(char *to, const char *from, uint max_length) { uint length=uint2korr(from); - uint char_length= (field_charset->mbmaxlen > 1) ? - max_length/field_charset->mbmaxlen : max_length; - from+=HA_KEY_BLOB_LENGTH; + uint char_length= ((field_charset->mbmaxlen > 1) ? + max_length/field_charset->mbmaxlen : max_length); + from+= HA_KEY_BLOB_LENGTH; if (length > char_length) + { char_length= my_charpos(field_charset, from, from+length, char_length); - set_if_smaller(length, char_length); + set_if_smaller(length, char_length); + } *to++= (char) (length & 255); if (max_length > 255) *to++= (char) (length >> 8); @@ -4705,16 +4822,16 @@ const char *Field_varstring::unpack(char *to, const char *from) { uint length; - if (field_length > 255) + if (field_length <= 255) { length= (uint) (uchar) (*to= *from++); to[1]=0; } else { - length=uint2korr(from); - to[0] = *from++; - to[1] = *from++; + length= uint2korr(from); + to[0]= *from++; + to[1]= *from++; } if (length) memcpy(to+HA_KEY_BLOB_LENGTH, from, length); @@ -4722,77 +4839,122 @@ } -int Field_varstring::pack_cmp(const char *a, const char *b, uint key_length) +int Field_varstring::pack_cmp(const char *a, const char *b, uint key_length, + my_bool insert_or_update) { uint a_length; uint b_length; if (key_length > 255) { - a_length=uint2korr(a); a+= 2; - b_length=uint2korr(b); b+= 2; + a_length=uint2korr(a); a+= HA_KEY_BLOB_LENGTH; + b_length=uint2korr(b); b+= HA_KEY_BLOB_LENGTH; } else { a_length= (uint) (uchar) *a++; b_length= (uint) (uchar) *b++; } - return my_strnncoll(field_charset, - (const uchar*) a, a_length, - (const uchar*) b, b_length); + return field_charset->coll->strnncollsp(field_charset, + (const uchar*) a, a_length, + (const uchar*) b, b_length, + insert_or_update); } -int Field_varstring::pack_cmp(const char *b, uint key_length) + +int Field_varstring::pack_cmp(const char *b, uint key_length, + my_bool insert_or_update) { char *a= ptr+HA_KEY_BLOB_LENGTH; uint a_length= uint2korr(ptr); uint b_length; + uint char_length= ((field_charset->mbmaxlen > 1) ? + key_length / field_charset->mbmaxlen : key_length); + if (key_length > 255) { - b_length=uint2korr(b); b+= 2; + b_length=uint2korr(b); b+= HA_KEY_BLOB_LENGTH; } else - { b_length= (uint) (uchar) *b++; + + if (a_length > char_length) + { + char_length= my_charpos(field_charset, a, a+a_length, char_length); + set_if_smaller(a_length, char_length); } - return my_strnncoll(field_charset, - (const uchar*) a, a_length, - (const uchar*) b, b_length); + + return field_charset->coll->strnncollsp(field_charset, + (const uchar*) a, + a_length, + (const uchar*) b, b_length, + insert_or_update); } + uint Field_varstring::packed_col_length(const char *data_ptr, uint length) { if (length > 255) return uint2korr(data_ptr)+HA_KEY_BLOB_LENGTH; - else - return (uint) ((uchar) *data_ptr)+1; + return (uint) ((uchar) *data_ptr)+1; } + uint Field_varstring::max_packed_col_length(uint max_length) { return (max_length > 255 ? 2 : 1)+max_length; } -void Field_varstring::get_key_image(char *buff, uint length, CHARSET_INFO *cs, - imagetype type) + +void Field_varstring::get_key_image(char *buff, uint length, imagetype type) { - uint f_length=uint2korr(ptr); - if (f_length > length) - f_length= length; - int2store(buff,length); - memcpy(buff+HA_KEY_BLOB_LENGTH, ptr+HA_KEY_BLOB_LENGTH, length); -#ifdef HAVE_purify + uint f_length= uint2korr(ptr); + uint char_length= length / field_charset->mbmaxlen; + char_length= my_charpos(field_charset, ptr, ptr + HA_KEY_BLOB_LENGTH, + char_length); + set_if_smaller(f_length, char_length); + int2store(buff,f_length); + memcpy(buff+HA_KEY_BLOB_LENGTH, ptr+HA_KEY_BLOB_LENGTH, f_length); if (f_length < length) + { + /* + Must clear this as we do a memcmp in opt_range.cc to detect + identical keys + */ bzero(buff+HA_KEY_BLOB_LENGTH+f_length, (length-f_length)); -#endif + } } -void Field_varstring::set_key_image(char *buff,uint length, CHARSET_INFO *cs) + +void Field_varstring::set_key_image(char *buff,uint length) { length=uint2korr(buff); // Real length is here - (void) Field_varstring::store(buff+HA_KEY_BLOB_LENGTH, length, cs); + (void) Field_varstring::store(buff+HA_KEY_BLOB_LENGTH, length, + field_charset); } +int Field_varstring::cmp_binary_offset(uint row_offset) +{ + return cmp_binary(ptr, ptr+row_offset); +} + + +int Field_varstring::cmp_binary(const char *a_ptr, const char *b_ptr, + uint32 max_length) +{ + char *a,*b; + uint diff; + uint32 a_length,b_length; + + a_length= uint2korr(a_ptr); + b_length= uint2korr(b_ptr); + set_if_smaller(a_length, max_length); + set_if_smaller(b_length, max_length); + if (a_length != b_length) + return 1; + return memcmp(a_ptr+2, b_ptr+2, a_length); +} + /**************************************************************************** ** blob type @@ -5030,10 +5192,10 @@ int Field_blob::cmp(const char *a,uint32 a_length, const char *b, uint32 b_length) { - return field_charset->coll->strnncoll(field_charset, - (const uchar*)a, a_length, - (const uchar*)b, b_length, - 0); + return field_charset->coll->strnncollsp(field_charset, + (const uchar*)a, a_length, + (const uchar*)b, b_length, + 0); } @@ -5080,8 +5242,7 @@ /* The following is used only when comparing a key */ -void Field_blob::get_key_image(char *buff,uint length, - CHARSET_INFO *cs, imagetype type) +void Field_blob::get_key_image(char *buff, uint length, imagetype type) { uint32 blob_length= get_length(ptr); char *blob; @@ -5116,8 +5277,9 @@ #endif /*HAVE_SPATIAL*/ get_ptr(&blob); - uint char_length= length / cs->mbmaxlen; - char_length= my_charpos(cs, blob, blob + blob_length, char_length); + uint char_length= length / field_charset->mbmaxlen; + char_length= my_charpos(field_charset, blob, blob + blob_length, + char_length); set_if_smaller(blob_length, char_length); if ((uint32) length > blob_length) @@ -5133,10 +5295,11 @@ memcpy(buff+HA_KEY_BLOB_LENGTH, blob, length); } -void Field_blob::set_key_image(char *buff,uint length, CHARSET_INFO *cs) + +void Field_blob::set_key_image(char *buff,uint length) { length= uint2korr(buff); - (void) Field_blob::store(buff+HA_KEY_BLOB_LENGTH, length, cs); + (void) Field_blob::store(buff+HA_KEY_BLOB_LENGTH, length, field_charset); } @@ -5149,7 +5312,7 @@ uint char_length= max_key_length / cs->mbmaxlen; char_length= my_charpos(cs, blob1, blob1+blob_length, char_length); set_if_smaller(blob_length, char_length); - return Field_blob::cmp(blob1,min(blob_length, max_key_length), + return Field_blob::cmp(blob1, blob_length, (char*) key_ptr+HA_KEY_BLOB_LENGTH, uint2korr(key_ptr)); } @@ -5241,7 +5404,8 @@ /* Keys for blobs are like keys on varchars */ -int Field_blob::pack_cmp(const char *a, const char *b, uint key_length) +int Field_blob::pack_cmp(const char *a, const char *b, uint key_length, + my_bool insert_or_update) { uint a_length; uint b_length; @@ -5255,13 +5419,15 @@ a_length= (uint) (uchar) *a++; b_length= (uint) (uchar) *b++; } - return my_strnncoll(field_charset, - (const uchar*) a, a_length, - (const uchar*) b, b_length); + return field_charset->coll->strnncollsp(field_charset, + (const uchar*) a, a_length, + (const uchar*) b, b_length, + insert_or_update); } -int Field_blob::pack_cmp(const char *b, uint key_length) +int Field_blob::pack_cmp(const char *b, uint key_length, + my_bool insert_or_update) { char *a; memcpy_fixed(&a,ptr+packlength,sizeof(char*)); @@ -5275,12 +5441,11 @@ b_length=uint2korr(b); b+=2; } else - { b_length= (uint) (uchar) *b++; - } - return my_strnncoll(field_charset, - (const uchar*) a, a_length, - (const uchar*) b, b_length); + return field_charset->coll->strnncollsp(field_charset, + (const uchar*) a, a_length, + (const uchar*) b, b_length, + insert_or_update); } /* Create a packed key that will be used for storage from a MySQL row */ @@ -5290,8 +5455,8 @@ char *save=ptr; ptr=(char*) from; uint32 length=get_length(); // Length of from string - uint char_length= (field_charset->mbmaxlen > 1) ? - max_length/field_charset->mbmaxlen : max_length; + uint char_length= ((field_charset->mbmaxlen > 1) ? + max_length/field_charset->mbmaxlen : max_length); if (length) get_ptr((char**) &from); if (length > char_length) @@ -5365,14 +5530,15 @@ return to+length; } + uint Field_blob::packed_col_length(const char *data_ptr, uint length) { if (length > 255) return uint2korr(data_ptr)+2; - else - return (uint) ((uchar) *data_ptr)+1; + return (uint) ((uchar) *data_ptr)+1; } + uint Field_blob::max_packed_col_length(uint max_length) { return (max_length > 255 ? 2 : 1)+max_length; @@ -5381,8 +5547,7 @@ #ifdef HAVE_SPATIAL -void Field_geom::get_key_image(char *buff, uint length, CHARSET_INFO *cs, - imagetype type) +void Field_geom::get_key_image(char *buff, uint length, imagetype type) { char *blob; const char *dummy; @@ -5411,11 +5576,6 @@ } -void Field_geom::set_key_image(char *buff, uint length, CHARSET_INFO *cs) -{ - Field_blob::set_key_image(buff, length, cs); -} - void Field_geom::sql_type(String &res) const { CHARSET_INFO *cs= &my_charset_latin1; @@ -5864,7 +6024,7 @@ /***************************************************************************** -** Handling of field and create_field + Handling of field and create_field *****************************************************************************/ void create_field::create_length_to_internal_length(void) @@ -5876,9 +6036,10 @@ case MYSQL_TYPE_BLOB: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_STRING: + case MYSQL_TYPE_VARCHAR: length*= charset->mbmaxlen; - pack_length= calc_pack_length(sql_type == FIELD_TYPE_VAR_STRING ? - FIELD_TYPE_STRING : sql_type, length); + key_length*= charset->mbmaxlen; + pack_length= calc_pack_length(sql_type, length); break; case MYSQL_TYPE_ENUM: case MYSQL_TYPE_SET: @@ -5890,6 +6051,22 @@ } } + +enum_field_types get_blob_type_from_length(ulong length) +{ + enum_field_types type; + if (length < 256) + type= FIELD_TYPE_TINY_BLOB; + else if (length < 65536) + type= FIELD_TYPE_BLOB; + else if (length < 256L*256L*256L) + type= FIELD_TYPE_MEDIUM_BLOB; + else + type= FIELD_TYPE_LONG_BLOB; + return type; +} + + /* Make a field from the .frm file info */ @@ -5897,9 +6074,10 @@ uint32 calc_pack_length(enum_field_types type,uint32 length) { switch (type) { + case MYSQL_TYPE_VAR_STRING: case FIELD_TYPE_STRING: - case FIELD_TYPE_DECIMAL: return (length); - case FIELD_TYPE_VAR_STRING: return (length+HA_KEY_BLOB_LENGTH); + case FIELD_TYPE_DECIMAL: return (length); + case MYSQL_TYPE_VARCHAR: return (length+HA_KEY_BLOB_LENGTH); case FIELD_TYPE_YEAR: case FIELD_TYPE_TINY : return 1; case FIELD_TYPE_SHORT : return 2; @@ -5972,12 +6150,16 @@ { if (!f_is_packed(pack_flag)) { - if (field_type == FIELD_TYPE_STRING || + if (field_type == MYSQL_TYPE_STRING || field_type == FIELD_TYPE_DECIMAL || // 3.23 or 4.0 string - field_type == FIELD_TYPE_VAR_STRING) + field_type == MYSQL_TYPE_VAR_STRING) return new Field_string(ptr,field_length,null_pos,null_bit, unireg_check, field_name, table, field_charset); + if (field_type == MYSQL_TYPE_VARCHAR) + return new Field_varstring(ptr,field_length,null_pos,null_bit, + unireg_check, field_name, table, + field_charset); return 0; // Error } @@ -6090,44 +6272,51 @@ flags= old_field->flags; unireg_check=old_field->unireg_check; pack_length=old_field->pack_length(); + key_length= old_field->key_length(); sql_type= old_field->real_type(); charset= old_field->charset(); // May be NULL ptr comment= old_field->comment; + decimals= old_field->decimals(); /* Fix if the original table had 4 byte pointer blobs */ if (flags & BLOB_FLAG) pack_length= (pack_length- old_field->table->blob_ptr_size + portable_sizeof_char_ptr); - switch (sql_type) - { - case FIELD_TYPE_BLOB: - switch (pack_length - portable_sizeof_char_ptr) - { - case 1: sql_type= FIELD_TYPE_TINY_BLOB; break; - case 2: sql_type= FIELD_TYPE_BLOB; break; - case 3: sql_type= FIELD_TYPE_MEDIUM_BLOB; break; - default: sql_type= FIELD_TYPE_LONG_BLOB; break; - } - length=(length+charset->mbmaxlen-1)/charset->mbmaxlen; // QQ: Probably not needed - break; - case MYSQL_TYPE_ENUM: - case MYSQL_TYPE_SET: - case FIELD_TYPE_STRING: - case FIELD_TYPE_VAR_STRING: - length=(length+charset->mbmaxlen-1)/charset->mbmaxlen; - break; - default: - break; - } - - decimals= old_field->decimals(); - if (sql_type == FIELD_TYPE_STRING) - { + switch (sql_type) { + case FIELD_TYPE_BLOB: + switch (pack_length - portable_sizeof_char_ptr) { + case 1: sql_type= FIELD_TYPE_TINY_BLOB; break; + case 2: sql_type= FIELD_TYPE_BLOB; break; + case 3: sql_type= FIELD_TYPE_MEDIUM_BLOB; break; + default: sql_type= FIELD_TYPE_LONG_BLOB; break; + } + length=(length+charset->mbmaxlen-1) / charset->mbmaxlen; + key_length/= charset->mbmaxlen; + break; + case FIELD_TYPE_STRING: /* Change CHAR -> VARCHAR if dynamic record length */ - sql_type=old_field->type(); - decimals=0; + if (old_field->type() == MYSQL_TYPE_VAR_STRING) + sql_type= MYSQL_TYPE_VARCHAR; + /* fall through */ + + case MYSQL_TYPE_ENUM: + case MYSQL_TYPE_SET: + case MYSQL_TYPE_VARCHAR: + case MYSQL_TYPE_VAR_STRING: + /* These are corrected in create_length_to_internal_length */ + length= (length+charset->mbmaxlen-1) / charset->mbmaxlen; + key_length/= charset->mbmaxlen; + break; +#ifdef HAVE_SPATIAL + case FIELD_TYPE_GEOMETRY: + geom_type= ((Field_geom*)old_field)->geom_type; + break; +#endif + default: + break; } + if (flags & (ENUM_FLAG | SET_FLAG)) interval= ((Field_enum*) old_field)->typelib; else @@ -6152,12 +6341,6 @@ def= new Item_string(pos, tmp.length(), charset); } } -#ifdef HAVE_SPATIAL - if (sql_type == FIELD_TYPE_GEOMETRY) - { - geom_type= ((Field_geom*)old_field)->geom_type; - } -#endif } --- 1.123/sql/field.h 2004-12-06 02:05:21 +02:00 +++ 1.124/sql/field.h 2004-12-06 18:04:38 +02:00 @@ -184,27 +184,7 @@ */ virtual bool can_be_compared_as_longlong() const { return FALSE; } virtual void free() {} - Field *new_field(MEM_ROOT *root, struct st_table *new_table) - { - Field *tmp= (Field*) memdup_root(root,(char*) this,size_of()); - if (tmp) - { - if (tmp->table->maybe_null) - tmp->flags&= ~NOT_NULL_FLAG; - tmp->table= new_table; - tmp->key_start.init(0); - tmp->part_of_key.init(0); - tmp->part_of_sortkey.init(0); - tmp->unireg_check=Field::NONE; - tmp->flags&= (NOT_NULL_FLAG | BLOB_FLAG | UNSIGNED_FLAG | - ZEROFILL_FLAG | BINARY_FLAG | ENUM_FLAG | SET_FLAG); -#ifdef PROBABLY_WRONG - tmp->table_name= new_table->table_name; -#endif - tmp->reset_fields(); - } - return tmp; - } + virtual Field *new_field(MEM_ROOT *root, struct st_table *new_table); inline void move_field(char *ptr_arg,uchar *null_ptr_arg,uchar null_bit_arg) { ptr=ptr_arg; null_ptr=null_ptr_arg; null_bit=null_bit_arg; @@ -220,11 +200,10 @@ { memcpy(buff,ptr,length); } inline void set_image(char *buff,uint length, CHARSET_INFO *cs) { memcpy(ptr,buff,length); } - virtual void get_key_image(char *buff,uint length, CHARSET_INFO *cs, - imagetype type) - { get_image(buff,length,cs); } - virtual void set_key_image(char *buff,uint length, CHARSET_INFO *cs) - { set_image(buff,length,cs); } + virtual void get_key_image(char *buff, uint length, imagetype type) + { get_image(buff,length, &my_charset_bin); } + virtual void set_key_image(char *buff,uint length) + { set_image(buff,length, &my_charset_bin); } inline longlong val_int_offset(uint row_offset) { ptr+=row_offset; @@ -263,9 +242,11 @@ virtual uint max_packed_col_length(uint max_length) { return max_length;} - virtual int pack_cmp(const char *a,const char *b, uint key_length_arg) + virtual int pack_cmp(const char *a,const char *b, uint key_length_arg, + my_bool insert_or_update) { return cmp(a,b); } - virtual int pack_cmp(const char *b, uint key_length_arg) + virtual int pack_cmp(const char *b, uint key_length_arg, + my_bool insert_or_update) { return cmp(ptr,b); } uint offset(); // Should be inline ... void copy_from_tmp(int offset); @@ -908,8 +889,8 @@ enum_field_types type() const { return ((table && table->db_create_options & HA_OPTION_PACK_RECORD && - field_length >= 4) ? - FIELD_TYPE_VAR_STRING : FIELD_TYPE_STRING); + field_length >= 4) && table->frm_version < FRM_VER_TRUE_VARCHAR ? + MYSQL_TYPE_VAR_STRING : MYSQL_TYPE_STRING); } enum ha_base_keytype key_type() const { return binary() ? HA_KEYTYPE_BINARY : HA_KEYTYPE_TEXT; } @@ -926,8 +907,9 @@ void sql_type(String &str) const; char *pack(char *to, const char *from, uint max_length=~(uint) 0); const char *unpack(char* to, const char *from); - int pack_cmp(const char *a,const char *b,uint key_length); - int pack_cmp(const char *b,uint key_length); + int pack_cmp(const char *a,const char *b,uint key_length, + my_bool insert_or_update); + int pack_cmp(const char *b,uint key_length,my_bool insert_or_update); uint packed_col_length(const char *to, uint length); uint max_packed_col_length(uint max_length); uint size_of() const { return sizeof(*this); } @@ -935,6 +917,7 @@ bool has_charset(void) const { return charset() == &my_charset_bin ? FALSE : TRUE; } field_cast_enum field_cast_type() { return FIELD_CAST_STRING; } + Field *new_field(MEM_ROOT *root, struct st_table *new_table); }; @@ -954,7 +937,7 @@ NONE, field_name_arg, table_arg, cs) {} - enum_field_types type() const { return FIELD_TYPE_VAR_STRING; } + enum_field_types type() const { return MYSQL_TYPE_VARCHAR; } enum ha_base_keytype key_type() const { return binary() ? HA_KEYTYPE_VARBINARY : HA_KEYTYPE_VARTEXT; } bool zero_pack() const { return 0; } @@ -969,18 +952,23 @@ String *val_str(String*,String *); int cmp(const char *,const char*); void sort_string(char *buff,uint length); - void get_key_image(char *buff,uint length, CHARSET_INFO *cs, imagetype type); - void set_key_image(char *buff,uint length, CHARSET_INFO *cs); + void get_key_image(char *buff,uint length, imagetype type); + void set_key_image(char *buff,uint length); void sql_type(String &str) const; char *pack(char *to, const char *from, uint max_length=~(uint) 0); char *pack_key(char *to, const char *from, uint max_length); const char *unpack(char* to, const char *from); - int pack_cmp(const char *a, const char *b, uint key_length); - int pack_cmp(const char *b, uint key_length); + int pack_cmp(const char *a, const char *b, uint key_length, + my_bool insert_or_update); + int pack_cmp(const char *b, uint key_length,my_bool insert_or_update); + int cmp_binary(const char *a,const char *b, uint32 max_length=~0L); + int cmp_binary_offset(uint row_offset); + int key_cmp(const byte *,const byte*); + int key_cmp(const byte *str, uint length); uint packed_col_length(const char *to, uint length); uint max_packed_col_length(uint max_length); uint size_of() const { return sizeof(*this); } - enum_field_types real_type() const { return FIELD_TYPE_VAR_STRING; } + enum_field_types real_type() const { return MYSQL_TYPE_VARCHAR; } bool has_charset(void) const { return charset() == &my_charset_bin ? FALSE : TRUE; } field_cast_enum field_cast_type() { return FIELD_CAST_VARSTRING; } @@ -1049,8 +1037,8 @@ store_length(length); memcpy_fixed(ptr+packlength,&data,sizeof(char*)); } - void get_key_image(char *buff,uint length, CHARSET_INFO *cs, imagetype type); - void set_key_image(char *buff,uint length, CHARSET_INFO *cs); + void get_key_image(char *buff,uint length, imagetype type); + void set_key_image(char *buff,uint length); void sql_type(String &str) const; inline bool copy() { char *tmp; @@ -1068,8 +1056,9 @@ char *pack_key(char *to, const char *from, uint max_length); char *pack_key_from_key_image(char* to, const char *from, uint max_length); const char *unpack_key(char* to, const char *from, uint max_length); - int pack_cmp(const char *a, const char *b, uint key_length); - int pack_cmp(const char *b, uint key_length); + int pack_cmp(const char *a, const char *b, uint key_length, + my_bool insert_or_update); + int pack_cmp(const char *b, uint key_length,my_bool insert_or_update); uint packed_col_length(const char *col_ptr, uint length); uint max_packed_col_length(uint max_length); void free() { value.free(); } @@ -1082,6 +1071,7 @@ uint32 max_length(); }; + #ifdef HAVE_SPATIAL class Field_geom :public Field_blob { public: @@ -1106,12 +1096,12 @@ int store(double nr) { return 1; } int store(longlong nr) { return 1; } - void get_key_image(char *buff,uint length, CHARSET_INFO *cs,imagetype type); - void set_key_image(char *buff,uint length, CHARSET_INFO *cs); + void get_key_image(char *buff,uint length,imagetype type); field_cast_enum field_cast_type() { return FIELD_CAST_GEOM; } }; #endif /*HAVE_SPATIAL*/ + class Field_enum :public Field_str { protected: uint packlength; @@ -1192,8 +1182,8 @@ LEX_STRING comment; // Comment for field Item *def; // Default value enum enum_field_types sql_type; - uint32 length; - uint decimals,flags,pack_length; + ulong length; + uint decimals, flags, pack_length, key_length; Field::utype unireg_check; TYPELIB *interval; // Which interval to use List interval_list; @@ -1258,6 +1248,7 @@ TYPELIB *interval, const char *field_name, struct st_table *table); uint pack_length_to_packflag(uint type); +enum_field_types get_blob_type_from_length(ulong length); uint32 calc_pack_length(enum_field_types type,uint32 length); int set_field_to_null(Field *field); int set_field_to_null_with_conversions(Field *field, bool no_conversions); --- 1.34/sql/field_conv.cc 2004-11-13 19:35:41 +02:00 +++ 1.35/sql/field_conv.cc 2004-12-06 18:04:38 +02:00 @@ -353,15 +353,16 @@ static void do_varstring(Copy_field *copy) { uint length=uint2korr(copy->from_ptr); - if (length > copy->to_length-2) + if (length > copy->to_length- HA_KEY_BLOB_LENGTH) { - length=copy->to_length-2; + length=copy->to_length-HA_KEY_BLOB_LENGTH; if (current_thd->count_cuted_fields) copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1); } int2store(copy->to_ptr,length); - memcpy(copy->to_ptr+2, copy->from_ptr,length); + memcpy(copy->to_ptr+HA_KEY_BLOB_LENGTH, copy->from_ptr + HA_KEY_BLOB_LENGTH, + length); } /*************************************************************************** @@ -504,7 +505,7 @@ } else if (to->charset() != from->charset()) return do_field_string; - else if (to->real_type() == FIELD_TYPE_VAR_STRING && to_length != + else if (to->real_type() == MYSQL_TYPE_VARCHAR && to_length != from_length) return do_varstring; else if (to_length < from_length) --- 1.49/sql/ha_heap.cc 2004-11-17 21:07:06 +02:00 +++ 1.50/sql/ha_heap.cc 2004-12-06 18:04:38 +02:00 @@ -481,16 +481,20 @@ { uint flag= key_part->key_type; Field *field= key_part->field; + if (pos->algorithm == HA_KEY_ALG_BTREE) seg->type= field->key_type(); else { - if ((seg->type = field->key_type()) != (int) HA_KEYTYPE_TEXT) + if ((seg->type = field->key_type()) != (int) HA_KEYTYPE_TEXT && + seg->type != HA_KEYTYPE_VARTEXT && + seg->type != HA_KEYTYPE_VARBINARY) seg->type= HA_KEYTYPE_BINARY; } seg->start= (uint) key_part->offset; seg->length= (uint) key_part->length; - seg->flag = 0; + seg->flag= key_part->key_part_flag; + seg->charset= field->charset(); if (field->null_ptr) { --- 1.137/sql/ha_myisam.cc 2004-11-15 20:26:53 +02:00 +++ 1.138/sql/ha_myisam.cc 2004-12-06 18:04:38 +02:00 @@ -1377,9 +1377,9 @@ keydef[i].keysegs=pos->key_parts; for (j=0 ; j < pos->key_parts ; j++) { - keydef[i].seg[j].flag=pos->key_part[j].key_part_flag; Field *field=pos->key_part[j].field; type=field->key_type(); + keydef[i].seg[j].flag=pos->key_part[j].key_part_flag; if (options & HA_OPTION_PACK_KEYS || (pos->flags & (HA_PACK_KEY | HA_BINARY_PACK_KEY | @@ -1394,8 +1394,8 @@ if (j == 0) keydef[i].flag|=HA_PACK_KEY; if (!(field->flags & ZEROFILL_FLAG) && - (field->type() == FIELD_TYPE_STRING || - field->type() == FIELD_TYPE_VAR_STRING || + (field->type() == MYSQL_TYPE_STRING || + field->type() == MYSQL_TYPE_VAR_STRING || ((int) (pos->key_part[j].length - field->decimals())) >= 4)) keydef[i].seg[j].flag|=HA_SPACE_PACK; @@ -1474,30 +1474,31 @@ { recinfo_pos->type= (int) FIELD_BLOB; } - else if (!(options & HA_OPTION_PACK_RECORD)) + else if (!(options & HA_OPTION_PACK_RECORD) || + found->type() == MYSQL_TYPE_VARCHAR) recinfo_pos->type= (int) FIELD_NORMAL; else if (found->zero_pack()) recinfo_pos->type= (int) FIELD_SKIP_ZERO; else recinfo_pos->type= (int) ((length <= 3 || - (found->flags & ZEROFILL_FLAG)) ? - FIELD_NORMAL : - found->type() == FIELD_TYPE_STRING || - found->type() == FIELD_TYPE_VAR_STRING ? - FIELD_SKIP_ENDSPACE : - FIELD_SKIP_PRESPACE); + (found->flags & ZEROFILL_FLAG)) ? + FIELD_NORMAL : + found->type() == MYSQL_TYPE_STRING || + found->type() == MYSQL_TYPE_VAR_STRING ? + FIELD_SKIP_ENDSPACE : + FIELD_SKIP_PRESPACE); if (found->null_ptr) { recinfo_pos->null_bit=found->null_bit; recinfo_pos->null_pos= (uint) (found->null_ptr- - (uchar*) table_arg->record[0]); + (uchar*) table_arg->record[0]); } else { recinfo_pos->null_bit=0; recinfo_pos->null_pos=0; } - (recinfo_pos++) ->length=(uint16) length; + (recinfo_pos++)->length= (uint16) length; recpos=minpos+length; DBUG_PRINT("loop",("length: %d type: %d", recinfo_pos[-1].length,recinfo_pos[-1].type)); --- 1.113/sql/handler.h 2004-12-06 02:05:21 +02:00 +++ 1.114/sql/handler.h 2004-12-06 18:04:38 +02:00 @@ -74,6 +74,7 @@ #define HA_HAS_CHECKSUM (1 << 24) /* Table data are stored in separate files (for lower_case_table_names) */ #define HA_FILE_BASED (1 << 26) +#define HA_NO_VARCHAR (1 << 27) /* bits in index_flags(index_number) for what you can do with index */ @@ -252,6 +253,7 @@ uint merge_insert_method; bool table_existed; /* 1 in create if table existed */ bool frm_only; /* 1 if no ha_create_table() */ + bool varchar; /* 1 if table has a VARCHAR */ } HA_CREATE_INFO; --- 1.97/sql/item.cc 2004-12-06 17:15:48 +02:00 +++ 1.98/sql/item.cc 2004-12-06 19:18:30 +02:00 @@ -188,7 +188,6 @@ { DBUG_ENTER("Item_ident::cleanup"); #ifdef CANT_BE_USED_AS_MEMORY_IS_FREED - DBUG_PRINT("enter", ("b:%s(%s), t:%s(%s), f:%s(%s)", db_name ? db_name : "(null)", orig_db_name ? orig_db_name : "(null)", table_name ? table_name : "(null)", @@ -2237,18 +2236,29 @@ void Item_empty_string::make_field(Send_field *tmp_field) { - init_make_field(tmp_field,FIELD_TYPE_VAR_STRING); + init_make_field(tmp_field, MYSQL_TYPE_VARCHAR); } enum_field_types Item::field_type() const { - return ((result_type() == STRING_RESULT) ? FIELD_TYPE_VAR_STRING : + return ((result_type() == STRING_RESULT) ? MYSQL_TYPE_VARCHAR : (result_type() == INT_RESULT) ? FIELD_TYPE_LONGLONG : FIELD_TYPE_DOUBLE); } +/* + Create a field based on field_type of argument + + For now, this is only used to create a field for + IFNULL(x,something) + + RETURN + 0 error + # Created field +*/ + Field *Item::tmp_table_field_from_field_type(TABLE *table) { /* @@ -2304,12 +2314,17 @@ case MYSQL_TYPE_ENUM: case MYSQL_TYPE_SET: case MYSQL_TYPE_VAR_STRING: - if (max_length > 255) - break; // If blob + if (max_length > MAX_FIELD_CHARLENGTH) + break; // convert to blob + return new Field_varstring(max_length, maybe_null, name, table, + collation.collation); + case MYSQL_TYPE_VARCHAR: + if (max_length > CONVERT_IF_BIGGER_TO_BLOB) + break; // convert to blob return new Field_varstring(max_length, maybe_null, name, table, collation.collation); case MYSQL_TYPE_STRING: - if (max_length > 255) // If blob + if (max_length > MAX_FIELD_CHARLENGTH) // If blob break; return new Field_string(max_length, maybe_null, name, table, collation.collation); @@ -2637,6 +2652,7 @@ case MYSQL_TYPE_GEOMETRY: case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: + case MYSQL_TYPE_VARCHAR: { String *res; if ((res=val_str(buffer))) --- 1.127/sql/item_cmpfunc.cc 2004-12-06 02:05:21 +02:00 +++ 1.128/sql/item_cmpfunc.cc 2004-12-06 18:04:38 +02:00 @@ -1726,7 +1726,7 @@ { return cs->coll->strnncollsp(cs, (uchar *) x->ptr(),x->length(), - (uchar *) y->ptr(),y->length()); + (uchar *) y->ptr(),y->length(), 0); } --- 1.110/sql/item_sum.cc 2004-11-20 19:31:44 +02:00 +++ 1.111/sql/item_sum.cc 2004-12-06 18:04:39 +02:00 @@ -1194,7 +1194,7 @@ uint len=item->key_length; return cs->coll->strnncollsp(cs, (const uchar*) key1, len, - (const uchar*) key2, len); + (const uchar*) key2, len, 0); } /* @@ -1344,10 +1344,9 @@ about other fields */ Field* field = table->field[0]; - switch(field->type()) - { - case FIELD_TYPE_STRING: - case FIELD_TYPE_VAR_STRING: + switch (field->type()) { + case MYSQL_TYPE_STRING: + case MYSQL_TYPE_VAR_STRING: if (field->binary()) { compare_key = (qsort_cmp2)simple_raw_key_cmp; --- 1.85/sql/protocol.cc 2004-11-24 18:22:22 +02:00 +++ 1.86/sql/protocol.cc 2004-12-06 18:04:39 +02:00 @@ -511,6 +511,11 @@ CHARSET_INFO *cs= system_charset_info; Send_field field; item->make_field(&field); + + /* Keep things compatible for old clients */ + if (field.type == MYSQL_TYPE_VARCHAR) + field.type= MYSQL_TYPE_VAR_STRING; + prot.prepare_for_resend(); if (thd->client_capabilities & CLIENT_PROTOCOL_41) --- 1.131/sql/opt_range.cc 2004-11-28 20:01:33 +02:00 +++ 1.132/sql/opt_range.cc 2004-12-06 18:04:39 +02:00 @@ -1749,8 +1749,10 @@ objects are not allowed so don't use ROR-intersection for table deletes. */ - if ((thd->lex->sql_command != SQLCOM_DELETE) )//&& -// (thd->lex->sql_command != SQLCOM_UPDATE)) + if ((thd->lex->sql_command != SQLCOM_DELETE)) +#ifdef NOT_USED + if ((thd->lex->sql_command != SQLCOM_UPDATE)) +#endif { /* Get best non-covering ROR-intersection plan and prepare data for @@ -3693,8 +3695,7 @@ DBUG_RETURN(0); if (maybe_null) *str= (char) field->is_real_null(); // Set to 1 if null - field->get_key_image(str+maybe_null, key_part->length, - field->charset(), key_part->image_type); + field->get_key_image(str+maybe_null, key_part->length, key_part->image_type); if (copies == 2) { /* @@ -8444,7 +8445,7 @@ key++; // Skip null byte store_length--; } - field->set_key_image((char*) key, key_part->length, field->charset()); + field->set_key_image((char*) key, key_part->length); field->val_str(&tmp); fwrite(tmp.ptr(),sizeof(char),tmp.length(),DBUG_FILE); if (key+store_length < key_end) --- 1.39/sql/opt_sum.cc 2004-11-21 19:35:29 +02:00 +++ 1.40/sql/opt_sum.cc 2004-12-06 18:04:39 +02:00 @@ -562,8 +562,7 @@ store_val_in_field(part->field, args[between && max_fl ? 2 : 1]); if (part->null_bit) *key_ptr++= (byte) test(part->field->is_null()); - part->field->get_key_image((char*) key_ptr, part->length, - part->field->charset(), Field::itRAW); + part->field->get_key_image((char*) key_ptr, part->length, Field::itRAW); } if (is_field_part) { --- 1.114/sql/sql_acl.cc 2004-12-06 17:15:48 +02:00 +++ 1.115/sql/sql_acl.cc 2004-12-06 19:18:30 +02:00 @@ -1053,9 +1053,8 @@ ulong acl_get(const char *host, const char *ip, const char *user, const char *db, my_bool db_is_pattern) { - ulong host_access,db_access; + ulong host_access= ~0, db_access= 0; uint i,key_length; - db_access=0; host_access= ~0; char key[ACL_KEY_LENGTH],*tmp_db,*end; acl_entry *entry; DBUG_ENTER("acl_get"); @@ -1438,6 +1437,7 @@ TABLE_LIST tables; TABLE *table; bool error=1; + char user_key[MAX_KEY_LENGTH]; DBUG_ENTER("update_user_table"); DBUG_PRINT("enter",("user: %s host: %s",user,host)); @@ -1467,11 +1467,12 @@ DBUG_RETURN(1); /* purecov: deadcode */ table->field[0]->store(host,(uint) strlen(host), system_charset_info); table->field[1]->store(user,(uint) strlen(user), system_charset_info); + key_copy(user_key, table->record[0], table->key_info, + table->key_info->key_length); table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); - if (table->file->index_read_idx(table->record[0],0, - (byte*) table->field[0]->ptr, - table->key_info[0].key_length, + if (table->file->index_read_idx(table->record[0], 0, + user_key, table->key_info->key_length, HA_READ_KEY_EXACT)) { my_message(ER_PASSWORD_NO_MATCH, ER(ER_PASSWORD_NO_MATCH), @@ -1531,8 +1532,10 @@ const char *password= ""; uint password_len= 0; char what= (revoke_grant) ? 'N' : 'Y'; - DBUG_ENTER("replace_user_table"); + byte user_key[MAX_KEY_LENGTH]; LEX *lex= thd->lex; + DBUG_ENTER("replace_user_table"); + safe_mutex_assert_owner(&acl_cache->lock); if (combo.password.str && combo.password.str[0]) @@ -1549,11 +1552,13 @@ table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); table->field[1]->store(combo.user.str,combo.user.length, system_charset_info); + key_copy(user_key, table->record[0], table->key_info, + table->key_info->key_length); + table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (table->file->index_read_idx(table->record[0], 0, - (byte*) table->field[0]->ptr, - table->key_info[0].key_length, - HA_READ_KEY_EXACT)) + user_key, table->key_info->key_length, + HA_READ_KEY_EXACT)) { /* what == 'N' means revoke */ if (what == 'N') @@ -1742,6 +1747,7 @@ bool old_row_exists=0; int error; char what= (revoke_grant) ? 'N' : 'Y'; + byte user_key[MAX_KEY_LENGTH]; DBUG_ENTER("replace_db_table"); if (!initialized) @@ -1760,11 +1766,13 @@ table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); table->field[1]->store(db,(uint) strlen(db), system_charset_info); table->field[2]->store(combo.user.str,combo.user.length, system_charset_info); + key_copy(user_key, table->record[0], table->key_info, + table->key_info->key_length); + table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (table->file->index_read_idx(table->record[0],0, - (byte*) table->field[0]->ptr, - table->key_info[0].key_length, - HA_READ_KEY_EXACT)) + user_key, table->key_info->key_length, + HA_READ_KEY_EXACT)) { if (what == 'N') { // no row, no revoke @@ -1935,22 +1943,25 @@ 0,0,0, (hash_get_key) get_key_column,0,0); if (cols) { - int key_len; + uint key_prefix_len; + KEY_PART_INFO *key_part= col_privs->key_info->key_part; col_privs->field[0]->store(orig_host,(uint) strlen(orig_host), system_charset_info); col_privs->field[1]->store(db,(uint) strlen(db), system_charset_info); col_privs->field[2]->store(user,(uint) strlen(user), system_charset_info); col_privs->field[3]->store(tname,(uint) strlen(tname), system_charset_info); - key_len=(col_privs->field[0]->pack_length()+ - col_privs->field[1]->pack_length()+ - col_privs->field[2]->pack_length()+ - col_privs->field[3]->pack_length()); - key_copy(key,col_privs->record[0],col_privs->key_info,key_len); + + key_prefix_len= (key_part[0].store_length + + key_part[1].store_length + + key_part[2].store_length + + key_part[3].store_length); + key_copy(key, col_privs->record[0], col_privs->key_info, key_prefix_len); col_privs->field[4]->store("",0, &my_charset_latin1); + col_privs->file->ha_index_init(0); if (col_privs->file->index_read(col_privs->record[0], - (byte*) col_privs->field[0]->ptr, - key_len, HA_READ_KEY_EXACT)) + (byte*) key, + key_prefix_len, HA_READ_KEY_EXACT)) { cols = 0; /* purecov: deadcode */ col_privs->file->ha_index_end(); @@ -1972,7 +1983,7 @@ } my_hash_insert(&hash_columns, (byte *) mem_check); } while (!col_privs->file->index_next(col_privs->record[0]) && - !key_cmp_if_same(col_privs,key,0,key_len)); + !key_cmp_if_same(col_privs,key,0,key_prefix_len)); col_privs->file->ha_index_end(); } } @@ -2053,19 +2064,22 @@ ulong rights, bool revoke_grant) { int error=0,result=0; - uint key_length; byte key[MAX_KEY_LENGTH]; + uint key_prefix_length; + KEY_PART_INFO *key_part= table->key_info->key_part; DBUG_ENTER("replace_column_table"); table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); table->field[1]->store(db,(uint) strlen(db), system_charset_info); table->field[2]->store(combo.user.str,combo.user.length, system_charset_info); table->field[3]->store(table_name,(uint) strlen(table_name), system_charset_info); - key_length=(table->field[0]->pack_length()+ table->field[1]->pack_length()+ - table->field[2]->pack_length()+ table->field[3]->pack_length()); - key_copy(key,table->record[0],table->key_info,key_length); - rights &= COL_ACLS; // Only ACL for columns + /* Get length of 3 first key parts */ + key_prefix_length= (key_part[0].store_length + key_part[1].store_length + + key_part[2].store_length + key_part[3].store_length); + key_copy(key, table->record[0], table->key_info, key_prefix_length); + + rights&= COL_ACLS; // Only ACL for columns /* first fix privileges for all columns in column list */ @@ -2076,14 +2090,20 @@ { ulong privileges = xx->rights; bool old_row_exists=0; - key_restore(table->record[0],key,table->key_info,key_length); + byte user_key[MAX_KEY_LENGTH]; + + key_restore(table->record[0],key,table->key_info, + key_prefix_length); table->field[4]->store(xx->column.ptr(),xx->column.length(), system_charset_info); + /* Get key for the first 4 columns */ + key_copy(user_key, table->record[0], table->key_info, + table->key_info->key_length); table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); - if (table->file->index_read(table->record[0],(byte*) table->field[0]->ptr, - table->key_info[0].key_length, - HA_READ_KEY_EXACT)) + if (table->file->index_read(table->record[0], user_key, + table->key_info->key_length, + HA_READ_KEY_EXACT)) { if (revoke_grant) { @@ -2095,7 +2115,8 @@ } old_row_exists = 0; restore_record(table,default_values); // Get empty record - key_restore(table->record[0],key,table->key_info,key_length); + key_restore(table->record[0],key,table->key_info, + key_prefix_length); table->field[4]->store(xx->column.ptr(),xx->column.length(), system_charset_info); } @@ -2152,10 +2173,14 @@ if (revoke_grant) { + byte user_key[MAX_KEY_LENGTH]; + key_copy(user_key, table->record[0], table->key_info, + key_prefix_length); + table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); - if (table->file->index_read(table->record[0], (byte*) table->field[0]->ptr, - key_length, - HA_READ_KEY_EXACT)) + if (table->file->index_read(table->record[0], user_key, + key_prefix_length, + HA_READ_KEY_EXACT)) goto end; /* Scan through all rows with the same host,db,user and table */ @@ -2169,7 +2194,8 @@ { GRANT_COLUMN *grant_column = NULL; char colum_name_buf[HOSTNAME_LENGTH+1]; - String column_name(colum_name_buf,sizeof(colum_name_buf),system_charset_info); + String column_name(colum_name_buf,sizeof(colum_name_buf), + system_charset_info); privileges&= ~rights; table->field[6]->store((longlong) @@ -2205,7 +2231,7 @@ } } } while (!table->file->index_next(table->record[0]) && - !key_cmp_if_same(table,key,0,key_length)); + !key_cmp_if_same(table, key, 0, key_prefix_length)); } end: @@ -2224,6 +2250,7 @@ int old_row_exists = 1; int error=0; ulong store_table_rights, store_col_rights; + byte user_key[MAX_KEY_LENGTH]; DBUG_ENTER("replace_table_table"); strxmov(grantor, thd->user, "@", thd->host_or_ip, NullS); @@ -2245,10 +2272,12 @@ table->field[2]->store(combo.user.str,combo.user.length, system_charset_info); table->field[3]->store(table_name,(uint) strlen(table_name), system_charset_info); store_record(table,record[1]); // store at pos 1 + key_copy(user_key, table->record[0], table->key_info, + table->key_info->key_length); + table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); - if (table->file->index_read_idx(table->record[0],0, - (byte*) table->field[0]->ptr, - table->key_info[0].key_length, + if (table->file->index_read_idx(table->record[0], 0, + user_key, table->key_info->key_length, HA_READ_KEY_EXACT)) { /* @@ -3702,6 +3731,8 @@ Field *user_field, LEX_USER *user_to) { int error; + TABLE *table; + byte user_key[MAX_KEY_LENGTH]; DBUG_ENTER("modify_grant_table"); if (user_to) @@ -3769,6 +3800,7 @@ char *user_str= user_from->user.str; const char *host; const char *user; + uint key_prefix_length; DBUG_ENTER("handle_grant_table"); if (! table_no) // mysql.user table @@ -3786,8 +3818,13 @@ table->real_name, user_str, host_str)); host_field->store(host_str, user_from->host.length, system_charset_info); user_field->store(user_str, user_from->user.length, system_charset_info); + + key_prefix_length= (table->key_info->key_part[0].store_length + + table->key_info->key_part[1].store_length); + key_copy(user_key, table->record[0], table->key_info, key_prefix_length); + if ((error= table->file->index_read_idx(table->record[0], 0, - (byte*) host_field->ptr, 0, + user_key, key_prefix_length, HA_READ_KEY_EXACT))) { if (error != HA_ERR_KEY_NOT_FOUND) @@ -4058,7 +4095,8 @@ else { /* Handle user array. */ - if ((handle_grant_struct(0, drop, user_from, user_to) && ! result) || found) + if ((handle_grant_struct(0, drop, user_from, user_to) && ! result) || + found) { result= 1; /* At least one record/element found. */ /* If search is requested, we do not need to search further. */ @@ -4120,6 +4158,7 @@ DBUG_RETURN(result); } + static void append_user(String *str, LEX_USER *user) { if (str->length()) @@ -4131,6 +4170,7 @@ str->append('\''); } + /* Create a list of users. @@ -4298,6 +4338,7 @@ DBUG_RETURN(result); } + /* Revoke all privileges from a list of users. @@ -4332,9 +4373,8 @@ { if (!check_acl_user(lex_user, &counter)) { - sql_print_error("REVOKE ALL PRIVILEGES, GRANT: User '%s'@'%s' not exists", - lex_user->user.str, - lex_user->host.str); + sql_print_error("REVOKE ALL PRIVILEGES, GRANT: User '%s'@'%s' does not " + "exists", lex_user->user.str, lex_user->host.str); result= -1; continue; } --- 1.195/sql/sql_base.cc 2004-12-06 02:05:23 +02:00 +++ 1.196/sql/sql_base.cc 2004-12-06 18:04:39 +02:00 @@ -1063,31 +1063,6 @@ for (uint i=0 ; i < table->fields ; i++) table->field[i]->table_name=table->table_name; } -#if MYSQL_VERSION_ID < 40100 - /* - If per-connection "new" variable (represented by variables.new_mode) - is set then we should pretend that the length of TIMESTAMP field is 19. - The cheapest (from perfomance viewpoint) way to achieve that is to set - field_length of all Field_timestamp objects in a table after opening - it (to 19 if new_mode is true or to original field length otherwise). - We save value of new_mode variable in TABLE::timestamp_mode to - not perform this setup if new_mode value is the same between sequential - table opens. - */ - my_bool new_mode= thd->variables.new_mode; - if (table->timestamp_mode != new_mode) - { - for (uint i=0 ; i < table->fields ; i++) - { - Field *field= table->field[i]; - - if (field->type() == FIELD_TYPE_TIMESTAMP) - field->field_length= new_mode ? 19 : - ((Field_timestamp *)(field))->orig_field_length; - } - table->timestamp_mode= new_mode; - } -#endif /* These variables are also set in reopen_table() */ table->tablenr=thd->current_tablenr++; table->used_fields=0; --- 1.373/sql/sql_parse.cc 2004-12-06 17:15:48 +02:00 +++ 1.374/sql/sql_parse.cc 2004-12-06 19:18:30 +02:00 @@ -118,15 +118,20 @@ static bool end_active_trans(THD *thd) { int error=0; + DBUG_ENTER("end_active_trans"); if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN | OPTION_TABLE_LOCK)) { + DBUG_PRINT("info",("options: 0x%lx", (ulong) thd->options)); thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE); + /* Safety if one did "drop table" on locked tables */ + if (!thd->locked_tables) + thd->options&= ~OPTION_TABLE_LOCK; thd->server_status&= ~SERVER_STATUS_IN_TRANS; if (ha_commit(thd)) error=1; } - return error; + DBUG_RETURN(error); } @@ -4736,7 +4741,7 @@ LEX *lex= thd->lex; uint allowed_type_modifier=0; uint sign_len; - char warn_buff[MYSQL_ERRMSG_SIZE]; + ulong max_field_charlength= MAX_FIELD_CHARLENGTH; DBUG_ENTER("add_field_to_list"); if (strlen(field_name) > NAME_LEN) @@ -4812,7 +4817,7 @@ new_field->length=0; new_field->change=change; new_field->interval=0; - new_field->pack_length=0; + new_field->pack_length= new_field->key_length= 0; new_field->charset=cs; new_field->geom_type= (Field::geometry_type) uint_geom_type; @@ -4884,36 +4889,22 @@ new_field->length++; } break; - case FIELD_TYPE_STRING: - case FIELD_TYPE_VAR_STRING: - if (new_field->length <= MAX_FIELD_CHARLENGTH || default_value) - break; - /* Convert long CHAR() and VARCHAR columns to TEXT or BLOB */ - new_field->sql_type= FIELD_TYPE_BLOB; - sprintf(warn_buff, ER(ER_AUTO_CONVERT), field_name, "CHAR", - (cs == &my_charset_bin) ? "BLOB" : "TEXT"); - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_AUTO_CONVERT, - warn_buff); - /* fall through */ + case MYSQL_TYPE_VARCHAR: + /* + We can't use pack_length as this includes the field length + Long VARCHAR's are automaticly converted to blobs in mysql_prepare_table + if they don't have a default value + */ + new_field->key_length= new_field->length; + max_field_charlength= MAX_FIELD_VARCHARLENGTH; + break; + case MYSQL_TYPE_STRING: + break; case FIELD_TYPE_BLOB: case FIELD_TYPE_TINY_BLOB: case FIELD_TYPE_LONG_BLOB: case FIELD_TYPE_MEDIUM_BLOB: case FIELD_TYPE_GEOMETRY: - if (new_field->length) - { - /* The user has given a length to the blob column */ - if (new_field->length < 256) - type= FIELD_TYPE_TINY_BLOB; - if (new_field->length < 65536) - type= FIELD_TYPE_BLOB; - else if (new_field->length < 256L*256L*256L) - type= FIELD_TYPE_MEDIUM_BLOB; - else - type= FIELD_TYPE_LONG_BLOB; - new_field->length= 0; - } - new_field->sql_type= type; if (default_value) // Allow empty as default value { String str,*res; @@ -5055,8 +5046,8 @@ when we know the character set of the column */ new_field->length= 1; + break; } - break; case FIELD_TYPE_ENUM: { // Should be safe @@ -5067,18 +5058,23 @@ while ((tmp= it++)) new_field->interval_list.push_back(tmp); new_field->length= 1; // See comment for FIELD_TYPE_SET above. - } + break; + } + case MYSQL_TYPE_VAR_STRING: + DBUG_ASSERT(0); // Impossible break; } - if ((new_field->length > MAX_FIELD_CHARLENGTH && type != FIELD_TYPE_SET && - type != FIELD_TYPE_ENUM) || - (!new_field->length && !(new_field->flags & BLOB_FLAG) && - type != FIELD_TYPE_STRING && - type != FIELD_TYPE_VAR_STRING && type != FIELD_TYPE_GEOMETRY)) + if (!(new_field->flags & BLOB_FLAG) && + ((new_field->length > max_field_charlength && type != FIELD_TYPE_SET && + type != FIELD_TYPE_ENUM && + (type != MYSQL_TYPE_VARCHAR || default_value)) || + (!new_field->length && + type != MYSQL_TYPE_STRING && + type != MYSQL_TYPE_VARCHAR && type != FIELD_TYPE_GEOMETRY))) { my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), - field_name, MAX_FIELD_CHARLENGTH);/* purecov: inspected */ + field_name, max_field_charlength); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } type_modifier&= AUTO_INCREMENT_FLAG; @@ -5088,11 +5084,10 @@ DBUG_RETURN(1); } if (!new_field->pack_length) - new_field->pack_length=calc_pack_length(new_field->sql_type == - FIELD_TYPE_VAR_STRING ? - FIELD_TYPE_STRING : - new_field->sql_type, - new_field->length); + new_field->pack_length= calc_pack_length(new_field->sql_type, + new_field->length); + if (!new_field->key_length) + new_field->key_length= new_field->pack_length; lex->create_list.push_back(new_field); lex->last_field=new_field; DBUG_RETURN(0); @@ -5136,7 +5131,6 @@ { #ifdef USE_MB int l; -/* if ((l = ismbchar(name, name+MBMAXLEN))) { Wei He: I think it's wrong */ if (use_mb(system_charset_info) && (l = my_ismbchar(system_charset_info, name, strend))) { --- 1.260/sql/sql_select.cc 2004-12-06 17:15:49 +02:00 +++ 1.261/sql/sql_select.cc 2004-12-06 18:04:39 +02:00 @@ -7539,7 +7539,8 @@ Field *new_field; if (convert_blob_length && org_field->flags & BLOB_FLAG) - new_field= new Field_varstring(convert_blob_length, org_field->maybe_null(), + new_field= new Field_varstring(convert_blob_length, + org_field->maybe_null(), org_field->field_name, table, org_field->charset()); else @@ -7552,7 +7553,8 @@ new_field->field_name= item->name; if (org_field->maybe_null()) new_field->flags&= ~NOT_NULL_FLAG; // Because of outer join - if (org_field->type() == FIELD_TYPE_VAR_STRING) + if (org_field->type() == MYSQL_TYPE_VAR_STRING || + org_field->type() == MYSQL_TYPE_VARCHAR) table->db_create_options|= HA_OPTION_PACK_RECORD; } return new_field; @@ -7759,6 +7761,11 @@ for send_fields */ +#define STRING_TOTAL_LENGTH_TO_PACK_ROWS 128 +#define AVG_STRING_LENGTH_TO_PACK_ROWS 64 +#define RATIO_TO_PACK_ROWS 2 +#define MIN_STRING_LENGTH_TO_PACK_ROWS 10 + TABLE * create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, ORDER *group, bool distinct, bool save_sum_fields, @@ -7766,10 +7773,13 @@ char *table_alias) { TABLE *table; - uint i,field_count,reclength,null_count,null_pack_length, - hidden_null_count, hidden_null_pack_length, hidden_field_count, - blob_count,group_null_items; - bool using_unique_constraint=0; + uint i,field_count,null_count,null_pack_length; + uint hidden_null_count, hidden_null_pack_length, hidden_field_count; + uint blob_count,group_null_items, string_count; + uint temp_pool_slot=MY_BIT_NONE; + ulong reclength, string_total_length; + bool using_unique_constraint= 0; + bool use_packed_rows= 0; bool not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS); char *tmpname,path[FN_REFLEN], filename[FN_REFLEN]; byte *pos,*group_buff; @@ -7780,8 +7790,6 @@ KEY_PART_INFO *key_part_info; Item **copy_func; MI_COLUMNDEF *recinfo; - uint temp_pool_slot=MY_BIT_NONE; - DBUG_ENTER("create_tmp_table"); DBUG_PRINT("enter",("distinct: %d save_sum_fields: %d rows_limit: %lu group: %d", (int) distinct, (int) save_sum_fields, @@ -7876,7 +7884,8 @@ /* Calculate which type of fields we will store in the temporary table */ - reclength=blob_count=null_count=hidden_null_count=group_null_items=0; + reclength= string_total_length= 0; + blob_count= string_count= null_count= hidden_null_count= group_null_items= 0; param->using_indirect_summary_function=0; List_iterator_fast li(fields); @@ -7923,6 +7932,12 @@ *blob_field++= new_field; blob_count++; } + if (new_field->real_type() == MYSQL_TYPE_STRING || + new_field->real_type() == MYSQL_TYPE_VARCHAR) + { + string_count++; + string_total_length+= new_field->pack_length(); + } thd->change_item_tree(argp, new Item_field(new_field)); if (!(new_field->flags & NOT_NULL_FLAG)) { @@ -8016,6 +8031,12 @@ reclength+=null_pack_length; if (!reclength) reclength=1; // Dummy select + /* Use packed rows if there is blobs or a lot of space to gain */ + if (blob_count || + string_total_length >= STRING_TOTAL_LENGTH_TO_PACK_ROWS && + (reclength / string_total_length <= RATIO_TO_PACK_ROWS || + string_total_length / string_count >= AVG_STRING_LENGTH_TO_PACK_ROWS)) + use_packed_rows= 1; table->fields=field_count; table->reclength=reclength; @@ -8090,10 +8111,9 @@ recinfo->length=length; if (field->flags & BLOB_FLAG) recinfo->type= (int) FIELD_BLOB; - else if (!field->zero_pack() && - (field->type() == FIELD_TYPE_STRING || - field->type() == FIELD_TYPE_VAR_STRING) && - length >= 10 && blob_count) + else if (use_packed_rows && + field->real_type() == MYSQL_TYPE_STRING && + length >= MIN_STRING_LENGTH_TO_PACK_ROWS) recinfo->type=FIELD_SKIP_ENDSPACE; else recinfo->type=FIELD_NORMAL; @@ -8168,6 +8188,8 @@ } else group->field->move_field((char*) group_buff); + /* In GROUP BY 'a' and 'a ' are equal for VARCHAR fields */ + key_part_info->key_part_flag|= HA_END_SPACE_ARE_EQUAL; group_buff+= key_part_info->length; } keyinfo->key_length+= key_part_info->length; @@ -8338,12 +8360,10 @@ } else { - seg->type= - ((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ? - HA_KEYTYPE_BINARY : HA_KEYTYPE_TEXT); - if (!(field->flags & ZEROFILL_FLAG) && - (field->type() == FIELD_TYPE_STRING || - field->type() == FIELD_TYPE_VAR_STRING) && + seg->type= ((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ? + HA_KEYTYPE_BINARY : HA_KEYTYPE_TEXT); + /* Tell handler if it can do suffic space compression */ + if (field->real_type() == MYSQL_TYPE_STRING && keyinfo->key_part[i].length > 4) seg->flag|=HA_SPACE_PACK; } @@ -9846,6 +9866,7 @@ DBUG_RETURN(0); } + /* Like end_update, but this is done with unique constraints instead of keys */ static int @@ -9993,11 +10014,11 @@ /* We can remove binary fields and numerical fields except float, as float comparison isn't 100 % secure - We have to keep binary strings to be able to check for end spaces + We have to keep normal strings to be able to check for end spaces */ if (field->binary() && - field->real_type() != FIELD_TYPE_STRING && - field->real_type() != FIELD_TYPE_VAR_STRING && + field->real_type() != MYSQL_TYPE_STRING && + field->real_type() != MYSQL_TYPE_VARCHAR && (field->type() != FIELD_TYPE_FLOAT || field->decimals() == 0)) { return !store_val_in_field(field,right_item); --- 1.199/sql/sql_table.cc 2004-12-06 17:15:49 +02:00 +++ 1.200/sql/sql_table.cc 2004-12-06 19:18:30 +02:00 @@ -433,6 +433,9 @@ DESCRIPTION Prepares the table and key structures for table creation. + NOTES + sets create_info->varchar if the table has a varchar or blob. + RETURN VALUES 0 ok -1 error @@ -447,20 +450,24 @@ const char *key_name; create_field *sql_field,*dup_field; uint field,null_fields,blob_columns; + uint max_key_length= file->max_key_length(); ulong pos; KEY *key_info; KEY_PART_INFO *key_part_info; int timestamps= 0, timestamps_with_niladic= 0; int field_no,dup_no; int select_field_pos,auto_increment=0; + List_iterator it(fields),it2(fields); DBUG_ENTER("mysql_prepare_table"); - List_iterator it(fields),it2(fields); select_field_pos=fields.elements - select_field_count; null_fields=blob_columns=0; + create_info->varchar= 0; for (field_no=0; (sql_field=it++) ; field_no++) { + CHARSET_INFO *save_cs; + if (!sql_field->charset) sql_field->charset= create_info->default_table_charset; /* @@ -472,13 +479,13 @@ if (create_info->table_charset && sql_field->charset != &my_charset_bin) sql_field->charset= create_info->table_charset; - CHARSET_INFO *savecs= sql_field->charset; + save_cs= sql_field->charset; if ((sql_field->flags & BINCMP_FLAG) && !(sql_field->charset= get_charset_by_csname(sql_field->charset->csname, MY_CS_BINSORT,MYF(0)))) { char tmp[64]; - strmake(strmake(tmp, savecs->csname, sizeof(tmp)-4), "_bin", 4); + strmake(strmake(tmp, save_cs->csname, sizeof(tmp)-4), "_bin", 4); my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp); DBUG_RETURN(-1); } @@ -569,10 +576,41 @@ } sql_field->create_length_to_internal_length(); + if (sql_field->length > MAX_FIELD_VARCHARLENGTH && + !(sql_field->flags & BLOB_FLAG)) + { + /* Convert long VARCHAR columns to TEXT or BLOB */ + char warn_buff[MYSQL_ERRMSG_SIZE]; + + if (sql_field->def) + { + my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), sql_field->field_name, + MAX_FIELD_VARCHARLENGTH / sql_field->charset->mbmaxlen); + DBUG_RETURN(-1); + } + sql_field->sql_type= FIELD_TYPE_BLOB; + sql_field->flags|= BLOB_FLAG; + sprintf(warn_buff, ER(ER_AUTO_CONVERT), sql_field->field_name, + "VARCHAR", + (sql_field->charset == &my_charset_bin) ? "BLOB" : "TEXT"); + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_AUTO_CONVERT, + warn_buff); + } + + if ((sql_field->flags & BLOB_FLAG) && sql_field->length) + { + if (sql_field->sql_type == FIELD_TYPE_BLOB) + { + /* The user has given a length to the blob column */ + sql_field->sql_type= get_blob_type_from_length(sql_field->length); + sql_field->pack_length= calc_pack_length(sql_field->sql_type, 0); + } + sql_field->length= 0; // Probably from an item + } - /* Don't pack keys in old tables if the user has requested this */ + /* Don't pack rows in old tables if the user has requested this */ if ((sql_field->flags & BLOB_FLAG) || - sql_field->sql_type == FIELD_TYPE_VAR_STRING && + sql_field->sql_type == MYSQL_TYPE_VARCHAR && create_info->row_type != ROW_TYPE_FIXED) { db_options|=HA_OPTION_PACK_RECORD; @@ -646,6 +684,7 @@ sql_field->length=8; // Unireg field length sql_field->unireg_check=Field::BLOB_FIELD; blob_columns++; + create_info->varchar= 1; break; case FIELD_TYPE_GEOMETRY: #ifdef HAVE_SPATIAL @@ -662,17 +701,37 @@ sql_field->length=8; // Unireg field length sql_field->unireg_check=Field::BLOB_FIELD; blob_columns++; + create_info->varchar= 1; break; #else my_error(ER_FEATURE_DISABLED, MYF(0), sym_group_geom.name, sym_group_geom.needed_define); DBUG_RETURN(-1); #endif /*HAVE_SPATIAL*/ - case FIELD_TYPE_VAR_STRING: - case FIELD_TYPE_STRING: + case MYSQL_TYPE_VARCHAR: +#ifndef QQ_ALL_HANDLERS_SUPPORT_VARCHAR + if (file->table_flags() & HA_NO_VARCHAR) + { + /* convert VARCHAR to CHAR because handler is not yet up to date */ + sql_field->sql_type= MYSQL_TYPE_VAR_STRING; + sql_field->pack_length= calc_pack_length(sql_field->sql_type, + (uint) sql_field->length); + if ((sql_field->length / sql_field->charset->mbmaxlen) > + MAX_FIELD_CHARLENGTH) + { + my_printf_error(ER_TOO_BIG_FIELDLENGTH, ER(ER_TOO_BIG_FIELDLENGTH), + MYF(0), sql_field->field_name, MAX_FIELD_CHARLENGTH); + DBUG_RETURN(-1); + } + } + else +#endif + create_info->varchar= 1; + /* fall through */ + case MYSQL_TYPE_STRING: sql_field->pack_flag=0; if (sql_field->charset->state & MY_CS_BINSORT) - sql_field->pack_flag|=FIELDFLAG_BINARY; + sql_field->pack_flag|= FIELDFLAG_BINARY; break; case FIELD_TYPE_ENUM: sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) | @@ -953,6 +1012,7 @@ CHARSET_INFO *ft_key_charset=0; // for FULLTEXT for (uint column_nr=0 ; (column=cols++) ; column_nr++) { + uint length; key_part_spec *dup_column; it.rewind(); @@ -981,8 +1041,8 @@ cols2.rewind(); if (key->type == Key::FULLTEXT) { - if ((sql_field->sql_type != FIELD_TYPE_STRING && - sql_field->sql_type != FIELD_TYPE_VAR_STRING && + if ((sql_field->sql_type != MYSQL_TYPE_STRING && + sql_field->sql_type != MYSQL_TYPE_VARCHAR && !f_is_blob(sql_field->pack_flag)) || sql_field->charset == &my_charset_bin || sql_field->charset->mbminlen > 1 || // ucs2 doesn't work yet @@ -1019,15 +1079,15 @@ } } #ifdef HAVE_SPATIAL - if (key->type == Key::SPATIAL) + if (key->type == Key::SPATIAL) { - if (!column->length ) + if (!column->length) { /* - BAR: 4 is: (Xmin,Xmax,Ymin,Ymax), this is for 2D case - Lately we'll extend this code to support more dimensions + 4 is: (Xmin,Xmax,Ymin,Ymax), this is for 2D case + Lately we'll extend this code to support more dimensions */ - column->length=4*sizeof(double); + column->length= 4*sizeof(double); } } #endif @@ -1063,7 +1123,8 @@ key_part_info->fieldnr= field; key_part_info->offset= (uint16) sql_field->offset; key_part_info->key_type=sql_field->pack_flag; - uint length=sql_field->pack_length; + length= sql_field->key_length; + if (column->length) { if (f_is_blob(sql_field->pack_flag)) @@ -1128,12 +1189,13 @@ /* Use packed keys for long strings on the first column */ if (!(db_options & HA_OPTION_NO_PACK_KEYS) && (length >= KEY_DEFAULT_PACK_LENGTH && - (sql_field->sql_type == FIELD_TYPE_STRING || - sql_field->sql_type == FIELD_TYPE_VAR_STRING || + (sql_field->sql_type == MYSQL_TYPE_STRING || + sql_field->sql_type == MYSQL_TYPE_VARCHAR || sql_field->pack_flag & FIELDFLAG_BLOB))) { - if (column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB)) - key_info->flags|= HA_BINARY_PACK_KEY; + if (column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB) || + sql_field->sql_type == MYSQL_TYPE_VARCHAR) + key_info->flags|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY; else key_info->flags|= HA_PACK_KEY; } @@ -1173,7 +1235,6 @@ if (!(key_info->flags & HA_NULL_PART_KEY)) unique_key=1; key_info->key_length=(uint16) key_length; - uint max_key_length= file->max_key_length(); if (key_length > max_key_length && key->type != Key::FULLTEXT) { my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length); --- 1.315/sql/sql_yacc.yy 2004-12-06 02:05:24 +02:00 +++ 1.316/sql/sql_yacc.yy 2004-12-06 18:04:40 +02:00 @@ -2773,13 +2773,13 @@ Lex->charset=&my_charset_bin; $$=FIELD_TYPE_STRING; } | varchar '(' NUM ')' opt_binary { Lex->length=$3.str; - $$=FIELD_TYPE_VAR_STRING; } + $$= MYSQL_TYPE_VARCHAR; } | nvarchar '(' NUM ')' { Lex->length=$3.str; - $$=FIELD_TYPE_VAR_STRING; + $$= MYSQL_TYPE_VARCHAR; Lex->charset=national_charset_info; } | VARBINARY '(' NUM ')' { Lex->length=$3.str; Lex->charset=&my_charset_bin; - $$=FIELD_TYPE_VAR_STRING; } + $$= MYSQL_TYPE_VARCHAR; } | YEAR_SYM opt_len field_options { $$=FIELD_TYPE_YEAR; } | DATE_SYM { $$=FIELD_TYPE_DATE; } | TIME_SYM { $$=FIELD_TYPE_TIME; } --- 1.41/sql/structs.h 2004-11-18 13:53:18 +02:00 +++ 1.42/sql/structs.h 2004-12-06 18:04:40 +02:00 @@ -98,6 +98,7 @@ union { int bdb_return_if_eq; } handler; + struct st_table *table; } KEY; --- 1.130/sql/table.cc 2004-11-25 15:33:29 +02:00 +++ 1.131/sql/table.cc 2004-12-06 18:04:40 +02:00 @@ -139,7 +139,8 @@ *fn_ext(outparam->path)='\0'; // Remove extension if (head[0] != (uchar) 254 || head[1] != 1 || - (head[2] != FRM_VER && head[2] != FRM_VER+1 && head[2] != FRM_VER+3)) + (head[2] != FRM_VER && head[2] != FRM_VER+1 && + ! (head[2] >= FRM_VER+3 && head[2] <= FRM_VER+4))) goto err_not_open; /* purecov: inspected */ new_field_pack_flag=head[27]; new_frm_ver= (head[2] - FRM_VER); @@ -215,7 +216,8 @@ for (i=0 ; i < keys ; i++, keyinfo++) { - if (new_frm_ver == 3) + keyinfo->table= outparam; + if (new_frm_ver >= 3) { keyinfo->flags= (uint) uint2korr(strpos) ^ HA_NOSAME; keyinfo->key_length= (uint) uint2korr(strpos+2); @@ -433,7 +435,7 @@ Field::geometry_type geom_type= Field::GEOM_GEOMETRY; LEX_STRING comment; - if (new_frm_ver == 3) + if (new_frm_ver >= 3) { /* new frm file in 4.1 */ field_length= uint2korr(strpos+3); @@ -441,11 +443,10 @@ pack_flag= uint2korr(strpos+8); unireg_type= (uint) strpos[10]; interval_nr= (uint) strpos[12]; - uint comment_length=uint2korr(strpos+15); field_type=(enum_field_types) (uint) strpos[13]; - // charset and geometry_type share the same byte in frm + /* charset and geometry_type share the same byte in frm */ if (field_type == FIELD_TYPE_GEOMETRY) { #ifdef HAVE_SPATIAL @@ -609,10 +610,12 @@ keyinfo->key_length+= HA_KEY_NULL_LENGTH; } if (field->type() == FIELD_TYPE_BLOB || - field->real_type() == FIELD_TYPE_VAR_STRING) + field->real_type() == MYSQL_TYPE_VARCHAR) { if (field->type() == FIELD_TYPE_BLOB) key_part->key_part_flag|= HA_BLOB_PART; + else + key_part->key_part_flag|= HA_VAR_LENGTH_PART; keyinfo->extra_length+=HA_KEY_BLOB_LENGTH; key_part->store_length+=HA_KEY_BLOB_LENGTH; keyinfo->key_length+= HA_KEY_BLOB_LENGTH; @@ -1232,7 +1235,11 @@ if ((file=my_create(name,CREATE_MODE,O_RDWR | O_TRUNC,MYF(MY_WME))) >= 0) { bzero((char*) fileinfo,64); - fileinfo[0]=(uchar) 254; fileinfo[1]= 1; fileinfo[2]= FRM_VER+3; // Header + /* header */ + fileinfo[0]=(uchar) 254; + fileinfo[1]= 1; + fileinfo[2]= FRM_VER+3+ test(create_info->varchar); + fileinfo[3]= (uchar) ha_checktype(create_info->db_type); fileinfo[4]=1; int2store(fileinfo+6,IO_SIZE); /* Next block starts here */ @@ -1385,7 +1392,7 @@ if (use_mb(system_charset_info)) { int len=my_ismbchar(system_charset_info, name, - name+system_charset_info->mbmaxlen); + name+system_charset_info->mbmaxlen); if (len) { name += len; @@ -1462,7 +1469,7 @@ if (use_mb(system_charset_info)) { int len=my_ismbchar(system_charset_info, name, - name+system_charset_info->mbmaxlen); + name+system_charset_info->mbmaxlen); if (len) { name += len; @@ -1497,7 +1504,8 @@ error=my_read(file,(byte*) head,4,MYF(MY_NABP)); my_close(file,MYF(0)); if (error || head[0] != (uchar) 254 || head[1] != 1 || - (head[2] != FRM_VER && head[2] != FRM_VER+1 && head[2] != FRM_VER+3)) + (head[2] != FRM_VER && head[2] != FRM_VER+1 && + (head[2] < FRM_VER+3 || head[2] > FRM_VER+4))) DBUG_RETURN(DB_TYPE_UNKNOWN); DBUG_RETURN(ha_checktype((enum db_type) (uint) *(head+3))); } --- 1.78/sql/table.h 2004-11-25 02:26:56 +02:00 +++ 1.79/sql/table.h 2004-12-06 19:18:30 +02:00 @@ -160,7 +160,8 @@ my_bool no_keyread, no_cache; my_bool clear_query_id; /* To reset query_id for tables and cols */ my_bool auto_increment_field_not_null; - my_bool alias_name_used; /* true if table_name is alias */ + my_bool insert_or_update; /* Can be used by the handler */ + my_bool alias_name_used; /* true if table_name is alias */ Field *next_number_field, /* Set if next_number is activated */ *found_next_number_field, /* Set on open */ *rowid_field; --- 1.52/strings/ctype-czech.c 2004-11-22 09:58:35 +02:00 +++ 1.53/strings/ctype-czech.c 2004-12-06 18:04:40 +02:00 @@ -275,8 +275,9 @@ static int my_strnncollsp_czech(CHARSET_INFO * cs, - const uchar *s, uint slen, - const uchar *t, uint tlen) + const uchar *s, uint slen, + const uchar *t, uint tlen, + my_bool diff_if_only_endspace_difference) { for ( ; slen && s[slen-1] == ' ' ; slen--); for ( ; tlen && t[tlen-1] == ' ' ; tlen--); @@ -352,7 +353,7 @@ #ifdef REAL_MYSQL -#define min_sort_char ' ' +#define min_sort_char 0 #define max_sort_char '9' #define EXAMPLE @@ -391,8 +392,17 @@ *min_str++= *max_str++ = *ptr; } - *min_length= (uint) (min_str - min_org); + + if (cs->state & MY_CS_BINSORT) + *min_length= (uint) (min_str - min_org); + else + { + /* 'a\0\0... is the smallest possible string */ + *min_length= res_length; + } + /* a\ff\ff... is the biggest possible string */ *max_length= res_length; + while (min_str != min_end) { *min_str++ = min_sort_char; /* Because of key compression */ --- 1.78/strings/ctype-tis620.c 2004-11-16 14:45:32 +02:00 +++ 1.79/strings/ctype-tis620.c 2004-12-06 19:18:30 +02:00 @@ -320,7 +320,7 @@ /*0xFC*/ { IGNORE, IGNORE, IGNORE, IGNORE, X }, /*0xFD*/ { IGNORE, IGNORE, IGNORE, IGNORE, X }, /*0xFE*/ { IGNORE, IGNORE, IGNORE, IGNORE, X }, -/* Utilize 0xFF for max_sort_chr in my_like_range_tis620 */ + /* Utilize 0xFF for max_sort_chr in my_like_range_tis620 */ /*0xFF*/ { 255 /*IGNORE*/, IGNORE, IGNORE, IGNORE, X }, }; @@ -559,12 +559,16 @@ static int my_strnncollsp_tis620(CHARSET_INFO * cs __attribute__((unused)), const uchar *a0, uint a_length, - const uchar *b0, uint b_length) + const uchar *b0, uint b_length, + my_bool diff_if_only_endspace_difference) { - uchar buf[80] ; - uchar *end, *a, *b, *alloced= NULL; + uchar buf[80], *end, *a, *b, alloced= NULL; uint length; int res= 0; + +#ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE + diff_if_only_endspace_difference= 0; +#endif a= buf; if ((a_length + b_length +2) > (int) sizeof(buf)) @@ -590,6 +594,8 @@ if (a_length != b_length) { int swap= 0; + if (diff_if_only_endspace_difference) + res= 1; /* Assume 'a' is bigger */ /* Check the next not space character of the longer key. If it's < ' ', then it's smaller than the other key. @@ -600,6 +606,7 @@ a_length= b_length; a= b; swap= -1; /* swap sign of result */ + res= -res; } for (end= a + a_length-length; a < end ; a++) { @@ -683,8 +690,14 @@ } if (*ptr == w_many) /* '%' in SQL */ { - *min_length= (uint) (min_str - min_org); - *max_length=res_length; + /* + Calculate length of keys: + 'a\0\0... is the smallest possible string when we have space expand + a\ff\ff... is the biggest possible string + */ + *min_length= ((cs->state & MY_CS_BINSORT) ? (uint) (min_str - min_org) : + res_length); + *max_length= res_length; do { *min_str++ = 0; @@ -694,10 +707,10 @@ } *min_str++= *max_str++ = *ptr; } - *min_length= *max_length = (uint) (min_str - min_org); + *min_length= *max_length = (uint) (min_str - min_org); while (min_str != min_end) - *min_str++ = *max_str++ = ' '; /* Because of key compression */ + *min_str++= *max_str++ = ' '; /* Because of key compression */ return 0; } --- 1.7/mysql-test/r/ctype_tis620.result 2004-11-15 19:26:09 +02:00 +++ 1.8/mysql-test/r/ctype_tis620.result 2004-12-06 18:04:36 +02:00 @@ -259,8 +259,8 @@ ¡Ñ³°ªÒ ¡Ñ³°Ô¡Ò ¡Ñ³·ÔÁÒ -¡Ñ¹µì ¡Ñ¹µÔ¡Ã +¡Ñ¹µì ¡Ñ¹¸ÔªÒ ¡Ñ¹¸ÔÁÒ ¡Ñ¹ÂÒÃѵ¹ì @@ -272,8 +272,8 @@ ¡Ò­¨¹ÇÃó ¡Ò­¨¹Ò ¡Ò¹´Ò -¡Ò¹µì ¡Ò¹µìÃÇÕ +¡Ò¹µì ¡ÒÂÊÔ·¸Ôì ¡ÒÃÇÔÍà ¡ÒÃØ³Õ @@ -350,8 +350,8 @@ à¡ÕÂõÔÈÑ¡´Ôì à¡ÕÂõÔÊÇÑÊ´Ôì à¡×éÍ¡ÙÅ -á¡éÇ á¡éÇ㨠+á¡éÇ â¡Ážѹ¸ì â¡àÁÈ â¡ÅºÍÅ ¤Í¹à¹ç¤ªÑè¹Êì @@ -368,8 +368,8 @@ ¢¨Ãà¡ÕÂÃµÔ ¢¨ÃÈÃÕ ¢¨ÃÈÑ¡´Ôì -¢¹ÔÉ°ì ¢¹ÔÉ°Ò +¢¹ÔÉ°ì ¢Çѭ㨠¢ÇÑ­ªÑ ¢ÇÑ­à´×͹ @@ -412,8 +412,8 @@ ठÊËÒÂÍÔÁà»ê¡«ì à¤.«Õ.¾Õ. áÁªªÕ¹à¹ÍÃÕè षշÕÅÔÊ«Ôè§ -ह áÁ¡«ì (»ÃÐà·Èä·Â) ह áÁç¡«ì (»ÃÐà·Èä·Â) +ह áÁ¡«ì (»ÃÐà·Èä·Â) à¤Ã×ÍÇÑÅÂì ᤹¹Ù ÍÔ¹àµÍÃìà·Ã´ á¤Ð¨éÍ @@ -494,12 +494,12 @@ ¨ÓàÃÔ­ ¨ÓÅͧ ¨Ô³³ì -¨Ôµµì ¨Ôµµì¹ÔÉÒ ¨ÔµµÁÒÊ ¨ÔµµÒ ¨ÔµµÔ ¨ÔµµÔ¹¹Ñ¹·ì +¨Ôµµì ¨ÔµÃÅ´Ò ¨ÔµÃÒ ¨ÔµÃÒÀóì @@ -627,10 +627,10 @@ ªÇ¹¾ÔÈ ªÇÅÔµ ªÇÔÈÒ -ªèÍ ªèͩѵà ªèÍ·Ô¾Âì ªèÍÍÑ­ªÑ­ +ªèÍ ªÐ¹ÔÅ ªÐÍé͹ ªÑªªÑ @@ -758,12 +758,12 @@ ³¸ÔµÒ ³ÀÑ·Ã ³Àѷáóì -³Ã§¤ì ³Ã§¤ìªÑ ³Ã§¤ì¾ÑªÃì ³Ã§¤ìÄ·¸Ôì ³Ã§¤ìÇÔ·Âì ³Ã§¤ìÈÑ¡´Ôì +³Ã§¤ì ³Ã§ÃÑ¡Éì ³Ã§Ä·¸Ôì ³Ã§ÈÑ¡´Ôì @@ -862,11 +862,11 @@ µÐÇѹ µÑ觨Ñè§ËÅÍ´ä¿ µÒà¿ç´ -µØê µØê¡µÒ µØéÁ µØë µØÅÒÅѡɳì +µØê àµçÁà´ª àµ×͹㨠àµ×͹µÒ @@ -917,8 +917,8 @@ ·Ñº·ÔÁ ·ÑȹÇÃó ·Ñȹվà -·ÑȹÕÂì ·ÑȹÕÂÒ +·ÑȹÕÂì ·ÑÈÇÃó ·èÒ·ÃÒÂá¨é§ÇѲ¹Ò ·Ô¦ÑÁ¾Ã @@ -1088,8 +1088,8 @@ ¹Ã¾Å ¹ÃÀÑ·Ãì ¹ÃÒ -¹ÃÔ¹·Ãì ¹ÃÔ¹·Ãìà´ª +¹ÃÔ¹·Ãì ¹ÃÔÈ ¹ÃÔɰ ¹ÃÕ @@ -1115,8 +1115,8 @@ ¹Ñ·¸Á¹ ¹Ñ¹ªÑ ¹Ñ¹·ªÑ -¹Ñ¹·¹ì ¹Ñ¹·¹Ò +¹Ñ¹·¹ì ¹Ñ¹·¾Ã ¹Ñ¹·¾Å ¹Ñ¹·ÁÒÊ @@ -1148,14 +1148,14 @@ ¹Ôà«Ð ¹Ô´ ¹Ô´Ò -¹ÔµÂì ¹ÔµÂÒ +¹ÔµÂì ¹ÔµÔ ¹ÔµÔ¾§Éì ¹ÔµÔÁÒ ¹Ô·ÃÒ -¹Ô·ÑÈ¹ì ¹Ô·ÑȹÕÂì +¹Ô·ÑÈ¹ì ¹Ô¸ÔÇ´Õ ¹Ô»»Í¹à¾¹µì(»ÃÐà·Èä·Â) ¹Ô¾¹¸ì @@ -1349,8 +1349,8 @@ »ÃÒ³ÕÂì »ÃÒâÁ·Âì »ÃÒö¹Ò -»ÃÔ­­ì »ÃÔ­­Ò +»ÃÔ­­ì »ÃÔ­´Ò »ÃÔ³´Ò »ÃÔ·ÑÈ @@ -1454,10 +1454,10 @@ ¾§ÉìÈÑ¡´Ôì ¾§ÉìÊѹµì ¾§Éì͹ѹµì -¾¨¹ì ¾¨¹Ò ¾¨¹Òö ¾¨¹ÕÂì +¾¨¹ì ¾¨ÁÒ¹ ¾¨ÁÒÅÂì ¾¹Á @@ -1504,8 +1504,8 @@ ¾ÃÊÇÃÃ¤ì ¾ÃËÁ¾Ñ²¹ì ¾ÃéÍÁªÑ -¾ÃлÃÐá´§ Î͹´éÒ¤ÒÃìÊì ¾ÃлÃÐá´§ Î͹´éÒ¤ÒÃìÊì ¨Ó¡Ñ´ +¾ÃлÃÐá´§ Î͹´éÒ¤ÒÃìÊì ¾ÃÐÃÒÁ 3 ¤ÒÃìà«ç¹àµÍÃì ¾ÃÐÃÒÁ 3 Î͹´éÒ¤ÒÃìÊì ¾ÃÔéÁà¾ÃÒ @@ -1604,10 +1604,10 @@ ¾Ùŷͧ¾Ãç;à¾ÍÃìµÕé_ ¾ÙżŠà¾ç§ ¿Ù ËÅÔ¹ -à¾çªÃì ྪÃÃѵ¹ì ྪÃÅ´Ò à¾ªÃÔ¹·Ãì +à¾çªÃì à¾ç­¨Ñ¹·Ãì à¾ç­·Ô¾Âì à¾ç­¹ÀÒ @@ -1831,7 +1831,6 @@ ÃÒàÁÈÃì ÃÒÂÕ¹ Ã×è¹ÇÃÒËì -ÃØé§ ÃØè§·Ô¾Âì ÃØè§·ÔÇÒ ÃØè§¹ÀÒ @@ -1840,11 +1839,12 @@ ÃØè§Ãѵ¹ì ÃØè§ÃÑÈÁÕ ÃØè§àÃ×ͧ -ÃØè§âè¹ì ÃØè§âè¹ì¢¹Êè§ +ÃØè§âè¹ì ÃØé§ÅÒÇÃó ÃØè§ÇÔ·Âì ÃØè§ÍÃØ³ +ÃØé§ ÃØ¨Ò ÃØ¨ÒÀÒ ÃØËÐ¹Ò @@ -1861,8 +1861,8 @@ áþᾤ ¤Í¹ÊµÃѤªÑè¹ âç§Ò¹àËÅç¡¡ÃØ§à·¾Ï âè¹ì»ÃÐàÊÃÔ° -Ä·¸Ôì Ä·¸ÔªÑ +Ä·¸Ôì ÅÅÔ´Ò ÅÅÔµÒ ÅÐÁèÍÁ @@ -2050,8 +2050,8 @@ ÇÔäÅÇÃó ÇÔÇ ÇÔÇÃø¹ì -ÇÔÇѲ¹ì ÇÔÇѲ¹ìªÑ +ÇÔÇѲ¹ì ÇÔÈ¹Õ ÇÔÈÃØµ ÇÔÈÒÅ @@ -2146,11 +2146,11 @@ ÈÈÔÇÔÁÅ ÈÈÔÉÒ ÈÑ¡´Ò -ÈÑ¡´Ôì ÈÑ¡´ÔìªÑ ÈÑ¡´ÔìàªÇ§ ÈÑ¡´Ôì´Ò ÈÑ¡´ÔìÇÔºÙÅÂì +ÈÑ¡´Ôì ÈÑ¡ÃÔ¹·Ãì ÈѹʹÕÂì ÈÒ¹µÔᏴì @@ -2348,18 +2348,18 @@ ÊÓÃÒ­ ÊÓÄ·¸Ôì ÊÓÅÕ -ÊÔ§Ëì ÊÔ§Ëì¾Å ÊÔ§ËÒ +ÊÔ§Ëì ÊԵҹѹ ÊԵҾà ÊÔ·¸Ò -ÊÔ·¸Ôì ÊÔ·¸ÔªÑ ÊÔ·¸Ôà´ª ÊÔ·¸Ô¾Ã ÊÔ·¸Ô¾Ãó ÊÔ·¸Ô¾Å +ÊÔ·¸Ôì ÊÔ¹·ÇÕ ÊÔÃԪѠÊÔÃÔà´ª @@ -2393,15 +2393,15 @@ ÊØ¢ÊÇÑÊ´Ôì¡Å¡ÒÃ ÊØ¢Êѹµì ÊØ¢ØÁ -ÊØ¤¹¸ì ÊØ¤¹¸Ò +ÊØ¤¹¸ì ÊØ¨ÒÃÕ ÊØ¨Ôµ ÊØ¨ÔµµÒ ÊØ¨ÔµÃÒ ÊØ¨Ô¹´Ò -ÊØ¨Ô¹µì ÊØ¨Ô¹µ¹ì +ÊØ¨Ô¹µì ÊØªÅ ÊØªÑÂ ÊØªÒ´Ò @@ -2443,13 +2443,13 @@ ÊØ¸Ô´Ò ÊØ¸ÔÈÑ¡´Ôì ÊØ¸Õ -ÊØ¸ÕÃì ÊØ¸ÕÃÒ +ÊØ¸ÕÃì ÊØ¹·Ã ÊØ¹·ÃÕ ÊØ¹Ñ··Õ -ÊØ¹Ñ¹·ì ÊØ¹Ñ¹·Ò +ÊØ¹Ñ¹·ì ÊØ¹ÔµÒ ÊØ¹ÔÈÒ ÊØ¹ÔÉÒ @@ -2511,10 +2511,10 @@ ÊØÃÈÑ¡´Ôì ÊØÃÊÔ·¸Ôì ÊØÃѪ¹Õ¡Ã -ÊØÃѵ¹ì ÊØÃѵ¹Ç´Õ ÊØÃѵ¹ìÇ´Õ ÊØÃѵ¹Ò +ÊØÃѵ¹ì ÊØÃѵÂÒ ÊØÃÒ§¤¹Ò ÊØÃԪѠ@@ -2529,8 +2529,8 @@ ÊØÃÕ¸Ò¾Ã ÊØÃÕ¾Ã ÊØÃÕÁÒÈ -ÊØÃÕÂì ÊØÃÕÂì¾Ã +ÊØÃÕÂì ÊØÃÕÃѵ¹ì ÊØÅÑ´´Ò ÊØÇÀÑ·Ãì @@ -2540,9 +2540,9 @@ ÊØÇÃÃ³Õ ÊØÇÃóÕÂì ÊØÇÃѵ¹ì -ÊØÇѲ¹ì ÊØÇѲ¹ìªÑÂ ÊØÇѲ¹Ò +ÊØÇѲ¹ì ÊØÇѵªÑÂ ÊØÇÒÃÕ ÊØÇԪѠ@@ -2623,8 +2623,8 @@ ͹¹·ì ͹ÇѪ ͹ѭ­Ò -͹ѹµì ͹ѹµÈÑ¡´Ôì +͹ѹµì Í¹Ø¡ÔµÔ Í¹Ø¡ÙÅ Í¹ØªÒ @@ -2770,8 +2770,8 @@ ÍÒÃҾà ÍÒÃÔÂÒ ÍÒÃÕ -ÍÒÃÕÂì ÍÒÃÕÂì àÊÁÒ©ÔÁ (ä·Âູ¡Ñ¹ +ÍÒÃÕÂì ÍÒÃÕÃѵ¹ì ÍÒÃÕÇÃó ÍӹǠ--- 1.26/strings/ctype-uca.c 2004-11-24 18:07:20 +02:00 +++ 1.27/strings/ctype-uca.c 2004-12-06 18:04:40 +02:00 @@ -7048,6 +7048,9 @@ slen First string length t Second string tlen Seconf string length + diff_if_only_endspace_difference + Set to 1 if the strings should be regarded as different + if they only difference in end space NOTES: Works exactly the same with my_strnncoll_uca(), @@ -7085,13 +7088,16 @@ static int my_strnncollsp_uca(CHARSET_INFO *cs, my_uca_scanner_handler *scanner_handler, const uchar *s, uint slen, - const uchar *t, uint tlen) + const uchar *t, uint tlen, + my_bool diff_if_only_endspace_difference) { - my_uca_scanner sscanner; - my_uca_scanner tscanner; - int s_res; - int t_res; + my_uca_scanner sscanner, tscanner; + int s_res, t_res; +#ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE + diff_if_only_endspace_difference= 0; +#endif + scanner_handler->init(&sscanner, cs, s, slen); scanner_handler->init(&tscanner, cs, t, tlen); @@ -7113,7 +7119,7 @@ return (s_res - t_res); s_res= scanner_handler->next(&sscanner); } while (s_res > 0); - return 0; + return diff_if_only_endspace_difference ? 1 : 0; } if (s_res < 0 && t_res > 0) @@ -7128,7 +7134,7 @@ return (s_res - t_res); t_res= scanner_handler->next(&tscanner); } while (t_res > 0); - return 0; + return diff_if_only_endspace_difference ? -1 : 0; } return ( s_res - t_res ); @@ -7941,11 +7947,13 @@ } static int my_strnncollsp_any_uca(CHARSET_INFO *cs, - const uchar *s, uint slen, - const uchar *t, uint tlen) + const uchar *s, uint slen, + const uchar *t, uint tlen, + my_bool diff_if_only_endspace_difference) { return my_strnncollsp_uca(cs, &my_any_uca_scanner_handler, - s, slen, t, tlen); + s, slen, t, tlen, + diff_if_only_endspace_difference); } static void my_hash_sort_any_uca(CHARSET_INFO *cs, @@ -7978,11 +7986,13 @@ } static int my_strnncollsp_ucs2_uca(CHARSET_INFO *cs, - const uchar *s, uint slen, - const uchar *t, uint tlen) + const uchar *s, uint slen, + const uchar *t, uint tlen, + my_bool diff_if_only_endspace_difference) { return my_strnncollsp_uca(cs, &my_ucs2_uca_scanner_handler, - s, slen, t, tlen); + s, slen, t, tlen, + diff_if_only_endspace_difference); } static void my_hash_sort_ucs2_uca(CHARSET_INFO *cs, --- 1.17/mysql-test/r/ctype_ucs.result 2004-12-06 02:05:20 +02:00 +++ 1.18/mysql-test/r/ctype_ucs.result 2004-12-06 18:04:36 +02:00 @@ -23,16 +23,24 @@ binary 'a a' > 'a' binary 'a \0' > 'a' binary 'a\0' > 'a' 1 1 1 SET CHARACTER SET koi8r; -CREATE TABLE t1 (word VARCHAR(64) CHARACTER SET ucs2); -INSERT INTO t1 VALUES (_koi8r'ò'), (X'2004'); +CREATE TABLE t1 (word VARCHAR(64) CHARACTER SET ucs2, word2 CHAR(64) CHARACTER SET ucs2); +INSERT INTO t1 VALUES (_koi8r'ò',_koi8r'ò'), (X'2004',X'2004'); SELECT hex(word) FROM t1 ORDER BY word; hex(word) 0420 2004 +SELECT hex(word2) FROM t1 ORDER BY word2; +hex(word2) +0420 +2004 DELETE FROM t1; -INSERT INTO t1 VALUES (X'042000200020'), (X'200400200020'); +INSERT INTO t1 VALUES (X'042000200020',X'042000200020'), (X'200400200020', X'200400200020'); SELECT hex(word) FROM t1 ORDER BY word; hex(word) +042000200020 +200400200020 +SELECT hex(word2) FROM t1 ORDER BY word2; +hex(word2) 0420 2004 DROP TABLE t1; --- 1.17/mysql-test/t/ctype_ucs.test 2004-12-06 02:05:20 +02:00 +++ 1.18/mysql-test/t/ctype_ucs.test 2004-12-06 18:04:37 +02:00 @@ -20,17 +20,19 @@ # which contains 0x20 in the high byte. # -CREATE TABLE t1 (word VARCHAR(64) CHARACTER SET ucs2); -INSERT INTO t1 VALUES (_koi8r'ò'), (X'2004'); +CREATE TABLE t1 (word VARCHAR(64) CHARACTER SET ucs2, word2 CHAR(64) CHARACTER SET ucs2); +INSERT INTO t1 VALUES (_koi8r'ò',_koi8r'ò'), (X'2004',X'2004'); SELECT hex(word) FROM t1 ORDER BY word; +SELECT hex(word2) FROM t1 ORDER BY word2; DELETE FROM t1; # # Check that real spaces are correctly trimmed. # -INSERT INTO t1 VALUES (X'042000200020'), (X'200400200020'); +INSERT INTO t1 VALUES (X'042000200020',X'042000200020'), (X'200400200020', X'200400200020'); SELECT hex(word) FROM t1 ORDER BY word; +SELECT hex(word2) FROM t1 ORDER BY word2; DROP TABLE t1; # @@ -52,7 +54,6 @@ SHOW CREATE TABLE t1; DROP TABLE t1; - # # BUG3946 # @@ -61,6 +62,7 @@ insert into t2 values ("103000"), ("22720000"), ("3401200"), ("78000"); select lpad(f1, 12, "-o-/") from t2; drop table t2; + ###################################################### # # Test of like --- 1.33/strings/ctype-ucs2.c 2004-12-01 17:25:00 +02:00 +++ 1.34/strings/ctype-ucs2.c 2004-12-06 19:18:30 +02:00 @@ -137,6 +137,9 @@ int res; const uchar *e=s+slen; + while (e > s+1 && e[-1] == ' ' && e[-2] == '\0') + e-= 2; + while ((s < e) && (res=my_ucs2_uni(cs,&wc, (uchar *)s, (uchar*)e)) >0) { int plane = (wc>>8) & 0xFF; @@ -247,14 +250,16 @@ static int my_strnncollsp_ucs2(CHARSET_INFO *cs __attribute__((unused)), const uchar *s, uint slen, - const uchar *t, uint tlen) + const uchar *t, uint tlen, + my_bool diff_if_only_endspace_difference + __attribute__((unused))) { const uchar *se, *te; uint minlen; /* extra safety to make sure the lengths are even numbers */ - slen= (slen >> 1) << 1; - tlen= (tlen >> 1) << 1; + slen&= ~1; + tlen&= ~1; se= s + slen; te= t + tlen; @@ -1354,8 +1359,10 @@ static int my_strnncollsp_ucs2_bin(CHARSET_INFO *cs, const uchar *s, uint slen, - const uchar *t, uint tlen) + const uchar *t, uint tlen, + my_bool diff_if_only_endspace_difference) { + /* TODO: Needs to be fixed to handle end space! */ return my_strnncoll_ucs2_bin(cs,s,slen,t,tlen,0); } @@ -1444,8 +1451,14 @@ } if (ptr[0] == '\0' && ptr[1] == w_many) /* '%' in SQL */ { - *min_length= (uint) (min_str - min_org); - *max_length=res_length; + /* + Calculate length of keys: + 'a\0\0... is the smallest possible string when we have space expand + a\ff\ff... is the biggest possible string + */ + *min_length= ((cs->state & MY_CS_BINSORT) ? (uint) (min_str - min_org) : + res_length); + *max_length= res_length; do { *min_str++ = 0; *min_str++ = 0; @@ -1457,7 +1470,6 @@ *min_str++= *max_str++ = ptr[0]; *min_str++= *max_str++ = ptr[1]; } - *min_length= *max_length = (uint) (min_str - min_org); /* Temporary fix for handling w_one at end of string (key compression) */ { @@ -1469,13 +1481,15 @@ } } + *min_length= *max_length = (uint) (min_str - min_org); while (min_str + 1 < min_end) { *min_str++ = *max_str++ = '\0'; - *min_str++ = *max_str++ = ' '; /* Because if key compression */ + *min_str++ = *max_str++ = ' '; /* Because if key compression */ } return 0; } + static MY_COLLATION_HANDLER my_collation_ucs2_general_ci_handler = { --- 1.34/strings/ctype-mb.c 2004-11-19 12:25:21 +02:00 +++ 1.35/strings/ctype-mb.c 2004-12-06 19:18:30 +02:00 @@ -362,6 +362,9 @@ slen Length of 's' t String to compare tlen Length of 't' + diff_if_only_endspace_difference + Set to 1 if the strings should be regarded as different + if they only difference in end space NOTE This function is used for character strings with binary collations. @@ -376,10 +379,16 @@ static int my_strnncollsp_mb_bin(CHARSET_INFO * cs __attribute__((unused)), const uchar *a, uint a_length, - const uchar *b, uint b_length) + const uchar *b, uint b_length, + my_bool diff_if_only_endspace_difference) { const uchar *end; uint length; + int res; + +#ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE + diff_if_only_endspace_difference= 0; +#endif end= a + (length= min(a_length, b_length)); while (a < end) @@ -387,9 +396,12 @@ if (*a++ != *b++) return ((int) a[-1] - (int) b[-1]); } + res= 0; if (a_length != b_length) { int swap= 0; + if (diff_if_only_endspace_difference) + res= 1; /* Assume 'a' is bigger */ /* Check the next not space character of the longer key. If it's < ' ', then it's smaller than the other key. @@ -400,6 +412,7 @@ a_length= b_length; a= b; swap= -1; /* swap sign of result */ + res= -res; } for (end= a + a_length-length; a < end ; a++) { @@ -407,7 +420,7 @@ return ((int) *a - (int) ' ') ^ swap; } } - return 0; + return res; } @@ -523,9 +536,15 @@ if (charlen < (uint) (min_str - min_org)) min_str= min_org + charlen; - /* Write min key */ - *min_length= (uint) (min_str - min_org); + /* + Calculate length of keys: + 'a\0\0... is the smallest possible string when we have space expand + a\ff\ff... is the biggest possible string + */ + *min_length= ((cs->state & MY_CS_BINSORT) ? (uint) (min_str - min_org) : + res_length); *max_length= res_length; + /* Create min key */ do { *min_str++= (char) cs->min_sort_char; @@ -541,13 +560,13 @@ } *min_str++= *max_str++ = *ptr; } - *min_length= *max_length = (uint) (min_str - min_org); + *min_length= *max_length = (uint) (min_str - min_org); while (min_str != min_end) - *min_str++= ' '; /* Because if key compression */ - pad_max_char(cs, max_str, max_end); + *min_str++= *max_str= ' '; /* Because if key compression */ return 0; } + static int my_wildcmp_mb_bin(CHARSET_INFO *cs, const char *str,const char *str_end, --- 1.78/strings/ctype-utf8.c 2004-11-24 18:07:20 +02:00 +++ 1.79/strings/ctype-utf8.c 2004-12-06 18:04:40 +02:00 @@ -1923,12 +1923,20 @@ } } -static void my_hash_sort_utf8(CHARSET_INFO *cs, const uchar *s, uint slen, ulong *n1, ulong *n2) +static void my_hash_sort_utf8(CHARSET_INFO *cs, const uchar *s, uint slen, + ulong *n1, ulong *n2) { my_wc_t wc; int res; const uchar *e=s+slen; + /* + Remove end space. We have to do this to be able to compare + 'A ' and 'A' as identical + */ + while (e > s && e[-1] == ' ') + e--; + while ((s < e) && (res=my_utf8_uni(cs,&wc, (uchar *)s, (uchar*)e))>0 ) { int plane = (wc>>8) & 0xFF; @@ -2021,6 +2029,9 @@ a_length Length of 'a' b Second string to compare b_length Length of 'b' + diff_if_only_endspace_difference + Set to 1 if the strings should be regarded as different + if they only difference in end space IMPLEMENTATION If one string is shorter as the other, then we space extend the other @@ -2039,13 +2050,17 @@ */ static int my_strnncollsp_utf8(CHARSET_INFO *cs, - const uchar *s, uint slen, - const uchar *t, uint tlen) + const uchar *s, uint slen, + const uchar *t, uint tlen, + my_bool diff_if_only_endspace_difference) { - int s_res,t_res; + int s_res, t_res, res; my_wc_t s_wc,t_wc; - const uchar *se= s+slen; - const uchar *te= t+tlen; + const uchar *se= s+slen, *te= t+tlen; + +#ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE + diff_if_only_endspace_difference= 0; +#endif while ( s < se && t < te ) { @@ -2074,16 +2089,20 @@ slen= se-s; tlen= te-t; + res= 0; if (slen != tlen) { int swap= 0; + if (diff_if_only_endspace_difference) + res= 1; /* Assume 'a' is bigger */ if (slen < tlen) { slen= tlen; s= t; se= te; swap= -1; + res= -res; } /* This following loop uses the fact that in UTF-8 @@ -2101,7 +2120,7 @@ return ((int)*s - (int) ' ') ^ swap; } } - return 0; + return res; } --- 1.42/strings/ctype-win1250ch.c 2004-11-22 09:58:35 +02:00 +++ 1.43/strings/ctype-win1250ch.c 2004-12-06 18:04:40 +02:00 @@ -479,7 +479,8 @@ static int my_strnncollsp_win1250ch(CHARSET_INFO * cs, const uchar *s, uint slen, - const uchar *t, uint tlen) + const uchar *t, uint tlen, + my_bool diff_if_only_endspace_difference) { for ( ; slen && s[slen-1] == ' ' ; slen--); for ( ; tlen && t[tlen-1] == ' ' ; tlen--); @@ -594,11 +595,19 @@ if (*min_str != min_sort_char) only_min_found= 0; min_str++; - *max_str++ = like_range_prefix_max_win1250ch[(uint)(*ptr)]; + *max_str++= like_range_prefix_max_win1250ch[(uint)(*ptr)]; } - *min_length = (uint) (min_str - min_org); - *max_length = res_length; + if (cs->state & MY_CS_BINSORT) + *min_length= (uint) (min_str - min_org); + else + { + /* 'a\0\0... is the smallest possible string */ + *min_length= res_length; + } + /* a\ff\ff... is the biggest possible string */ + *max_length= res_length; + while (min_str != min_end) { *min_str++ = min_sort_char; --- 1.92/mysql-test/r/subselect.result 2004-12-06 02:05:20 +02:00 +++ 1.93/mysql-test/r/subselect.result 2004-12-06 18:04:37 +02:00 @@ -361,10 +361,10 @@ INSERT INTO t8 (pseudo,email) VALUES ('2joce1','2test1'); EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t8 const PRIMARY PRIMARY 35 const 1 Using index -4 SUBQUERY t8 const PRIMARY PRIMARY 35 1 Using index -2 SUBQUERY t8 const PRIMARY PRIMARY 35 const 1 -3 SUBQUERY t8 const PRIMARY PRIMARY 35 1 Using index +1 PRIMARY t8 ref PRIMARY PRIMARY 37 const 1 Using where; Using index +4 SUBQUERY t8 ref PRIMARY PRIMARY 37 1 +2 SUBQUERY t8 ref PRIMARY PRIMARY 37 const 1 Using where +3 SUBQUERY t8 ref PRIMARY PRIMARY 37 1 Warnings: Note 1003 select `test`.`t8`.`pseudo` AS `pseudo`,(select `test`.`t8`.`email` AS `email` from `test`.`t8` where (`test`.`t8`.`pseudo` = (select `test`.`t8`.`pseudo` AS `pseudo` from `test`.`t8` where (`test`.`t8`.`pseudo` = _latin1'joce')))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where (`test`.`t8`.`pseudo` = (select `test`.`t8`.`pseudo` AS `pseudo` from `test`.`t8` where (`test`.`t8`.`pseudo` = _latin1'joce'))) SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM @@ -390,13 +390,13 @@ ('43506','2002-10-02','joce'),('40143','2002-08-03','joce'); EXPLAIN EXTENDED SELECT DISTINCT date FROM t1 WHERE date='2002-08-03'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL PRIMARY 41 NULL 2 Using where; Using index +1 SIMPLE t1 index NULL PRIMARY 43 NULL 2 Using where; Using index Warnings: Note 1003 select distinct `test`.`t1`.`date` AS `date` from `test`.`t1` where (`test`.`t1`.`date` = 20020803) EXPLAIN EXTENDED SELECT (SELECT DISTINCT date FROM t1 WHERE date='2002-08-03'); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used -2 SUBQUERY t1 index NULL PRIMARY 41 NULL 2 Using where; Using index +2 SUBQUERY t1 index NULL PRIMARY 43 NULL 2 Using where; Using index Warnings: Note 1003 select (select distinct `test`.`t1`.`date` AS `date` from `test`.`t1` where (`test`.`t1`.`date` = 20020803)) AS `(SELECT DISTINCT date FROM t1 WHERE date='2002-08-03')` SELECT DISTINCT date FROM t1 WHERE date='2002-08-03'; --- 1.14/mysql-test/r/ps_1general.result 2004-11-25 22:55:43 +02:00 +++ 1.15/mysql-test/r/ps_1general.result 2004-12-06 18:04:37 +02:00 @@ -277,7 +277,7 @@ prepare stmt4 from ' show table status from test like ''t9%'' '; execute stmt4; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t9 MyISAM 9 Dynamic 2 220 440 4294967295 2048 0 NULL # # # latin1_swedish_ci NULL +t9 MyISAM 10 Dynamic 2 222 444 4294967295 2048 0 NULL # # # latin1_swedish_ci NULL prepare stmt4 from ' show status like ''Threads_running'' '; execute stmt4; Variable_name Value @@ -291,7 +291,7 @@ prepare stmt4 from ' show full processlist '; execute stmt4; Id User Host db Command Time State Info -number root localhost test Query 0 NULL show full processlist +number root localhost test Query seconds NULL show full processlist prepare stmt4 from ' show grants for user '; prepare stmt4 from ' show create table t2 '; ERROR HY000: This command is not supported in the prepared statement protocol yet --- 1.11/mysql-test/r/ps_2myisam.result 2004-11-11 19:54:00 +02:00 +++ 1.12/mysql-test/r/ps_2myisam.result 2004-12-06 18:04:37 +02:00 @@ -69,7 +69,7 @@ def test t9 t9 c18 c18 1 1 1 Y 32768 0 63 def test t9 t9 c19 c19 1 1 1 Y 32768 0 63 def test t9 t9 c20 c20 254 1 1 Y 0 0 8 -def test t9 t9 c21 c21 253 10 10 Y 0 0 8 +def test t9 t9 c21 c21 254 10 10 Y 0 0 8 def test t9 t9 c22 c22 253 30 30 Y 0 0 8 def test t9 t9 c23 c23 252 255 8 Y 144 0 63 def test t9 t9 c24 c24 252 255 8 Y 16 0 8 @@ -1705,8 +1705,8 @@ info: Records: 3 Duplicates: 0 Warnings: 0 select a,b from t2 order by a ; a b -3 duplicate -4 duplicate +3 duplicate +4 duplicate 103 three delete from t2 ; prepare stmt1 from ' insert into t2 (b,a) @@ -1777,11 +1777,11 @@ `param04` longtext, `const05` binary(3) NOT NULL default '', `param05` longblob, - `const06` varchar(10) NOT NULL default '', + `const06` char(10) NOT NULL default '', `param06` longtext, `const07` date default NULL, `param07` longblob, - `const08` varchar(19) NOT NULL default '', + `const08` char(19) NOT NULL default '', `param08` longtext, `const09` datetime default NULL, `param09` longblob, @@ -1807,11 +1807,11 @@ def test t5 t5 param04 param04 252 16777215 3 Y 16 0 8 def test t5 t5 const05 const05 254 3 3 N 129 0 63 def test t5 t5 param05 param05 252 16777215 3 Y 144 0 63 -def test t5 t5 const06 const06 253 10 10 N 1 0 8 +def test t5 t5 const06 const06 254 10 10 N 1 0 8 def test t5 t5 param06 param06 252 16777215 10 Y 16 0 8 def test t5 t5 const07 const07 10 10 10 Y 128 0 63 def test t5 t5 param07 param07 252 16777215 10 Y 144 0 63 -def test t5 t5 const08 const08 253 19 19 N 1 0 8 +def test t5 t5 const08 const08 254 19 19 N 1 0 8 def test t5 t5 param08 param08 252 16777215 19 Y 16 0 8 def test t5 t5 const09 const09 12 19 19 Y 128 0 63 def test t5 t5 param09 param09 252 16777215 19 Y 144 0 63 --- 1.13/mysql-test/r/ps_3innodb.result 2004-11-11 19:54:00 +02:00 +++ 1.14/mysql-test/r/ps_3innodb.result 2004-12-06 18:04:37 +02:00 @@ -69,8 +69,8 @@ def test t9 t9 c18 c18 1 1 1 Y 32768 0 63 def test t9 t9 c19 c19 1 1 1 Y 32768 0 63 def test t9 t9 c20 c20 254 1 1 Y 0 0 8 -def test t9 t9 c21 c21 253 10 10 Y 0 0 8 -def test t9 t9 c22 c22 253 30 30 Y 0 0 8 +def test t9 t9 c21 c21 254 10 10 Y 0 0 8 +def test t9 t9 c22 c22 254 30 30 Y 0 0 8 def test t9 t9 c23 c23 252 255 8 Y 144 0 63 def test t9 t9 c24 c24 252 255 8 Y 16 0 8 def test t9 t9 c25 c25 252 65535 4 Y 144 0 63 @@ -1760,11 +1760,11 @@ `param04` longtext, `const05` binary(3) NOT NULL default '', `param05` longblob, - `const06` varchar(10) NOT NULL default '', + `const06` char(10) NOT NULL default '', `param06` longtext, `const07` date default NULL, `param07` longblob, - `const08` varchar(19) NOT NULL default '', + `const08` char(19) NOT NULL default '', `param08` longtext, `const09` datetime default NULL, `param09` longblob, @@ -1790,11 +1790,11 @@ def test t5 t5 param04 param04 252 16777215 3 Y 16 0 8 def test t5 t5 const05 const05 254 3 3 N 129 0 63 def test t5 t5 param05 param05 252 16777215 3 Y 144 0 63 -def test t5 t5 const06 const06 253 10 10 N 1 0 8 +def test t5 t5 const06 const06 254 10 10 N 1 0 8 def test t5 t5 param06 param06 252 16777215 10 Y 16 0 8 def test t5 t5 const07 const07 10 10 10 Y 128 0 63 def test t5 t5 param07 param07 252 16777215 10 Y 144 0 63 -def test t5 t5 const08 const08 253 19 19 N 1 0 8 +def test t5 t5 const08 const08 254 19 19 N 1 0 8 def test t5 t5 param08 param08 252 16777215 19 Y 16 0 8 def test t5 t5 const09 const09 12 19 19 Y 128 0 63 def test t5 t5 param09 param09 252 16777215 19 Y 144 0 63 --- 1.10/mysql-test/r/ps_4heap.result 2004-11-11 19:54:00 +02:00 +++ 1.11/mysql-test/r/ps_4heap.result 2004-12-06 18:04:37 +02:00 @@ -13,9 +13,9 @@ c9 double precision, c10 real, c11 decimal(7, 4), c12 numeric(8, 4), c13 date, c14 datetime, c15 timestamp(14), c16 time, c17 year, c18 bit, c19 bool, c20 char, -c21 char(10), c22 varchar(30), c23 char(100), c24 char(100), -c25 char(100), c26 char(100), c27 char(100), c28 char(100), -c29 char(100), c30 char(100), c31 enum('one', 'two', 'three'), +c21 char(10), c22 varchar(30), c23 varchar(100), c24 varchar(100), +c25 varchar(100), c26 varchar(100), c27 varchar(100), c28 varchar(100), +c29 varchar(100), c30 varchar(100), c31 enum('one', 'two', 'three'), c32 set('monday', 'tuesday', 'wednesday'), primary key(c1) ) engine = 'HEAP' ; @@ -70,7 +70,7 @@ def test t9 t9 c18 c18 1 1 1 Y 32768 0 63 def test t9 t9 c19 c19 1 1 1 Y 32768 0 63 def test t9 t9 c20 c20 254 1 1 Y 0 0 8 -def test t9 t9 c21 c21 253 10 10 Y 0 0 8 +def test t9 t9 c21 c21 254 10 10 Y 0 0 8 def test t9 t9 c22 c22 253 30 30 Y 0 0 8 def test t9 t9 c23 c23 253 100 8 Y 0 0 8 def test t9 t9 c24 c24 253 100 8 Y 0 0 8 @@ -1689,8 +1689,8 @@ info: Records: 3 Duplicates: 0 Warnings: 0 select a,b from t2 order by a ; a b -3 duplicate -4 duplicate +3 duplicate +4 duplicate 103 three delete from t2 ; prepare stmt1 from ' insert into t2 (b,a) @@ -1761,11 +1761,11 @@ `param04` longtext, `const05` binary(3) NOT NULL default '', `param05` longblob, - `const06` varchar(10) NOT NULL default '', + `const06` char(10) NOT NULL default '', `param06` longtext, `const07` date default NULL, `param07` longblob, - `const08` varchar(19) NOT NULL default '', + `const08` char(19) NOT NULL default '', `param08` longtext, `const09` datetime default NULL, `param09` longblob, @@ -1791,11 +1791,11 @@ def test t5 t5 param04 param04 252 16777215 3 Y 16 0 8 def test t5 t5 const05 const05 254 3 3 N 129 0 63 def test t5 t5 param05 param05 252 16777215 3 Y 144 0 63 -def test t5 t5 const06 const06 253 10 10 N 1 0 8 +def test t5 t5 const06 const06 254 10 10 N 1 0 8 def test t5 t5 param06 param06 252 16777215 10 Y 16 0 8 def test t5 t5 const07 const07 10 10 10 Y 128 0 63 def test t5 t5 param07 param07 252 16777215 10 Y 144 0 63 -def test t5 t5 const08 const08 253 19 19 N 1 0 8 +def test t5 t5 const08 const08 254 19 19 N 1 0 8 def test t5 t5 param08 param08 252 16777215 19 Y 16 0 8 def test t5 t5 const09 const09 12 19 19 Y 128 0 63 def test t5 t5 param09 param09 252 16777215 19 Y 144 0 63 --- 1.11/mysql-test/r/ps_5merge.result 2004-11-11 19:54:00 +02:00 +++ 1.12/mysql-test/r/ps_5merge.result 2004-12-06 18:04:37 +02:00 @@ -112,7 +112,7 @@ def test t9 t9 c18 c18 1 1 1 Y 32768 0 63 def test t9 t9 c19 c19 1 1 1 Y 32768 0 63 def test t9 t9 c20 c20 254 1 1 Y 0 0 8 -def test t9 t9 c21 c21 253 10 10 Y 0 0 8 +def test t9 t9 c21 c21 254 10 10 Y 0 0 8 def test t9 t9 c22 c22 253 30 30 Y 0 0 8 def test t9 t9 c23 c23 252 255 8 Y 144 0 63 def test t9 t9 c24 c24 252 255 8 Y 16 0 8 @@ -1700,11 +1700,11 @@ `param04` longtext, `const05` binary(3) NOT NULL default '', `param05` longblob, - `const06` varchar(10) NOT NULL default '', + `const06` char(10) NOT NULL default '', `param06` longtext, `const07` date default NULL, `param07` longblob, - `const08` varchar(19) NOT NULL default '', + `const08` char(19) NOT NULL default '', `param08` longtext, `const09` datetime default NULL, `param09` longblob, @@ -1730,11 +1730,11 @@ def test t5 t5 param04 param04 252 16777215 3 Y 16 0 8 def test t5 t5 const05 const05 254 3 3 N 129 0 63 def test t5 t5 param05 param05 252 16777215 3 Y 144 0 63 -def test t5 t5 const06 const06 253 10 10 N 1 0 8 +def test t5 t5 const06 const06 254 10 10 N 1 0 8 def test t5 t5 param06 param06 252 16777215 10 Y 16 0 8 def test t5 t5 const07 const07 10 10 10 Y 128 0 63 def test t5 t5 param07 param07 252 16777215 10 Y 144 0 63 -def test t5 t5 const08 const08 253 19 19 N 1 0 8 +def test t5 t5 const08 const08 254 19 19 N 1 0 8 def test t5 t5 param08 param08 252 16777215 19 Y 16 0 8 def test t5 t5 const09 const09 12 19 19 Y 128 0 63 def test t5 t5 param09 param09 252 16777215 19 Y 144 0 63 @@ -3121,7 +3121,7 @@ def test t9 t9 c18 c18 1 1 1 Y 32768 0 63 def test t9 t9 c19 c19 1 1 1 Y 32768 0 63 def test t9 t9 c20 c20 254 1 1 Y 0 0 8 -def test t9 t9 c21 c21 253 10 10 Y 0 0 8 +def test t9 t9 c21 c21 254 10 10 Y 0 0 8 def test t9 t9 c22 c22 253 30 30 Y 0 0 8 def test t9 t9 c23 c23 252 255 8 Y 144 0 63 def test t9 t9 c24 c24 252 255 8 Y 16 0 8 @@ -4709,11 +4709,11 @@ `param04` longtext, `const05` binary(3) NOT NULL default '', `param05` longblob, - `const06` varchar(10) NOT NULL default '', + `const06` char(10) NOT NULL default '', `param06` longtext, `const07` date default NULL, `param07` longblob, - `const08` varchar(19) NOT NULL default '', + `const08` char(19) NOT NULL default '', `param08` longtext, `const09` datetime default NULL, `param09` longblob, @@ -4739,11 +4739,11 @@ def test t5 t5 param04 param04 252 16777215 3 Y 16 0 8 def test t5 t5 const05 const05 254 3 3 N 129 0 63 def test t5 t5 param05 param05 252 16777215 3 Y 144 0 63 -def test t5 t5 const06 const06 253 10 10 N 1 0 8 +def test t5 t5 const06 const06 254 10 10 N 1 0 8 def test t5 t5 param06 param06 252 16777215 10 Y 16 0 8 def test t5 t5 const07 const07 10 10 10 Y 128 0 63 def test t5 t5 param07 param07 252 16777215 10 Y 144 0 63 -def test t5 t5 const08 const08 253 19 19 N 1 0 8 +def test t5 t5 const08 const08 254 19 19 N 1 0 8 def test t5 t5 param08 param08 252 16777215 19 Y 16 0 8 def test t5 t5 const09 const09 12 19 19 Y 128 0 63 def test t5 t5 param09 param09 252 16777215 19 Y 144 0 63 --- 1.11/mysql-test/r/ps_6bdb.result 2004-11-11 19:54:00 +02:00 +++ 1.12/mysql-test/r/ps_6bdb.result 2004-12-06 18:04:37 +02:00 @@ -69,7 +69,7 @@ def test t9 t9 c18 c18 1 1 1 Y 32768 0 63 def test t9 t9 c19 c19 1 1 1 Y 32768 0 63 def test t9 t9 c20 c20 254 1 1 Y 0 0 8 -def test t9 t9 c21 c21 253 10 10 Y 0 0 8 +def test t9 t9 c21 c21 254 10 10 Y 0 0 8 def test t9 t9 c22 c22 253 30 30 Y 0 0 8 def test t9 t9 c23 c23 252 255 8 Y 144 0 63 def test t9 t9 c24 c24 252 255 8 Y 16 0 8 @@ -1688,8 +1688,8 @@ info: Records: 3 Duplicates: 0 Warnings: 0 select a,b from t2 order by a ; a b -3 duplicate -4 duplicate +3 duplicate +4 duplicate 103 three delete from t2 ; prepare stmt1 from ' insert into t2 (b,a) @@ -1760,11 +1760,11 @@ `param04` longtext, `const05` binary(3) NOT NULL default '', `param05` longblob, - `const06` varchar(10) NOT NULL default '', + `const06` char(10) NOT NULL default '', `param06` longtext, `const07` date default NULL, `param07` longblob, - `const08` varchar(19) NOT NULL default '', + `const08` char(19) NOT NULL default '', `param08` longtext, `const09` datetime default NULL, `param09` longblob, @@ -1790,11 +1790,11 @@ def test t5 t5 param04 param04 252 16777215 3 Y 16 0 8 def test t5 t5 const05 const05 254 3 3 N 129 0 63 def test t5 t5 param05 param05 252 16777215 3 Y 144 0 63 -def test t5 t5 const06 const06 253 10 10 N 1 0 8 +def test t5 t5 const06 const06 254 10 10 N 1 0 8 def test t5 t5 param06 param06 252 16777215 10 Y 16 0 8 def test t5 t5 const07 const07 10 10 10 Y 128 0 63 def test t5 t5 param07 param07 252 16777215 10 Y 144 0 63 -def test t5 t5 const08 const08 253 19 19 N 1 0 8 +def test t5 t5 const08 const08 254 19 19 N 1 0 8 def test t5 t5 param08 param08 252 16777215 19 Y 16 0 8 def test t5 t5 const09 const09 12 19 19 Y 128 0 63 def test t5 t5 param09 param09 252 16777215 19 Y 144 0 63 --- 1.8/mysql-test/t/ps_1general.test 2004-11-29 23:47:39 +02:00 +++ 1.9/mysql-test/t/ps_1general.test 2004-12-06 18:04:38 +02:00 @@ -317,7 +317,7 @@ execute stmt4; --enable_result_log prepare stmt4 from ' show full processlist '; ---replace_column 1 number +--replace_column 1 number 6 seconds execute stmt4; prepare stmt4 from ' show grants for user '; --error 1295 --- 1.2/mysql-test/r/select.result.es 2004-12-02 14:08:07 +02:00 +++ 1.3/mysql-test/r/select.result.es 2004-12-06 19:18:30 +02:00 @@ -1,5 +1,7 @@ drop table if exists t1,t2,t3,t4; drop table if exists t1_1,t1_2,t9_1,t9_2; +drop table if exists t1_1,t1_2,t9_1,t9_2; +drop view if exists v1; CREATE TABLE t1 ( Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL, Varor_period smallint(4) unsigned DEFAULT '0' NOT NULL @@ -2079,10 +2081,8 @@ SELECT a.gvid, (SUM(CASE b.sampletid WHEN 140 THEN b.samplevalue ELSE 0 END)) as the_success,(SUM(CASE b.sampletid WHEN 141 THEN b.samplevalue ELSE 0 END)) as the_fail,(SUM(CASE b.sampletid WHEN 142 THEN b.samplevalue ELSE 0 END)) as the_size,(SUM(CASE b.sampletid WHEN 143 THEN b.samplevalue ELSE 0 END)) as the_time FROM t1 a, t2 b WHERE a.hmid = b.hmid AND a.volid = b.volid AND b.sampletime >= 'wrong-date-value' AND b.sampletime < 'wrong-date-value' AND b.sampletid IN (140, 141, 142, 143) GROUP BY a.gvid; gvid the_success the_fail the_size the_time Warnings: -Warning 1292 Truncated incorrect datetime value: 'wrong-date-value' -Warning 1292 Truncated incorrect datetime value: 'wrong-date-value' -Warning 1292 Truncated incorrect datetime value: 'wrong-date-value' -Warning 1292 Truncated incorrect datetime value: 'wrong-date-value' +Warning 1292 Incorrect datetime value: 'wrong-date-value' for column 'sampletime' at row 1 +Warning 1292 Incorrect datetime value: 'wrong-date-value' for column 'sampletime' at row 1 SELECT a.gvid, (SUM(CASE b.sampletid WHEN 140 THEN b.samplevalue ELSE 0 END)) as the_success,(SUM(CASE b.sampletid WHEN 141 THEN b.samplevalue ELSE 0 END)) as the_fail,(SUM(CASE b.sampletid WHEN 142 THEN b.samplevalue ELSE 0 END)) as the_size,(SUM(CASE b.sampletid WHEN 143 THEN b.samplevalue ELSE 0 END)) as the_time FROM t1 a, t2 b WHERE a.hmid = b.hmid AND a.volid = b.volid AND b.sampletime >= NULL AND b.sampletime < NULL AND b.sampletid IN (140, 141, 142, 143) GROUP BY a.gvid; gvid the_success the_fail the_size the_time DROP TABLE t1,t2; @@ -2345,7 +2345,7 @@ s select * from t3 where s = 'one'; s -one +one select * from t1,t2 where t1.s = t2.s; s s two two --- 1.11/ndb/src/common/util/NdbSqlUtil.cpp 2004-11-18 12:48:59 +02:00 +++ 1.12/ndb/src/common/util/NdbSqlUtil.cpp 2004-12-06 18:04:38 +02:00 @@ -410,7 +410,7 @@ CHARSET_INFO* cs = (CHARSET_INFO*)(info); // length in bytes including null padding to Uint32 uint l1 = (full << 2); - int k = (*cs->coll->strnncollsp)(cs, u1.v, l1, u2.v, l1); + int k = (*cs->coll->strnncollsp)(cs, u1.v, l1, u2.v, l1, 0); return k < 0 ? -1 : k > 0 ? +1 : 0; } @@ -559,7 +559,7 @@ CHARSET_INFO* cs = (CHARSET_INFO*)(info); // length in bytes including null padding to Uint32 uint l1 = (full << 2); - int k = (*cs->coll->strnncollsp)(cs, u1.v, l1, u2.v, l1); + int k = (*cs->coll->strnncollsp)(cs, u1.v, l1, u2.v, l1,0); return k < 0 ? -1 : k > 0 ? +1 : 0; } return CmpUnknown; --- 1.120/sql/ha_ndbcluster.cc 2004-11-30 19:58:14 +02:00 +++ 1.121/sql/ha_ndbcluster.cc 2004-12-06 18:04:38 +02:00 @@ -406,6 +406,7 @@ return TRUE; case MYSQL_TYPE_NULL: case MYSQL_TYPE_GEOMETRY: + case MYSQL_TYPE_VARCHAR: break; } return FALSE; @@ -1843,7 +1844,7 @@ (new_row[key_part->null_offset] & key_part->null_bit)) return 1; } - if (key_part->key_part_flag & (HA_BLOB_PART | HA_VAR_LENGTH)) + if (key_part->key_part_flag & (HA_BLOB_PART | HA_VAR_LENGTH_PART)) { if (key_part->field->cmp_binary((char*) (old_row + key_part->offset), @@ -3774,6 +3775,7 @@ m_table_flags(HA_REC_NOT_IN_SEQ | HA_NULL_IN_KEY | HA_AUTO_PART_KEY | + HA_NO_VARCHAR | HA_NO_PREFIX_CHAR_KEYS), m_share(0), m_use_write(FALSE), --- 1.26/mysql-test/r/heap.result 2004-12-06 02:05:20 +02:00 +++ 1.27/mysql-test/r/heap.result 2004-12-06 19:18:30 +02:00 @@ -1,4 +1,4 @@ -drop table if exists t1; +drop table if exists t1,t2,t3; create table t1 (a int not null,b int not null, primary key (a)) engine=heap comment="testing heaps" avg_row_length=100 min_rows=1 max_rows=100; insert into t1 values(1,1),(2,2),(3,3),(4,4); delete from t1 where a=1 or a=0; @@ -249,3 +249,421 @@ 3 2 drop table t1; +set storage_engine=HEAP; +create table t1 (v varchar(10), c char(10), t varchar(50)); +insert into t1 values('+ ', '+ ', '+ '); +set @a=repeat(' ',20); +insert into t1 values (concat('+',@a),concat('+',@a),concat('+',@a)); +Warnings: +Warning 1265 Data truncated for column 'v' at row 1 +select concat('*',v,'*',c,'*',t,'*') from t1; +concat('*',v,'*',c,'*',t,'*') +*+ *+*+ * +*+ *+*+ * +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` varchar(10) default NULL, + `c` char(10) default NULL, + `t` varchar(50) default NULL +) ENGINE=HEAP DEFAULT CHARSET=latin1 +create table t2 like t1; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `v` varchar(10) default NULL, + `c` char(10) default NULL, + `t` varchar(50) default NULL +) ENGINE=HEAP DEFAULT CHARSET=latin1 +create table t3 select * from t1; +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `v` varchar(10) default NULL, + `c` char(10) default NULL, + `t` varchar(50) default NULL +) ENGINE=HEAP DEFAULT CHARSET=latin1 +alter table t1 modify c varchar(10); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` varchar(10) default NULL, + `c` varchar(10) default NULL, + `t` varchar(50) default NULL +) ENGINE=HEAP DEFAULT CHARSET=latin1 +alter table t1 modify v char(10); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` char(10) default NULL, + `c` varchar(10) default NULL, + `t` varchar(50) default NULL +) ENGINE=HEAP DEFAULT CHARSET=latin1 +alter table t1 modify t varchar(10); +Warnings: +Warning 1265 Data truncated for column 't' at row 2 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` char(10) default NULL, + `c` varchar(10) default NULL, + `t` varchar(10) default NULL +) ENGINE=HEAP DEFAULT CHARSET=latin1 +select concat('*',v,'*',c,'*',t,'*') from t1; +concat('*',v,'*',c,'*',t,'*') +*+*+*+ * +*+*+*+ * +drop table t1,t2,t3; +create table t1 (v varchar(10), c char(10), t varchar(50), key(v), key(c), key(t(10))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` varchar(10) default NULL, + `c` char(10) default NULL, + `t` varchar(50) default NULL, + KEY `v` (`v`), + KEY `c` (`c`), + KEY `t` (`t`(10)) +) ENGINE=HEAP DEFAULT CHARSET=latin1 +select count(*) from t1; +count(*) +270 +insert into t1 values(concat('a',char(1)),concat('a',char(1)),concat('a',char(1))); +select count(*) from t1 where v='a'; +count(*) +10 +select count(*) from t1 where c='a'; +count(*) +10 +select count(*) from t1 where t='a'; +count(*) +10 +select count(*) from t1 where v='a '; +count(*) +10 +select count(*) from t1 where c='a '; +count(*) +10 +select count(*) from t1 where t='a '; +count(*) +10 +select count(*) from t1 where v between 'a' and 'a '; +count(*) +10 +select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; +count(*) +10 +select count(*) from t1 where v like 'a%'; +count(*) +11 +select count(*) from t1 where c like 'a%'; +count(*) +11 +select count(*) from t1 where t like 'a%'; +count(*) +11 +select count(*) from t1 where v like 'a %'; +count(*) +9 +explain select count(*) from t1 where v='a '; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref v v 13 const 10 Using where +explain select count(*) from t1 where c='a '; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref c c 11 const 10 Using where +explain select count(*) from t1 where t='a '; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref t t 13 const 10 Using where +explain select count(*) from t1 where v like 'a%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL v NULL NULL NULL 271 Using where +explain select count(*) from t1 where v between 'a' and 'a '; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL v NULL NULL NULL 271 Using where +explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL v NULL NULL NULL 271 Using where +alter table t1 add unique(v); +ERROR 23000: Duplicate entry '{ ' for key 1 +alter table t1 add key(v); +select concat('*',v,'*',c,'*',t,'*') as qq from t1 where v='a'; +qq +*a *a*a * +*a *a*a * +*a *a*a * +*a *a*a * +*a *a*a * +*a *a*a * +*a *a*a * +*a *a*a * +*a *a*a * +*a*a*a* +explain select * from t1 where v='a'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref v,v_2 v 13 const 10 Using where +select v,count(*) from t1 group by v limit 10; +v count(*) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select v,count(t) from t1 group by v limit 10; +v count(t) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select v,count(c) from t1 group by v limit 10; +v count(c) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select sql_big_result v,count(t) from t1 group by v limit 10; +v count(t) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select sql_big_result v,count(c) from t1 group by v limit 10; +v count(c) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select c,count(*) from t1 group by c limit 10; +c count(*) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select c,count(t) from t1 group by c limit 10; +c count(t) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select sql_big_result c,count(t) from t1 group by c limit 10; +c count(t) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select t,count(*) from t1 group by t limit 10; +t count(*) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select t,count(t) from t1 group by t limit 10; +t count(t) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select sql_big_result t,count(t) from t1 group by t limit 10; +t count(t) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +drop table t1; +create table t1 (a char(10), unique (a)); +insert into t1 values ('a'); +insert into t1 values ('a '); +ERROR 23000: Duplicate entry 'a' for key 1 +alter table t1 modify a varchar(10); +insert into t1 values ('a '),('a '),('a '),('a '); +ERROR 23000: Duplicate entry 'a ' for key 1 +insert into t1 values ('a '); +ERROR 23000: Duplicate entry 'a ' for key 1 +insert into t1 values ('a '); +ERROR 23000: Duplicate entry 'a ' for key 1 +insert into t1 values ('a '); +ERROR 23000: Duplicate entry 'a ' for key 1 +update t1 set a='a ' where a like 'a '; +update t1 set a='a ' where a like 'a '; +drop table t1; +create table t1 (v varchar(10), c char(10), t varchar(50), key using btree (v), key using btree (c), key using btree (t(10))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` varchar(10) default NULL, + `c` char(10) default NULL, + `t` varchar(50) default NULL, + KEY `v` TYPE BTREE (`v`), + KEY `c` TYPE BTREE (`c`), + KEY `t` TYPE BTREE (`t`(10)) +) ENGINE=HEAP DEFAULT CHARSET=latin1 +select count(*) from t1; +count(*) +270 +insert into t1 values(concat('a',char(1)),concat('a',char(1)),concat('a',char(1))); +select count(*) from t1 where v='a'; +count(*) +10 +select count(*) from t1 where c='a'; +count(*) +10 +select count(*) from t1 where t='a'; +count(*) +10 +select count(*) from t1 where v='a '; +count(*) +10 +select count(*) from t1 where c='a '; +count(*) +10 +select count(*) from t1 where t='a '; +count(*) +10 +select count(*) from t1 where v between 'a' and 'a '; +count(*) +10 +select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; +count(*) +10 +explain select count(*) from t1 where v='a '; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref v v 13 const # Using where +explain select count(*) from t1 where c='a '; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref c c 11 const # Using where +explain select count(*) from t1 where t='a '; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref t t 13 const # Using where +explain select count(*) from t1 where v like 'a%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 13 NULL # Using where +explain select count(*) from t1 where v between 'a' and 'a '; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 13 NULL # Using where +explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 13 NULL # Using where +alter table t1 add unique(v); +ERROR 23000: Duplicate entry '{ ' for key 1 +alter table t1 add key(v); +select concat('*',v,'*',c,'*',t,'*') as qq from t1 where v='a'; +qq +*a*a*a* +*a *a*a * +*a *a*a * +*a *a*a * +*a *a*a * +*a *a*a * +*a *a*a * +*a *a*a * +*a *a*a * +*a *a*a * +explain select * from t1 where v='a'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref v,v_2 v 13 const 7 Using where +drop table t1; +create table t1 (a char(10), unique using btree (a)) engine=heap; +insert into t1 values ('a'); +insert into t1 values ('a '); +ERROR 23000: Duplicate entry 'a' for key 1 +alter table t1 modify a varchar(10); +insert into t1 values ('a '),('a '),('a '),('a '); +ERROR 23000: Duplicate entry 'a ' for key 1 +insert into t1 values ('a '); +ERROR 23000: Duplicate entry 'a ' for key 1 +insert into t1 values ('a '); +ERROR 23000: Duplicate entry 'a ' for key 1 +insert into t1 values ('a '); +ERROR 23000: Duplicate entry 'a ' for key 1 +update t1 set a='a ' where a like 'a '; +update t1 set a='a ' where a like 'a '; +drop table t1; +create table t1 (v varchar(10), c char(10), t varchar(50), key(v(5)), key(c(5)), key(t(5))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` varchar(10) default NULL, + `c` char(10) default NULL, + `t` varchar(50) default NULL, + KEY `v` (`v`(5)), + KEY `c` (`c`(5)), + KEY `t` (`t`(5)) +) ENGINE=HEAP DEFAULT CHARSET=latin1 +drop table t1; +create table t1 (v varchar(65530), key(v(10))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` varchar(65530) default NULL, + KEY `v` (`v`(10)) +) ENGINE=HEAP DEFAULT CHARSET=latin1 +insert into t1 values(repeat('a',65530)); +select length(v) from t1 where v=repeat('a',65530); +length(v) +65530 +drop table t1; +set storage_engine=MyISAM; --- 1.84/mysql-test/r/innodb.result 2004-12-06 17:15:48 +02:00 +++ 1.85/mysql-test/r/innodb.result 2004-12-06 19:18:30 +02:00 @@ -1421,19 +1421,19 @@ insert t3 select * from t1; checksum table t1, t2, t3, t4 quick; Table Checksum -test.t1 968604391 +test.t1 272226711 test.t2 NULL test.t3 NULL test.t4 NULL checksum table t1, t2, t3, t4; Table Checksum -test.t1 968604391 +test.t1 272226711 test.t2 968604391 test.t3 968604391 test.t4 NULL checksum table t1, t2, t3, t4 extended; Table Checksum -test.t1 968604391 +test.t1 272226711 test.t2 968604391 test.t3 968604391 test.t4 NULL @@ -1700,3 +1700,5 @@ show status like "Innodb_rows_updated"; Variable_name Value Innodb_rows_updated 29530 +create table t1 (v varchar(16384)) engine=innodb; +ERROR 42000: Column length too big for column 'v' (max = 255); use BLOB instead --- 1.45/mysql-test/r/order_by.result 2004-11-25 18:02:36 +02:00 +++ 1.46/mysql-test/r/order_by.result 2004-12-06 18:04:37 +02:00 @@ -272,7 +272,7 @@ insert into t1 values (1, NULL, NULL), (1, NULL, 'b'), (1, 1, NULL), (1, 1, 'b'), (1, 1, 'b'), (2, 1, 'a'), (2, 1, 'b'), (2, 2, 'a'), (2, 2, 'b'), (2, 3, 'c'),(1,3,'b'); explain select * from t1 where (a = 1 and b is null and c = 'b') or (a > 2) order by a desc; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index a a 20 NULL 11 Using where; Using index +1 SIMPLE t1 index a a 22 NULL 11 Using where; Using index select * from t1 where (a = 1 and b is null and c = 'b') or (a > 2) order by a desc; a b c 1 NULL b @@ -348,7 +348,7 @@ Warning 1265 Data truncated for column 'c' at row 3 explain select * from t1 order by a, b, c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL a 18 NULL 11 Using index +1 SIMPLE t1 index NULL a 20 NULL 11 Using index select * from t1 order by a, b, c; a b c 1 0 @@ -364,7 +364,7 @@ 2 3 c explain select * from t1 order by a desc, b desc, c desc; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL a 18 NULL 11 Using index +1 SIMPLE t1 index NULL a 20 NULL 11 Using index select * from t1 order by a desc, b desc, c desc; a b c 2 3 c @@ -380,7 +380,7 @@ 1 0 explain select * from t1 where (a = 1 and b = 1 and c = 'b') or (a > 2) order by a desc; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 18 NULL 3 Using where; Using index +1 SIMPLE t1 range a a 20 NULL 3 Using where; Using index select * from t1 where (a = 1 and b = 1 and c = 'b') or (a > 2) order by a desc; a b c 1 1 b @@ -574,7 +574,7 @@ INSERT INTO t1 VALUES ('0',3,'0'),('0',2,'1'),('0',1,'2'),('1',2,'1'),('1',1,'3'), ('1',0,'2'),('2',3,'0'),('2',2,'1'),('2',1,'2'),('2',3,'0'),('2',2,'1'),('2',1,'2'),('3',2,'1'),('3',1,'2'),('3','3','3'); EXPLAIN SELECT * FROM t1 WHERE FieldKey = '1' ORDER BY LongVal; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref FieldKey,LongField,StringField LongField 36 const 3 Using where +1 SIMPLE t1 ref FieldKey,LongField,StringField LongField 38 const 3 Using where SELECT * FROM t1 WHERE FieldKey = '1' ORDER BY LongVal; FieldKey LongVal StringVal 1 0 2 @@ -582,7 +582,7 @@ 1 2 1 EXPLAIN SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY LongVal; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range FieldKey,LongField,StringField FieldKey 36 NULL 4 Using where; Using filesort +1 SIMPLE t1 range FieldKey,LongField,StringField FieldKey 38 NULL 4 Using where; Using filesort SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY LongVal; FieldKey LongVal StringVal 3 1 2 @@ -590,7 +590,7 @@ 3 3 3 EXPLAIN SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY FieldKey, LongVal; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range FieldKey,LongField,StringField LongField 36 NULL 4 Using where +1 SIMPLE t1 range FieldKey,LongField,StringField LongField 38 NULL 4 Using where SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY FieldKey, LongVal; FieldKey LongVal StringVal 3 1 2 --- 1.43/mysql-test/r/select.result 2004-11-28 21:41:57 +02:00 +++ 1.44/mysql-test/r/select.result 2004-12-06 18:04:37 +02:00 @@ -2313,7 +2313,7 @@ s select * from t3 where s = 'one'; s -one +one select * from t1,t2 where t1.s = t2.s; s s two two --- 1.42/mysql-test/r/type_blob.result 2004-11-22 21:54:42 +02:00 +++ 1.43/mysql-test/r/type_blob.result 2004-12-06 18:04:37 +02:00 @@ -4,17 +4,19 @@ Field Type Null Key Default Extra a blob YES NULL b text YES NULL -c blob YES NULL +c tinyblob YES NULL d mediumtext YES NULL e longtext YES NULL -CREATE TABLE t2 (a char(257), b varbinary(70000), c varchar(70000000)); +CREATE TABLE t2 (a char(255), b varbinary(70000), c varchar(70000000)); Warnings: -Note 1246 Converting column 'a' from CHAR to TEXT -Note 1246 Converting column 'b' from CHAR to BLOB -Note 1246 Converting column 'c' from CHAR to TEXT +Note 1246 Converting column 'b' from VARCHAR to BLOB +Note 1246 Converting column 'c' from VARCHAR to TEXT +CREATE TABLE t4 (c varchar(65530) character set utf8 not null); +Warnings: +Note 1246 Converting column 'c' from VARCHAR to TEXT show columns from t2; Field Type Null Key Default Extra -a text YES NULL +a char(255) YES NULL b mediumblob YES NULL c longtext YES NULL create table t3 (a long, b long byte); @@ -24,10 +26,18 @@ `a` mediumtext, `b` mediumblob ) ENGINE=MyISAM DEFAULT CHARSET=latin1 -drop table t1,t2,t3 -#; +show create TABLE t4; +Table Create Table +t4 CREATE TABLE `t4` ( + `c` mediumtext character set utf8 NOT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1,t2,t3,t4; CREATE TABLE t1 (a char(257) default "hello"); ERROR 42000: Column length too big for column 'a' (max = 255); use BLOB instead +CREATE TABLE t2 (a char(256)); +ERROR 42000: Column length too big for column 'a' (max = 255); use BLOB instead +CREATE TABLE t1 (a varchar(70000) default "hello"); +ERROR 42000: Column length too big for column 'a' (max = 65535); use BLOB instead CREATE TABLE t2 (a blob default "hello"); ERROR 42000: BLOB/TEXT column 'a' can't have a default value drop table if exists t1,t2; @@ -71,16 +81,16 @@ show full fields from t1; Field Type Collation Null Key Default Extra Privileges Comment t text latin1_swedish_ci YES NULL select,insert,update,references -c varchar(10) latin1_swedish_ci YES NULL select,insert,update,references +c char(10) latin1_swedish_ci YES NULL select,insert,update,references b blob NULL YES NULL select,insert,update,references -d varbinary(10) NULL YES NULL select,insert,update,references +d binary(10) NULL YES NULL select,insert,update,references lock tables t1 WRITE; show full fields from t1; Field Type Collation Null Key Default Extra Privileges Comment t text latin1_swedish_ci YES NULL select,insert,update,references -c varchar(10) latin1_swedish_ci YES NULL select,insert,update,references +c char(10) latin1_swedish_ci YES NULL select,insert,update,references b blob NULL YES NULL select,insert,update,references -d varbinary(10) NULL YES NULL select,insert,update,references +d binary(10) NULL YES NULL select,insert,update,references unlock tables; select t from t1 where t like "hello"; t @@ -520,6 +530,11 @@ drop table t1; create table t1 (id integer primary key auto_increment, txt text not null, unique index txt_index (txt (20))); insert into t1 (txt) values ('Chevy'), ('Chevy '); +ERROR 23000: Duplicate entry 'Chevy ' for key 2 +insert into t1 (txt) values ('Chevy'), ('CHEVY'); +ERROR 23000: Duplicate entry 'Chevy' for key 2 +alter table t1 drop index txt_index, add index txt_index (txt(20)); +insert into t1 (txt) values ('Chevy '); select * from t1 where txt='Chevy'; id txt 1 Chevy @@ -589,7 +604,7 @@ 2 Chevy 3 Ford drop table t1; -create table t1 (id integer primary key auto_increment, txt text, unique index txt_index (txt (20))); +create table t1 (id integer primary key auto_increment, txt text, index txt_index (txt (20))); insert into t1 (txt) values ('Chevy'), ('Chevy '), (NULL); select * from t1 where txt='Chevy' or txt is NULL; id txt --- 1.19/mysql-test/t/heap.test 2004-12-02 13:06:11 +02:00 +++ 1.20/mysql-test/t/heap.test 2004-12-06 19:18:30 +02:00 @@ -3,7 +3,7 @@ # --disable_warnings -drop table if exists t1; +drop table if exists t1,t2,t3; --enable_warnings create table t1 (a int not null,b int not null, primary key (a)) engine=heap comment="testing heaps" avg_row_length=100 min_rows=1 max_rows=100; @@ -195,3 +195,214 @@ insert into t1 values ('2'), ('3'); select * from t1; drop table t1; + +# +# Test varchar +# We can't use varchar.inc becasue heap doesn't support blob's +# + +let $default=`select @@storage_engine`; +set storage_engine=HEAP; + +# +# Simple basic test that endspace is saved +# + +create table t1 (v varchar(10), c char(10), t varchar(50)); +insert into t1 values('+ ', '+ ', '+ '); +set @a=repeat(' ',20); +insert into t1 values (concat('+',@a),concat('+',@a),concat('+',@a)); +select concat('*',v,'*',c,'*',t,'*') from t1; + +# Check how columns are copied +show create table t1; +create table t2 like t1; +show create table t2; +create table t3 select * from t1; +show create table t3; +alter table t1 modify c varchar(10); +show create table t1; +alter table t1 modify v char(10); +show create table t1; +alter table t1 modify t varchar(10); +show create table t1; +select concat('*',v,'*',c,'*',t,'*') from t1; +drop table t1,t2,t3; + +# +# Testing of keys +# +create table t1 (v varchar(10), c char(10), t varchar(50), key(v), key(c), key(t(10))); +show create table t1; +disable_query_log; +let $1=10; +while ($1) +{ + let $2=27; + eval set @space=repeat(' ',10-$1); + while ($2) + { + eval set @char=char(ascii('a')+$2-1); + insert into t1 values(concat(@char,@space),concat(@char,@space),concat(@char,@space)); + dec $2; + } + dec $1; +} +enable_query_log; +select count(*) from t1; +insert into t1 values(concat('a',char(1)),concat('a',char(1)),concat('a',char(1))); +select count(*) from t1 where v='a'; +select count(*) from t1 where c='a'; +select count(*) from t1 where t='a'; +select count(*) from t1 where v='a '; +select count(*) from t1 where c='a '; +select count(*) from t1 where t='a '; +select count(*) from t1 where v between 'a' and 'a '; +select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; +select count(*) from t1 where v like 'a%'; +select count(*) from t1 where c like 'a%'; +select count(*) from t1 where t like 'a%'; +select count(*) from t1 where v like 'a %'; +explain select count(*) from t1 where v='a '; +explain select count(*) from t1 where c='a '; +explain select count(*) from t1 where t='a '; +explain select count(*) from t1 where v like 'a%'; +explain select count(*) from t1 where v between 'a' and 'a '; +explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; + +--error 1062 +alter table t1 add unique(v); +alter table t1 add key(v); +select concat('*',v,'*',c,'*',t,'*') as qq from t1 where v='a'; +explain select * from t1 where v='a'; + +# GROUP BY + +select v,count(*) from t1 group by v limit 10; +select v,count(t) from t1 group by v limit 10; +select v,count(c) from t1 group by v limit 10; +select sql_big_result v,count(t) from t1 group by v limit 10; +select sql_big_result v,count(c) from t1 group by v limit 10; +select c,count(*) from t1 group by c limit 10; +select c,count(t) from t1 group by c limit 10; +select sql_big_result c,count(t) from t1 group by c limit 10; +select t,count(*) from t1 group by t limit 10; +select t,count(t) from t1 group by t limit 10; +select sql_big_result t,count(t) from t1 group by t limit 10; +drop table t1; + +# +# Test unique keys +# + +create table t1 (a char(10), unique (a)); +insert into t1 values ('a'); +--error 1062 +insert into t1 values ('a '); + +alter table t1 modify a varchar(10); +--error 1062 +insert into t1 values ('a '),('a '),('a '),('a '); +--error 1062 +insert into t1 values ('a '); +--error 1062 +insert into t1 values ('a '); +--error 1062 +insert into t1 values ('a '); +update t1 set a='a ' where a like 'a '; +update t1 set a='a ' where a like 'a '; +drop table t1; + +# +# Testing of btree keys +# + +create table t1 (v varchar(10), c char(10), t varchar(50), key using btree (v), key using btree (c), key using btree (t(10))); +show create table t1; +disable_query_log; +let $1=10; +while ($1) +{ + let $2=27; + eval set @space=repeat(' ',10-$1); + while ($2) + { + eval set @char=char(ascii('a')+$2-1); + insert into t1 values(concat(@char,@space),concat(@char,@space),concat(@char,@space)); + dec $2; + } + dec $1; +} +enable_query_log; +select count(*) from t1; +insert into t1 values(concat('a',char(1)),concat('a',char(1)),concat('a',char(1))); +select count(*) from t1 where v='a'; +select count(*) from t1 where c='a'; +select count(*) from t1 where t='a'; +select count(*) from t1 where v='a '; +select count(*) from t1 where c='a '; +select count(*) from t1 where t='a '; +select count(*) from t1 where v between 'a' and 'a '; +--replace_column 9 # +select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; +--replace_column 9 # +explain select count(*) from t1 where v='a '; +--replace_column 9 # +explain select count(*) from t1 where c='a '; +--replace_column 9 # +explain select count(*) from t1 where t='a '; +--replace_column 9 # +explain select count(*) from t1 where v like 'a%'; +--replace_column 9 # +explain select count(*) from t1 where v between 'a' and 'a '; +--replace_column 9 # +explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; + +--error 1062 +alter table t1 add unique(v); +alter table t1 add key(v); +select concat('*',v,'*',c,'*',t,'*') as qq from t1 where v='a'; +explain select * from t1 where v='a'; + +drop table t1; + +# +# Test unique btree keys +# + +create table t1 (a char(10), unique using btree (a)) engine=heap; +insert into t1 values ('a'); +--error 1062 +insert into t1 values ('a '); + +alter table t1 modify a varchar(10); +--error 1062 +insert into t1 values ('a '),('a '),('a '),('a '); +--error 1062 +insert into t1 values ('a '); +--error 1062 +insert into t1 values ('a '); +--error 1062 +insert into t1 values ('a '); +update t1 set a='a ' where a like 'a '; +update t1 set a='a ' where a like 'a '; +drop table t1; + +# +# test show create table +# + +create table t1 (v varchar(10), c char(10), t varchar(50), key(v(5)), key(c(5)), key(t(5))); +show create table t1; +drop table t1; + +create table t1 (v varchar(65530), key(v(10))); +show create table t1; +insert into t1 values(repeat('a',65530)); +select length(v) from t1 where v=repeat('a',65530); +drop table t1; + +# +# Reset varchar test +# +eval set storage_engine=$default; --- 1.67/mysql-test/t/innodb.test 2004-11-22 22:33:09 +02:00 +++ 1.68/mysql-test/t/innodb.test 2004-12-06 19:18:30 +02:00 @@ -1210,3 +1210,15 @@ show status like "Innodb_rows_inserted"; show status like "Innodb_rows_read"; show status like "Innodb_rows_updated"; +# +# Test varchar +# + +#let $default=`select @@storage_engine`; +#set storage_engine=INNODB; +#source include/varchar.inc; +#eval set storage_engine=$default; + +# InnoDB specific varchar tests +--error 1074 +create table t1 (v varchar(16384)) engine=innodb; --- 1.23/mysql-test/t/type_blob.test 2004-11-22 20:06:53 +02:00 +++ 1.24/mysql-test/t/type_blob.test 2004-12-06 18:04:38 +02:00 @@ -18,12 +18,14 @@ show columns from t1; # PS doesn't give errors on prepare yet --disable_ps_protocol -CREATE TABLE t2 (a char(257), b varbinary(70000), c varchar(70000000)); +CREATE TABLE t2 (a char(255), b varbinary(70000), c varchar(70000000)); +CREATE TABLE t4 (c varchar(65530) character set utf8 not null); --enable_ps_protocol show columns from t2; create table t3 (a long, b long byte); show create TABLE t3; -drop table t1,t2,t3 +show create TABLE t4; +drop table t1,t2,t3,t4; # # Check errors with blob @@ -31,6 +33,10 @@ --error 1074 CREATE TABLE t1 (a char(257) default "hello"); +--error 1074 +CREATE TABLE t2 (a char(256)); +--error 1074 +CREATE TABLE t1 (a varchar(70000) default "hello"); --error 1101 CREATE TABLE t2 (a blob default "hello"); @@ -316,10 +322,16 @@ # # Test blob's with end space (Bug #1651) +# This is a bit changed since we now have true varchar # create table t1 (id integer primary key auto_increment, txt text not null, unique index txt_index (txt (20))); +--error 1062 insert into t1 (txt) values ('Chevy'), ('Chevy '); +--error 1062 +insert into t1 (txt) values ('Chevy'), ('CHEVY'); +alter table t1 drop index txt_index, add index txt_index (txt(20)); +insert into t1 (txt) values ('Chevy '); select * from t1 where txt='Chevy'; select * from t1 where txt='Chevy '; select * from t1 where txt='Chevy ' or txt='Chevy'; @@ -340,7 +352,7 @@ select * from t1 where txt >= 'Chevy'; drop table t1; -create table t1 (id integer primary key auto_increment, txt text, unique index txt_index (txt (20))); +create table t1 (id integer primary key auto_increment, txt text, index txt_index (txt (20))); insert into t1 (txt) values ('Chevy'), ('Chevy '), (NULL); select * from t1 where txt='Chevy' or txt is NULL; explain select * from t1 where txt='Chevy' or txt is NULL; --- 1.127/sql/ha_innodb.cc 2004-12-03 17:57:37 +02:00 +++ 1.128/sql/ha_innodb.cc 2004-12-06 18:04:38 +02:00 @@ -2010,11 +2010,12 @@ switch (mysql_tp) { case FIELD_TYPE_STRING: - case FIELD_TYPE_VAR_STRING: + case MYSQL_TYPE_VAR_STRING: case FIELD_TYPE_TINY_BLOB: case FIELD_TYPE_MEDIUM_BLOB: case FIELD_TYPE_BLOB: case FIELD_TYPE_LONG_BLOB: + case MYSQL_TYPE_VARCHAR: /* Use the charset number to pick the right charset struct for the comparison. Since the MySQL function get_charset may be slow before Bar removes the mutex operation there, we first @@ -2042,7 +2043,7 @@ ret = charset->coll->strnncollsp(charset, a, a_length, - b, b_length); + b, b_length, 0); if (ret < 0) { return(-1); } else if (ret > 0) { @@ -2071,17 +2072,11 @@ 8 bits: this is used in ibuf and also when DATA_NOT_NULL is ORed to the type */ - DBUG_ASSERT((ulint)FIELD_TYPE_STRING < 256); - DBUG_ASSERT((ulint)FIELD_TYPE_VAR_STRING < 256); - DBUG_ASSERT((ulint)FIELD_TYPE_DOUBLE < 256); - DBUG_ASSERT((ulint)FIELD_TYPE_FLOAT < 256); - DBUG_ASSERT((ulint)FIELD_TYPE_DECIMAL < 256); - switch (field->type()) { /* NOTE that we only allow string types in DATA_MYSQL and DATA_VARMYSQL */ - case FIELD_TYPE_VAR_STRING: if (field->binary()) { - + case MYSQL_TYPE_VAR_STRING: + case MYSQL_TYPE_VARCHAR: if (field->binary()) { return(DATA_BINARY); } else if (strcmp( field->charset()->name, @@ -2648,12 +2643,12 @@ if (len == UNIV_SQL_NULL) { data = NULL; - } else if (col_type == DATA_VARCHAR || col_type == DATA_BINARY - || col_type == DATA_VARMYSQL) { - /* Remove trailing spaces */ - while (len > 0 && data[len - 1] == ' ') { - len--; - } + } else if (col_type == DATA_VARCHAR || col_type == DATA_BINARY + || col_type == DATA_VARMYSQL) { + /* Remove trailing spaces */ + while (len > 0 && data[len - 1] == ' ') { + len--; + } } else if (col_type == DATA_INT) { /* Store integer data in InnoDB in a big-endian format, sign bit negated, if signed */ --- 1.72/sql/ha_innodb.h 2004-11-30 12:05:18 +02:00 +++ 1.73/sql/ha_innodb.h 2004-12-06 18:04:38 +02:00 @@ -84,6 +84,7 @@ HA_CAN_SQL_HANDLER | HA_NOT_EXACT_COUNT | HA_PRIMARY_KEY_IN_READ_INDEX | + HA_NO_VARCHAR | HA_TABLE_SCAN_ON_INDEX), last_dup_key((uint) -1), start_of_scan(0), --- 1.47/mysql-test/r/myisam.result 2004-11-22 21:54:41 +02:00 +++ 1.48/mysql-test/r/myisam.result 2004-12-06 18:04:37 +02:00 @@ -408,8 +408,8 @@ test.t1 repair status OK select concat(a,'.') from t1 where a='aaa'; concat(a,'.') -aaa. aaa . +aaa. select concat(a,'.') from t1 where binary a='aaa'; concat(a,'.') aaa. @@ -461,20 +461,27 @@ a . drop table t1; create table t1 (a int not null auto_increment primary key, b text not null, unique b (b(20))); -insert into t1 (b) values ('a'),('a '),('a '); +insert into t1 (b) values ('a'),('b'),('c'); select concat(b,'.') from t1; concat(b,'.') a. -a . -a . +b. +c. update t1 set b='b ' where a=2; update t1 set b='b ' where a > 1; ERROR 23000: Duplicate entry 'b ' for key 2 +insert into t1 (b) values ('b'); +ERROR 23000: Duplicate entry 'b' for key 2 +select * from t1; +a b +1 a +2 b +3 c delete from t1 where b='b'; select a,concat(b,'.') from t1; a concat(b,'.') 1 a. -3 a . +3 c. drop table t1; create table t1 (a int not null); create table t2 (a int not null, primary key (a)); @@ -506,18 +513,18 @@ insert t2 select * from t1; checksum table t1, t2, t3 quick; Table Checksum -test.t1 968604391 +test.t1 272226711 test.t2 NULL test.t3 NULL checksum table t1, t2, t3; Table Checksum -test.t1 968604391 -test.t2 968604391 +test.t1 272226711 +test.t2 272226711 test.t3 NULL checksum table t1, t2, t3 extended; Table Checksum -test.t1 968604391 -test.t2 968604391 +test.t1 272226711 +test.t2 272226711 test.t3 NULL drop table t1,t2; create table t1 (a int, key (a)); @@ -555,3 +562,384 @@ count(*) 2 drop table t1; +set storage_engine=MyISAM; +drop table if exists t1,t2,t3; +--- Testing varchar --- +--- Testing varchar --- +create table t1 (v varchar(10), c char(10), t text); +insert into t1 values('+ ', '+ ', '+ '); +set @a=repeat(' ',20); +insert into t1 values (concat('+',@a),concat('+',@a),concat('+',@a)); +Warnings: +Warning 1265 Data truncated for column 'v' at row 1 +select concat('*',v,'*',c,'*',t,'*') from t1; +concat('*',v,'*',c,'*',t,'*') +*+ *+*+ * +*+ *+*+ * +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` varchar(10) default NULL, + `c` char(10) default NULL, + `t` text +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +create table t2 like t1; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `v` varchar(10) default NULL, + `c` char(10) default NULL, + `t` text +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +create table t3 select * from t1; +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `v` varchar(10) default NULL, + `c` char(10) default NULL, + `t` text +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +alter table t1 modify c varchar(10); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` varchar(10) default NULL, + `c` varchar(10) default NULL, + `t` text +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +alter table t1 modify v char(10); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` char(10) default NULL, + `c` varchar(10) default NULL, + `t` text +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +alter table t1 modify t varchar(10); +Warnings: +Warning 1265 Data truncated for column 't' at row 2 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` char(10) default NULL, + `c` varchar(10) default NULL, + `t` varchar(10) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +select concat('*',v,'*',c,'*',t,'*') from t1; +concat('*',v,'*',c,'*',t,'*') +*+*+*+ * +*+*+*+ * +drop table t1,t2,t3; +create table t1 (v varchar(10), c char(10), t text, key(v), key(c), key(t(10))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` varchar(10) default NULL, + `c` char(10) default NULL, + `t` text, + KEY `v` (`v`), + KEY `c` (`c`), + KEY `t` (`t`(10)) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +select count(*) from t1; +count(*) +270 +insert into t1 values(concat('a',char(1)),concat('a',char(1)),concat('a',char(1))); +select count(*) from t1 where v='a'; +count(*) +10 +select count(*) from t1 where c='a'; +count(*) +10 +select count(*) from t1 where t='a'; +count(*) +10 +select count(*) from t1 where v='a '; +count(*) +10 +select count(*) from t1 where c='a '; +count(*) +10 +select count(*) from t1 where t='a '; +count(*) +10 +select count(*) from t1 where v between 'a' and 'a '; +count(*) +10 +select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; +count(*) +10 +select count(*) from t1 where v like 'a%'; +count(*) +11 +select count(*) from t1 where c like 'a%'; +count(*) +11 +select count(*) from t1 where t like 'a%'; +count(*) +11 +select count(*) from t1 where v like 'a %'; +count(*) +9 +explain select count(*) from t1 where v='a '; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref v v 13 const 9 Using where; Using index +explain select count(*) from t1 where c='a '; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref c c 11 const 9 Using where; Using index +explain select count(*) from t1 where t='a '; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range t t 13 NULL 9 Using where +explain select count(*) from t1 where v like 'a%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 13 NULL 10 Using where; Using index +explain select count(*) from t1 where v between 'a' and 'a '; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 13 NULL 9 Using where; Using index +explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 13 NULL 9 Using where; Using index +alter table t1 add unique(v); +ERROR 23000: Duplicate entry '{ ' for key 1 +alter table t1 add key(v); +select concat('*',v,'*',c,'*',t,'*') as qq from t1 where v='a'; +qq +*a*a*a* +*a *a*a * +*a *a*a * +*a *a*a * +*a *a*a * +*a *a*a * +*a *a*a * +*a *a*a * +*a *a*a * +*a *a*a * +explain select * from t1 where v='a'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref v,v_2 v_2 13 const 7 Using where +select v,count(*) from t1 group by v limit 10; +v count(*) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select v,count(t) from t1 group by v limit 10; +v count(t) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select v,count(c) from t1 group by v limit 10; +v count(c) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select sql_big_result v,count(t) from t1 group by v limit 10; +v count(t) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select sql_big_result v,count(c) from t1 group by v limit 10; +v count(c) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select c,count(*) from t1 group by c limit 10; +c count(*) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select c,count(t) from t1 group by c limit 10; +c count(t) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select sql_big_result c,count(t) from t1 group by c limit 10; +c count(t) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select t,count(*) from t1 group by t limit 10; +t count(*) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select t,count(t) from t1 group by t limit 10; +t count(t) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select sql_big_result t,count(t) from t1 group by t limit 10; +t count(t) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +drop table t1; +create table t1 (a char(10), unique (a)); +insert into t1 values ('a '); +insert into t1 values ('a '); +ERROR 23000: Duplicate entry 'a' for key 1 +alter table t1 modify a varchar(10); +insert into t1 values ('a '),('a '),('a '),('a '); +ERROR 23000: Duplicate entry 'a ' for key 1 +insert into t1 values ('a '); +ERROR 23000: Duplicate entry 'a ' for key 1 +insert into t1 values ('a '); +ERROR 23000: Duplicate entry 'a ' for key 1 +insert into t1 values ('a '); +ERROR 23000: Duplicate entry 'a ' for key 1 +update t1 set a='a ' where a like 'a%'; +select concat(a,'.') from t1; +concat(a,'.') +a . +update t1 set a='abc ' where a like 'a '; +select concat(a,'.') from t1; +concat(a,'.') +a . +update t1 set a='a ' where a like 'a %'; +select concat(a,'.') from t1; +concat(a,'.') +a . +update t1 set a='a ' where a like 'a '; +select concat(a,'.') from t1; +concat(a,'.') +a . +drop table t1; +create table t1 (v varchar(10), c char(10), t text, key(v(5)), key(c(5)), key(t(5))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` varchar(10) default NULL, + `c` char(10) default NULL, + `t` text, + KEY `v` (`v`(5)), + KEY `c` (`c`(5)), + KEY `t` (`t`(5)) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 (v char(10) character set utf8); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` char(10) character set utf8 default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 (v varchar(10), c char(10)) row_format=fixed; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` varchar(10) default NULL, + `c` char(10) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 ROW_FORMAT=FIXED +insert into t1 values('a','a'),('a ','a '); +select concat('*',v,'*',c,'*') from t1; +concat('*',v,'*',c,'*') +*a*a* +*a *a* +drop table t1; +create table t1 (v varchar(65530), key(v(10))); +insert into t1 values(repeat('a',65530)); +select length(v) from t1 where v=repeat('a',65530); +length(v) +65530 +drop table t1; +create table t1 (v varchar(65530), key(v)); +Warnings: +Warning 1071 Specified key was too long; max key length is 1000 bytes +drop table if exists t1; +create table t1 (v varchar(65536)); +Warnings: +Note 1246 Converting column 'v' from VARCHAR to TEXT +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` mediumtext +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 (v varchar(65530) character set utf8); +Warnings: +Note 1246 Converting column 'v' from VARCHAR to TEXT +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` mediumtext character set utf8 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +set storage_engine=MyISAM; +create table t1 (v varchar(65535)); +ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs --- 1.35/mysql-test/t/myisam.test 2004-11-22 21:54:42 +02:00 +++ 1.36/mysql-test/t/myisam.test 2004-12-06 18:04:38 +02:00 @@ -450,11 +450,14 @@ # Test text and unique # create table t1 (a int not null auto_increment primary key, b text not null, unique b (b(20))); -insert into t1 (b) values ('a'),('a '),('a '); +insert into t1 (b) values ('a'),('b'),('c'); select concat(b,'.') from t1; update t1 set b='b ' where a=2; --error 1062 update t1 set b='b ' where a > 1; +--error 1062 +insert into t1 (b) values ('b'); +select * from t1; delete from t1 where b='b'; select a,concat(b,'.') from t1; drop table t1; @@ -524,3 +527,15 @@ select count(*) from t1 where a is null; drop table t1; +# +# Test varchar +# + +let $default=`select @@storage_engine`; +set storage_engine=MyISAM; +source include/varchar.inc; +eval set storage_engine=$default; + +# MyISAM specific varchar tests +--error 1118 +create table t1 (v varchar(65535)); --- 1.9/mysql-test/r/strict.result 2004-12-01 01:29:00 +02:00 +++ 1.10/mysql-test/r/strict.result 2004-12-06 18:04:37 +02:00 @@ -811,12 +811,14 @@ NULL NULL 1.79769313486232e+308 0 DROP TABLE t1; -CREATE TABLE t1 (col1 CHAR(5), col2 VARCHAR(5)); -INSERT INTO t1 VALUES ('hello', 'hello'),('he', 'he'),('hello ', 'hello '); +CREATE TABLE t1 (col1 CHAR(5), col2 VARCHAR(6)); +INSERT INTO t1 VALUES ('hello', 'hello'),('he', 'he'),('hello ', 'hello '); INSERT INTO t1 (col1) VALUES ('hellobob'); ERROR 01000: Data truncated for column 'col1' at row 1 INSERT INTO t1 (col2) VALUES ('hellobob'); ERROR 01000: Data truncated for column 'col2' at row 1 +INSERT INTO t1 (col2) VALUES ('hello '); +ERROR 01000: Data truncated for column 'col2' at row 1 UPDATE t1 SET col1 ='hellobob' WHERE col1 ='he'; ERROR 01000: Data truncated for column 'col1' at row 2 UPDATE t1 SET col2 ='hellobob' WHERE col2 ='he'; @@ -831,9 +833,9 @@ SELECT * FROM t1; col1 col2 hello hello -he hello -hello hello -hello hello +he hellot +hello hello +hello hellob DROP TABLE t1; CREATE TABLE t1 (col1 enum('red','blue','green')); INSERT INTO t1 VALUES ('red'),('blue'),('green'); --- 1.6/mysql-test/t/strict.test 2004-11-26 12:02:35 +02:00 +++ 1.7/mysql-test/t/strict.test 2004-12-06 18:04:38 +02:00 @@ -563,12 +563,14 @@ # Testing INSERT with CHAR/VARCHAR -CREATE TABLE t1 (col1 CHAR(5), col2 VARCHAR(5)); -INSERT INTO t1 VALUES ('hello', 'hello'),('he', 'he'),('hello ', 'hello '); +CREATE TABLE t1 (col1 CHAR(5), col2 VARCHAR(6)); +INSERT INTO t1 VALUES ('hello', 'hello'),('he', 'he'),('hello ', 'hello '); --error 1265 INSERT INTO t1 (col1) VALUES ('hellobob'); --error 1265 INSERT INTO t1 (col2) VALUES ('hellobob'); +--error 1265 +INSERT INTO t1 (col2) VALUES ('hello '); --error 1265 UPDATE t1 SET col1 ='hellobob' WHERE col1 ='he'; --error 1265 --- 1.3/mysql-test/t/endspace.test 2004-12-01 17:25:00 +02:00 +++ 1.4/mysql-test/t/endspace.test 2004-12-06 18:04:37 +02:00 @@ -41,16 +41,16 @@ select concat('|', text1, '|') from t1 where text1='teststring'; select concat('|', text1, '|') from t1 where text1='teststring '; explain select concat('|', text1, '|') from t1 where text1='teststring '; -select * from t1 where text1 like 'teststring_%'; -select * from t1 where text1='teststring' or text1 like 'teststring_%'; +select concat('|', text1, '|') from t1 where text1 like 'teststring_%'; +select concat('|', text1, '|') from t1 where text1='teststring' or text1 like 'teststring_%'; select concat('|', text1, '|') from t1 where text1='teststring' or text1 > 'teststring\t'; select concat('|', text1, '|') from t1 order by text1; drop table t1; create table t1 (text1 varchar(32) not NULL, KEY key1 (text1)) pack_keys=0; insert into t1 values ('teststring'), ('nothing'), ('teststring\t'); -select * from t1 where text1='teststring' or text1 like 'teststring_%'; -select * from t1 where text1='teststring' or text1 >= 'teststring\t'; +select concat('|', text1, '|') from t1 where text1='teststring' or text1 like 'teststring_%'; +select concat('|', text1, '|') from t1 where text1='teststring' or text1 >= 'teststring\t'; drop table t1; # Test HEAP tables (with BTREE keys) --- 1.48/libmysqld/Makefile.am 2004-12-06 01:59:59 +02:00 +++ 1.49/libmysqld/Makefile.am 2004-12-06 18:04:36 +02:00 @@ -26,7 +26,7 @@ -DDATADIR="\"$(MYSQLDATAdir)\"" \ -DSHAREDIR="\"$(MYSQLSHAREdir)\"" INCLUDES= @MT_INCLUDES@ @bdb_includes@ -I$(top_srcdir)/include \ - -I$(top_srcdir)/sql -I$(top_srcdir)/regex \ + -I$(top_srcdir)/sql -I$(top_srcdir)/sql/examples -I$(top_srcdir)/regex \ $(openssl_includes) @ZLIB_INCLUDES@ noinst_LIBRARIES = libmysqld_int.a @@ -35,6 +35,7 @@ libmysqld_sources= libmysqld.c lib_sql.cc emb_qcache.cc libmysqlsources = errmsg.c get_password.c libmysql.c client.c pack.c \ my_time.c +sqlexamplessources = ha_example.cc ha_archive.cc ha_tina.cc noinst_HEADERS = embedded_priv.h emb_qcache.h @@ -61,7 +62,7 @@ sp_head.cc sp_pcontext.cc sp.cc sp_cache.cc sp_rcontext.cc \ parse_file.cc sql_view.cc sql_trigger.cc -libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources) +libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources) $(sqlexamplessources) libmysqld_a_SOURCES= # automake misses these @@ -125,12 +126,16 @@ rm -f $(srcdir)/$$f; \ @LN_CP_F@ $(srcdir)/../libmysql/$$f $(srcdir)/$$f; \ done; \ + for f in $(sqlexamplessources); do \ + rm -f $(srcdir)/$$f; \ + @LN_CP_F@ $(srcdir)/../sql/examples/$$f $(srcdir)/$$f; \ + done; \ rm -f $(srcdir)/client_settings.h; \ @LN_CP_F@ $(srcdir)/../libmysql/client_settings.h $(srcdir)/client_settings.h; clean-local: - rm -f `echo $(sqlsources) $(libmysqlsources) | sed "s;\.lo;.c;g"` \ + rm -f `echo $(sqlsources) $(libmysqlsources) $(sqlexamplessources) | sed "s;\.lo;.c;g"` \ $(top_srcdir)/linked_libmysqld_sources; \ rm -f client_settings.h --- 1.121/client/mysqltest.c 2004-11-22 21:54:40 +02:00 +++ 1.122/client/mysqltest.c 2004-12-06 18:04:36 +02:00 @@ -778,7 +778,7 @@ } else v = var_reg + digit; - return eval_expr(v, var_val, (const char**)&var_val_end); + DBUG_RETURN(eval_expr(v, var_val, (const char**)&var_val_end)); } --- 1.23/mysql-test/r/mysqldump.result 2004-11-30 19:58:12 +02:00 +++ 1.24/mysql-test/r/mysqldump.result 2004-12-06 18:04:37 +02:00 @@ -106,7 +106,7 @@ - + --- 1.9/include/decimal.h 2004-12-06 01:59:56 +02:00 +++ 1.10/include/decimal.h 2004-12-06 18:04:36 +02:00 @@ -49,13 +49,7 @@ int decimal_div(decimal *from1, decimal *from2, decimal *to, int scale_incr); int decimal_mod(decimal *from1, decimal *from2, decimal *to); int decimal_round(decimal *from, decimal *to, int new_scale, decimal_round_mode mode); - -/* - the following works only on special "zero" decimal, not on any - decimal that happen to evaluate to zero -*/ - -#define decimal_is_zero(dec) ((dec)->intg1==1 && (dec)->frac1==0 && (dec)->buf[0]==0) +int decimal_is_zero(decimal *from); /* set a decimal to zero */ --- 1.31/strings/decimal.c 2004-12-06 16:08:19 +02:00 +++ 1.32/strings/decimal.c 2004-12-06 18:04:40 +02:00 @@ -98,10 +98,12 @@ implementation-defined. */ -#include +#include #include #include #include /* for my_alloca */ +#include +#include typedef decimal_digit dec1; typedef longlong dec2; @@ -308,7 +310,7 @@ char *s=from, *s1; int i, intg, frac, error, intg1, frac1; dec1 x,*buf; - + LINT_INIT(error); sanity(to); while (my_isspace(&my_charset_latin1, *s)) @@ -366,6 +368,7 @@ intg=intg1*DIG_PER_DEC1; } } + /* Error is guranteed to be set here */ to->intg=intg; to->frac=frac; @@ -1353,6 +1356,8 @@ dec1 *buf0, *buf1=from1->buf, *buf2=from2->buf, *tmp1, *start2, *stop2, *stop1, *stop0, norm2, carry, *start1; dec2 norm_factor, x, guess, y; + + LINT_INIT(error); if (mod) to=mod; --- 1.33/mysql-test/r/ps.result 2004-11-22 22:33:09 +02:00 +++ 1.34/mysql-test/r/ps.result 2004-12-06 18:04:37 +02:00 @@ -207,10 +207,10 @@ prepare stmt1 from ' show table status from test like ''t1%'' '; execute stmt1; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 MyISAM 9 Dynamic 0 0 0 4294967295 1024 0 NULL # # # latin1_swedish_ci NULL +t1 MyISAM 10 Dynamic 0 0 0 4294967295 1024 0 NULL # # # latin1_swedish_ci NULL show table status from test like 't1%' ; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 MyISAM 9 Dynamic 0 0 0 4294967295 1024 0 NULL # # # latin1_swedish_ci NULL +t1 MyISAM 10 Dynamic 0 0 0 4294967295 1024 0 NULL # # # latin1_swedish_ci NULL deallocate prepare stmt1 ; drop table t1; create table t1(a varchar(2), b varchar(3)); --- 1.34/mysql-test/r/bdb.result 2004-11-04 23:37:32 +02:00 +++ 1.35/mysql-test/r/bdb.result 2004-12-06 19:18:30 +02:00 @@ -140,13 +140,13 @@ 1015 102 2 explain select level from t1 where level=1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref level level 1 const 1 Using index +1 SIMPLE t1 ref level level 1 const 6 Using index explain select level,id from t1 where level=1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref level level 1 const 1 Using index +1 SIMPLE t1 ref level level 1 const 6 Using index explain select level,id,parent_id from t1 where level=1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref level level 1 const 1 +1 SIMPLE t1 ref level level 1 const 6 select level,id from t1 where level=1; level id 1 1002 @@ -625,7 +625,7 @@ 1016 102 2 explain select level from t1 where level=1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref level level 1 const 1 Using index +1 SIMPLE t1 ref level level 1 const 6 Using index select level,id from t1 where level=1; level id 1 1004 @@ -1291,3 +1291,382 @@ select * from t1; a b drop table t1; +set storage_engine=bdb; +drop table if exists t1,t2,t3; +--- Testing varchar --- +--- Testing varchar --- +create table t1 (v varchar(10), c char(10), t text); +insert into t1 values('+ ', '+ ', '+ '); +set @a=repeat(' ',20); +insert into t1 values (concat('+',@a),concat('+',@a),concat('+',@a)); +Warnings: +Warning 1265 Data truncated for column 'v' at row 1 +select concat('*',v,'*',c,'*',t,'*') from t1; +concat('*',v,'*',c,'*',t,'*') +*+ *+*+ * +*+ *+*+ * +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` varchar(10) default NULL, + `c` char(10) default NULL, + `t` text +) ENGINE=BerkeleyDB DEFAULT CHARSET=latin1 +create table t2 like t1; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `v` varchar(10) default NULL, + `c` char(10) default NULL, + `t` text +) ENGINE=BerkeleyDB DEFAULT CHARSET=latin1 +create table t3 select * from t1; +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `v` varchar(10) default NULL, + `c` char(10) default NULL, + `t` text +) ENGINE=BerkeleyDB DEFAULT CHARSET=latin1 +alter table t1 modify c varchar(10); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` varchar(10) default NULL, + `c` varchar(10) default NULL, + `t` text +) ENGINE=BerkeleyDB DEFAULT CHARSET=latin1 +alter table t1 modify v char(10); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` char(10) default NULL, + `c` varchar(10) default NULL, + `t` text +) ENGINE=BerkeleyDB DEFAULT CHARSET=latin1 +alter table t1 modify t varchar(10); +Warnings: +Warning 1265 Data truncated for column 't' at row 2 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` char(10) default NULL, + `c` varchar(10) default NULL, + `t` varchar(10) default NULL +) ENGINE=BerkeleyDB DEFAULT CHARSET=latin1 +select concat('*',v,'*',c,'*',t,'*') from t1; +concat('*',v,'*',c,'*',t,'*') +*+*+*+ * +*+*+*+ * +drop table t1,t2,t3; +create table t1 (v varchar(10), c char(10), t text, key(v), key(c), key(t(10))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` varchar(10) default NULL, + `c` char(10) default NULL, + `t` text, + KEY `v` (`v`), + KEY `c` (`c`), + KEY `t` (`t`(10)) +) ENGINE=BerkeleyDB DEFAULT CHARSET=latin1 +select count(*) from t1; +count(*) +270 +insert into t1 values(concat('a',char(1)),concat('a',char(1)),concat('a',char(1))); +select count(*) from t1 where v='a'; +count(*) +10 +select count(*) from t1 where c='a'; +count(*) +10 +select count(*) from t1 where t='a'; +count(*) +10 +select count(*) from t1 where v='a '; +count(*) +10 +select count(*) from t1 where c='a '; +count(*) +10 +select count(*) from t1 where t='a '; +count(*) +10 +select count(*) from t1 where v between 'a' and 'a '; +count(*) +10 +select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; +count(*) +10 +select count(*) from t1 where v like 'a%'; +count(*) +11 +select count(*) from t1 where c like 'a%'; +count(*) +11 +select count(*) from t1 where t like 'a%'; +count(*) +11 +select count(*) from t1 where v like 'a %'; +count(*) +9 +explain select count(*) from t1 where v='a '; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref v v 13 const 10 Using where +explain select count(*) from t1 where c='a '; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref c c 11 const 10 Using where +explain select count(*) from t1 where t='a '; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range t t 13 NULL 10 Using where +explain select count(*) from t1 where v like 'a%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 13 NULL 11 Using where +explain select count(*) from t1 where v between 'a' and 'a '; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 13 NULL 10 Using where +explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 13 NULL 10 Using where +alter table t1 add unique(v); +ERROR 23000: Duplicate entry '{ ' for key 1 +alter table t1 add key(v); +select concat('*',v,'*',c,'*',t,'*') as qq from t1 where v='a'; +qq +*a*a*a* +*a *a*a * +*a *a*a * +*a *a*a * +*a *a*a * +*a *a*a * +*a *a*a * +*a *a*a * +*a *a*a * +*a *a*a * +explain select * from t1 where v='a'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref v,v_2 v 13 const 10 Using where +select v,count(*) from t1 group by v limit 10; +v count(*) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select v,count(t) from t1 group by v limit 10; +v count(t) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select v,count(c) from t1 group by v limit 10; +v count(c) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select sql_big_result v,count(t) from t1 group by v limit 10; +v count(t) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select sql_big_result v,count(c) from t1 group by v limit 10; +v count(c) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select c,count(*) from t1 group by c limit 10; +c count(*) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select c,count(t) from t1 group by c limit 10; +c count(t) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select sql_big_result c,count(t) from t1 group by c limit 10; +c count(t) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select t,count(*) from t1 group by t limit 10; +t count(*) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select t,count(t) from t1 group by t limit 10; +t count(t) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +select sql_big_result t,count(t) from t1 group by t limit 10; +t count(t) +a 1 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +drop table t1; +create table t1 (a char(10), unique (a)); +insert into t1 values ('a '); +insert into t1 values ('a '); +ERROR 23000: Duplicate entry 'a' for key 1 +alter table t1 modify a varchar(10); +insert into t1 values ('a '),('a '),('a '),('a '); +ERROR 23000: Duplicate entry 'a ' for key 1 +insert into t1 values ('a '); +ERROR 23000: Duplicate entry 'a ' for key 1 +insert into t1 values ('a '); +ERROR 23000: Duplicate entry 'a ' for key 1 +insert into t1 values ('a '); +ERROR 23000: Duplicate entry 'a ' for key 1 +update t1 set a='a ' where a like 'a%'; +select concat(a,'.') from t1; +concat(a,'.') +a . +update t1 set a='abc ' where a like 'a '; +select concat(a,'.') from t1; +concat(a,'.') +a . +update t1 set a='a ' where a like 'a %'; +select concat(a,'.') from t1; +concat(a,'.') +a . +update t1 set a='a ' where a like 'a '; +select concat(a,'.') from t1; +concat(a,'.') +a . +drop table t1; +create table t1 (v varchar(10), c char(10), t text, key(v(5)), key(c(5)), key(t(5))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` varchar(10) default NULL, + `c` char(10) default NULL, + `t` text, + KEY `v` (`v`(5)), + KEY `c` (`c`(5)), + KEY `t` (`t`(5)) +) ENGINE=BerkeleyDB DEFAULT CHARSET=latin1 +drop table t1; +create table t1 (v char(10) character set utf8); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` char(10) character set utf8 default NULL +) ENGINE=BerkeleyDB DEFAULT CHARSET=latin1 +drop table t1; +create table t1 (v varchar(10), c char(10)) row_format=fixed; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` varchar(10) default NULL, + `c` char(10) default NULL +) ENGINE=BerkeleyDB DEFAULT CHARSET=latin1 ROW_FORMAT=FIXED +insert into t1 values('a','a'),('a ','a '); +select concat('*',v,'*',c,'*') from t1; +concat('*',v,'*',c,'*') +*a*a* +*a *a* +drop table t1; +create table t1 (v varchar(65530), key(v(10))); +insert into t1 values(repeat('a',65530)); +select length(v) from t1 where v=repeat('a',65530); +length(v) +65530 +drop table t1; +create table t1 (v varchar(65530), key(v)); +Warnings: +Warning 1071 Specified key was too long; max key length is 255 bytes +drop table if exists t1; +create table t1 (v varchar(65536)); +Warnings: +Note 1246 Converting column 'v' from VARCHAR to TEXT +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` mediumtext +) ENGINE=BerkeleyDB DEFAULT CHARSET=latin1 +drop table t1; +create table t1 (v varchar(65530) character set utf8); +Warnings: +Note 1246 Converting column 'v' from VARCHAR to TEXT +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` mediumtext character set utf8 +) ENGINE=BerkeleyDB DEFAULT CHARSET=latin1 +drop table t1; +set storage_engine=MyISAM; --- 1.40/mysql-test/t/bdb.test 2004-11-04 23:37:32 +02:00 +++ 1.41/mysql-test/t/bdb.test 2004-12-06 19:18:30 +02:00 @@ -939,3 +939,12 @@ select * from t1; drop table t1; + +# +# Test varchar +# + +let $default=`select @@storage_engine`; +set storage_engine=bdb; +source include/varchar.inc; +eval set storage_engine=$default; --- 1.82/tests/client_test.c 2004-12-06 11:38:52 +02:00 +++ 1.83/tests/client_test.c 2004-12-06 18:04:41 +02:00 @@ -7651,13 +7651,13 @@ if (!opt_silent) { - fprintf(stdout, "\n id : %d", id); - fprintf(stdout, "\n name : %s(%ld)", data, length); + fprintf(stdout, "id : %d\n", id); + fprintf(stdout, "name : %s(%ld)\n", data, length); } DIE_UNLESS(id == 9876); - DIE_UNLESS(length == 19); /* Due to VARCHAR(20) */ - DIE_UNLESS(strcmp(data, "MySQL - Open Source") == 0); + DIE_UNLESS(length == 19 || length == 20); /* Due to VARCHAR(20) */ + DIE_UNLESS(is_prefix(data, "MySQL - Open Source") == 1); rc= mysql_stmt_fetch(stmt); check_execute(stmt, rc); --- 1.36/sql/sql_help.cc 2004-11-25 02:23:08 +02:00 +++ 1.37/sql/sql_help.cc 2004-12-06 18:04:39 +02:00 @@ -286,8 +286,7 @@ relations->file->ha_index_init(iindex_relations); rkey_id->store((longlong) key_id); - rkey_id->get_key_image(buff, rkey_id->pack_length(), rkey_id->charset(), - Field::itRAW); + rkey_id->get_key_image(buff, rkey_id->pack_length(), Field::itRAW); int key_res= relations->file->index_read(relations->record[0], (byte *)buff, rkey_id->pack_length(), HA_READ_KEY_EXACT); @@ -300,8 +299,7 @@ longlong topic_id= rtopic_id->val_int(); Field *field= find_fields[help_topic_help_topic_id].field; field->store((longlong) topic_id); - field->get_key_image(topic_id_buff, field->pack_length(), field->charset(), - Field::itRAW); + field->get_key_image(topic_id_buff, field->pack_length(), Field::itRAW); if (!topics->file->index_read(topics->record[0], (byte *)topic_id_buff, field->pack_length(), HA_READ_KEY_EXACT))