diff options
author | unknown <monty@donna.mysql.com> | 2001-01-28 21:35:50 +0200 |
---|---|---|
committer | unknown <monty@donna.mysql.com> | 2001-01-28 21:35:50 +0200 |
commit | 184e24b2253a81b03476e3d4d8cf56d5eb9dbf18 (patch) | |
tree | fabb5447e17b9f0959cb83b6d88351367ca53645 | |
parent | 298ba0d39d6d38d5be860a3ad8a55b469b67e7d8 (diff) | |
download | mariadb-git-184e24b2253a81b03476e3d4d8cf56d5eb9dbf18.tar.gz |
Fixed ALTER TABLE on MERGE tables
Fixed bug in DISTINCT
Docs/manual.texi:
Updated Changelog
Cleaned up adding character sets
merge/open.c:
skip comments
myisam/mi_check.c:
Fixed bug when sorting index on Windows
myisammrg/myrg_info.c:
Use only portable printf arguments
myisammrg/myrg_rrnd.c:
Use only portable printf arguments
mysql-test/r/distinct.result:
Added test case for bug in distinct
mysql-test/r/merge.result:
Added test for ALTER TABLE
mysql-test/t/distinct.test:
Added test case for bug in distinct
mysql-test/t/merge.test:
Added test for ALTER TABLE
sql-bench/crash-me.sh:
Fixed portability issues
sql/ha_myisammrg.cc:
Fixed for ALTER TABLE on MERGE tables
sql/item_sum.cc:
Fixed bug in DISTINCT
sql/sql_db.cc:
Added test of namelen in check_db_name
sql/sql_select.cc:
Fixed bug in DISTINCT
sql/sql_select.h:
Fixed bug in DISTINCT
sql/sql_table.cc:
Fixed ALTER TABLE on MERGE tables
sql/table.cc:
Added test of namelen in check_db_name
sql/table.h:
Fixed ALTER TABLE on MERGE tables
-rw-r--r-- | Docs/manual.texi | 206 | ||||
-rw-r--r-- | merge/open.c | 2 | ||||
-rw-r--r-- | myisam/mi_check.c | 37 | ||||
-rw-r--r-- | myisammrg/myrg_info.c | 4 | ||||
-rw-r--r-- | myisammrg/myrg_rrnd.c | 6 | ||||
-rw-r--r-- | mysql-test/r/distinct.result | 14 | ||||
-rw-r--r-- | mysql-test/r/merge.result | 6 | ||||
-rw-r--r-- | mysql-test/t/distinct.test | 16 | ||||
-rw-r--r-- | mysql-test/t/merge.test | 9 | ||||
-rw-r--r-- | sql-bench/crash-me.sh | 6 | ||||
-rw-r--r-- | sql/ha_myisammrg.cc | 1 | ||||
-rw-r--r-- | sql/item_sum.cc | 2 | ||||
-rw-r--r-- | sql/sql_db.cc | 4 | ||||
-rw-r--r-- | sql/sql_select.cc | 97 | ||||
-rw-r--r-- | sql/sql_select.h | 8 | ||||
-rw-r--r-- | sql/sql_table.cc | 9 | ||||
-rw-r--r-- | sql/table.cc | 3 | ||||
-rw-r--r-- | sql/table.h | 1 |
18 files changed, 321 insertions, 110 deletions
diff --git a/Docs/manual.texi b/Docs/manual.texi index c719ab240cd..dd89e9e70c8 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -555,6 +555,7 @@ What Languages Are Supported by MySQL? * Character sets:: The character set used for data and sorting * Adding character set:: Adding a new character set +* Character arrays:: * String collating:: String collating support * Multi-byte characters:: Multi-byte character support @@ -567,7 +568,7 @@ Replication in MySQL * Replication Options:: Replication Options in my.cnf * Replication SQL:: SQL Commands related to replication * Replication FAQ:: Frequently Asked Questions about replication -* Troubleshooting Replication:: Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication +* Troubleshooting Replication:: Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication Getting Maximum Performance from MySQL @@ -863,6 +864,7 @@ Changes in release 4.0.x (Development; Alpha) Changes in release 3.23.x (Stable) +* News-3.23.33:: Changes in release 3.23.33 * News-3.23.32:: Changes in release 3.23.32 * News-3.23.31:: Changes in release 3.23.31 * News-3.23.30:: Changes in release 3.23.30 @@ -2214,7 +2216,6 @@ Apart from the following links, you can find and download a lot of @uref{http://www.mysql.com/Downloads/Contrib/, Contrib directory}. @cindex @code{Contrib} directory - @cindex URLs to MySQL information @cindex related information URLs @strong{MySQL} @@ -2265,8 +2266,10 @@ The Mac OS Xclave. Running @strong{MySQL} on Mac OS X MySQL for Mac OS X Server. @item @uref{http://www.latencyzero.com/macosx/mysql.html}@* Bulding MySQL for Mac OS X +@item @uref{http://www.essencesw.com/Software/mysqllib.html}@* +New Client libraries for the Mac OS Classic (Macintosh). @item @uref{http://www.lilback.com/macsql/}@* -Client libraries for the Macintosh. +Client libraries for Mac OS Classic (Macintosh). @end itemize @subheading Perl-related Links @@ -2355,6 +2358,9 @@ MySQL-Databases, creating of new DBs and tables, editing etc. @item @uref{http://www.scibit.com/Products/Software/Utils/Mascon.asp}@* Mascon is a powerful Win32 GUI for the administering MySQL server databases. + +@item @uref{http://www.rtlabs.com/}@* +MacSQL Monitor. GUI for MySQL, ODBC, and JDBC databases for the Mac OS. @end itemize @subheading Distributions that Include MySQL @@ -2555,9 +2561,21 @@ any MTA to deliver to users in a @strong{MySQL} database. @item @uref{http://www.pbc.ottawa.on.ca}@* Visual Basic class generator for Active X. +@item @uref{http://www.essencesw.com/Software/mysqllib.html}@* +New Client libraries for the Mac OS Classic (Macintosh). + @item @uref{http://www.lilback.com/macsql/}@* Client libraries for the Macintosh. +@item @uref{http://www.essencesw.com/Plugins/mysqlplug.html}@* +Plugin for REALbasic (for Machintosh) + +@item @uref{http://www.iis.ee.ethz.ch/~neeri/macintosh/gusi-qa.html}@* +A library that emulates BSD sockets and pthreads on Macintosh. This can +be used if you want to compile the @strong{MySQL} client library on Mac. It +could probably even be sued to port @strong{MySQL} to Macintosh, but we +don't know of anyone that has tried that. + @c 404 not found @c @item @uref{http://tfdec1.fys.kuleuven.ac.be/~michael/fpc-linux/mysql}@* @c @strong{MySQL} binding to Free Pascal. @@ -8550,6 +8568,13 @@ While you are doing an @code{ALTER TABLE} the table is locked from usage by other threads. This has to do with the fact that you on Windows can't delete a file that is in use by another threads. (We may in the future find some way to go around this problem). + +@item @code{DROP TABLE} on a table that is in use by a @code{MERGE} table will not work. +The @code{MERGE} handler does it table mapping hidden from @strong{MySQL}. +Because windows doesn't allow one to drop files that are open, you have +to first flush all @code{MERGE} tables (with @code{FLUSH TABLES}) or drop the +@code{MERGE} table before drooping the table. We will fix this at +the same time we introduce @code{VIEW}'s. @end table Here are some open issues for anyone who might want to help us with the Windows @@ -22713,6 +22738,7 @@ the outside of the @code{MySQL} server: @example shell> cd /mysql-data-directory/current-database shell> ls -1 t1.MYI t2.MYI > total.MRG +shell> mysqladmin flush-tables @end example Now you can do things like: @@ -22731,10 +22757,18 @@ mysql> select * from total; +---+---------+ @end example -To remap a @code{MERGE} table you must either @code{DROP} it and -re-create it or change the @code{.MRG} file and issue a @code{FLUSH -TABLE} on the @code{MERGE} table and all underlying tables to force the -handler to read the new definition file. +To remap a @code{MERGE} table you can do one of the following: + +@itemize @bullet +@item +@code{DROP} the table and re-create it +@item +Use @code{ALTER TABLE table_name UNION(...)} +@item +Change the @code{.MRG} file and issue a @code{FLUSH TABLE} on the +@code{MERGE} table and all underlying tables to force the handler to +read the new definition file. +@end itemize @cindex tables, ISAM @node ISAM, HEAP, MERGE, Table types @@ -25456,6 +25490,7 @@ your changes with the new @file{errmsg.txt} file. @menu * Character sets:: The character set used for data and sorting * Adding character set:: Adding a new character set +* Character arrays:: * String collating:: String collating support * Multi-byte characters:: Multi-byte character support @end menu @@ -25514,28 +25549,52 @@ default-character-set=character-set-name but normally this is never needed. -To add another character set to @strong{MySQL}, use the following procedure. - @cindex character sets, adding @cindex adding, character sets -@node Adding character set, String collating, Character sets, Languages +@node Adding character set, Character arrays, Character sets, Languages @subsection Adding a New Character Set -@enumerate -@item -Choose a name for the character set, denoted @code{MYSET} below. +To add another character set to @strong{MySQL}, use the following procedure. -@item Decide if the set is simple or complex. If the character set does not need to use special string collating routines for -sorting and does not need mulit-byte character support, it is +sorting and does not need multi-byte character support, it is simple. If it needs either of those features, it is complex. +For example, @code{latin1} and @code{danish} are simple charactersets while +@code{big5} or @code{czech} are complex character sets. + +In the following section, we have assumed that you name your character +set @code{MYSET}. + +For a simple character set do the following: + +@enumerate +@item +Add MYSET to the end of the @file{sql/share/charsets/Index} file +Assign an unique number to it. + @item -If the character set is simple, then create the file -@file{sql/share/charsets/MYSET.conf}, and add MYSET the -@file{sql/share/charsets/Index} file. Read the -@file{sql/share/charsets/README} for more instructions. +Create the file @file{sql/share/charsets/MYSET.conf}. +(You can use @file{sql/share/charsets/latin1.conf} as a base for this). + +The syntax for the file very simple: + +@itemize @bullet +@item +Comments start with a '#' character and proceed to the end of the line. +@item +Words are separated by arbitrary amounts of whitespace. +@item +When defining the character set, every word must be a number in hexadecimal +format +@item +The @code{ctype} array takes up the first 257 words. The +@code{to_lower}, @code{to_upper} and @code{sort_order} arrays take up +256 words each after that. +@end itemize + +@xref{Character arrays}. @item Add the character set name to the @code{CHARSETS_AVAILABLE} and @@ -25544,20 +25603,28 @@ Add the character set name to the @code{CHARSETS_AVAILABLE} and @item Reconfigure, recompile, and test. +@end enumerate + +For a complex character set do the following: + +@enumerate @item -If the character set is complex, create the file -@file{strings/ctype-MYSET.c} in the @strong{MySQL} source distribution. +Create the file @file{strings/ctype-MYSET.c} in the @strong{MySQL} source +distribution. @item -Add MYSET to the end of the @file{sql/share/charsets/Index} file. Take -note of its position in the file - this is its character set number, -denoted @code{MYNUMBER} below. +Add MYSET to the end of the @file{sql/share/charsets/Index} file. +Assign an unique number to it. @item -Look at one of the existing @file{ctype-*.c} files to see what needs to be -defined. Note that the arrays in your file must have names like -@code{ctype_MYSET}, @code{to_lower_MYSET}, and so on. +Look at one of the existing @file{ctype-*.c} files to see what needs to +be defined, for example @file{strings/ctype-big5.c}. Note that the +arrays in your file must have names like @code{ctype_MYSET}, +@code{to_lower_MYSET}, and so on. This corresponds to the arrays +in the simple character set. @xref{Character arrays}. For a complex +character set +@item Near the top of the file, place a special comment like this: @example @@ -25579,6 +25646,34 @@ the following sections. Only include them if you the string collating functions or the multi-byte character set functions, respectively. +@item +You should then create some of the following functions: + +@itemize @bullet +@item @code{my_strncoll_MYSET()} +@item @code{my_strcoll_MYSET()} +@item @code{my_strxfrm_MYSET()} +@item @code{my_like_range_MYSET()} +@end itemize + +@xref{String collating}. + +@item +Add the character set name to the @code{CHARSETS_AVAILABLE} and +@code{COMPILED_CHARSETS} lists in @code{configure.in}. + +@item +Reconfigure, recompile, and test. +@end enumerate + +The file @file{sql/share/charsets/README} includes some more instructions. + +If you want to have the character set included in the @strong{MySQL} +distribution, mail a patch to @email{internals@@lists.mysql.com}. + +@node Character arrays, String collating, Adding character set, Languages +@subsection The character definition arrays + @code{to_lower[]} and @code{to_upper[]} are simple arrays that hold the lowercase and uppercase characters corresponding to each member of the character set. For example: @@ -25593,12 +25688,13 @@ comparison and sorting purposes. For many character sets, this is the same as @code{to_upper[]} (which means sorting will be case insensitive). @strong{MySQL} will sort characters based on the value of @code{sort_order[character]}. For more complicated sorting rules, see -the discussion of string collating below. +the discussion of string collating below. @xref{String collating}. @code{ctype[]} is an array of bit values, with one element for one character. (Note that @code{to_lower[]}, @code{to_upper[]}, and @code{sort_order[]} are indexed by character value, but @code{ctype[]} is indexed by character value + 1. This is an old legacy to be able to handle EOF.) + You can find the following bitmask definitions in @file{m_ctype.h}: @example @@ -25613,28 +25709,18 @@ You can find the following bitmask definitions in @file{m_ctype.h}: @end example The @code{ctype[]} entry for each character should be the union of the -applicable bitmask values that describe the character. -For example, @code{'A'} is an uppercase character (@code{_U}) as well as a -hexadecimal digit (@code{_X}), so @code{ctype['A'+1]} should contain the value: +applicable bitmask values that describe the character. For example, +@code{'A'} is an uppercase character (@code{_U}) as well as a +hexadecimal digit (@code{_X}), so @code{ctype['A'+1]} should contain the +value: + @example _U + _X = 01 + 0200 = 0201 @end example -@item -Add support for the string collating or multi-byte features needed, as -described in the following sections. - -@item -Add the character set name to the @code{CHARSETS_AVAILABLE} and -@code{COMPILED_CHARSETS} lists in @code{configure.in}. - -@item -Reconfigure, recompile, and test. -@end enumerate - @cindex collating, strings @cindex string collating -@node String collating, Multi-byte characters, Adding character set, Languages +@node String collating, Multi-byte characters, Character arrays, Languages @subsection String Collating Support If the sorting rules for your language are too complex to be handled @@ -25647,7 +25733,7 @@ character sets for examples. You must specify the @code{strxfrm_multiply_MYSET=N} value in the special comment at the top of the file. @code{N} should be set to -the maximum ratio the strings may grow during my_strxfrm_MYSET (it +the maximum ratio the strings may grow during @code{my_strxfrm_MYSET} (it must be a positive integer). @cindex characters, multi-byte @@ -25737,7 +25823,7 @@ tables}. * Replication Options:: Replication Options in my.cnf * Replication SQL:: SQL Commands related to replication * Replication FAQ:: Frequently Asked Questions about replication -* Troubleshooting Replication:: Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication +* Troubleshooting Replication:: Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication. Troubleshooting Replication @end menu @node Replication Intro, Replication Implementation, Replication, Replication @@ -33108,8 +33194,9 @@ symbols that start with @code{mysql_}, like the following: you should be able to solve this by adding @code{-Lpath-to-the-mysql-library -lmysqlclient} @strong{LAST} on your link line. -If you get @code{undefined reference} errors for the @code{compress} function, -add @code{-lgz} @strong{LAST} on your link line and try again! +If you get @code{undefined reference} errors for the @code{uncompress} +or @code{compress} function, add @code{-lgz} @strong{LAST} on your link +line and try again! If you get @code{undefined reference} errors for functions that should exist on your system, like @code{connect}, check the man page for the @@ -38174,6 +38261,10 @@ This means that your PHP version isn't compiled with @strong{MySQL} support. You can either compile a dynamic @strong{MySQL} module and load it into PHP or recompile PHP with built-in @strong{MySQL} support. This is described in detail in the PHP manual. +@item Error: "undefined reference to `uncompress'" +This means that the client library is compiled with support for a compressed +client/server protocol. The fix is to add @code{-lz} last when linking +with @code{-lmysqlclient}. @end itemize @cindex C++ APIs @@ -39875,6 +39966,8 @@ colour coding, dump functionality and much more. @uref{http://www.scibit.com/Products/Software/Utils/Mascon.asp,Mascon home page}. @item @uref{http://www.virtualbeer.net/dbui/,DBUI} DBUI is a Gtk graphical database editor. +@item @uref{http://www.rtlabs.com/, MacSQL} +GUI for MySQL, ODBC, and JDBC databases for the Mac OS. @end itemize @cindex Web clients @@ -40816,6 +40909,12 @@ not yet 100 % confident in this code. @appendixsubsec Changes in release 3.23.33 @itemize bullet @item +@code{myisamchk -S} and @code{OPTIMIZE TABLE} now works on Windows. +@item +Fixed bug when using @code{DISTINCT} on results from functions that refered to +a group function, like +@code{SELECT a,DISTINCT SEC_TO_TIME(sum(a)) from table_name GROUP BY a,b}. +@item Fixed bug in replication that broke slave server start with existing @code{master.info} - bug introduced in 3.23.32 @item @@ -40840,6 +40939,13 @@ Fixed several timing bugs in the test suite @item Extended @code{mysqltest} to take care of the timing issues in the test suite. +@item +@code{ALTER TABLE} can now be used to change the definition for a +@code{MERGE} table. +@item +Fixed creation of @code{MERGE} tables on Windows. +@item +Portability fixes for OpenBSD and OS2. @end itemize @@ -45514,10 +45620,6 @@ The following problems are known and will be fixed in due time: @itemize @bullet @item -@code{ALTER TABLE} can't be used to change the @code{UNION} of a @code{MERGE} -table. For the moment, you should drop the MERGE table and create it again -if you need to change the @code{UNION}. -@item @code{mysqldump} on a @code{MERGE} table doesn't include the current mapped tables. @item diff --git a/merge/open.c b/merge/open.c index 2a3d815cd27..35005e6e718 100644 --- a/merge/open.c +++ b/merge/open.c @@ -62,7 +62,7 @@ int handle_locking; { if ((end=buff+length)[-1] == '\n') end[-1]='\0'; - if (buff[0]) /* Skipp empty lines */ + if (buff[0] && buff[0] != '#') /* Skipp empty lines and comments */ { last_isam=isam; if (!test_if_hard_path(buff)) diff --git a/myisam/mi_check.c b/myisam/mi_check.c index ee9e3387119..73738711188 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -1462,6 +1462,8 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name) reg1 MI_KEYDEF *keyinfo; File new_file; my_off_t index_pos[MI_MAX_POSSIBLE_KEY]; + uint r_locks,w_locks; + MYISAM_SHARE *share=info->s; DBUG_ENTER("sort_index"); if (!(param->testflag & T_SILENT)) @@ -1475,21 +1477,21 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name) param->temp_filename); DBUG_RETURN(-1); } - if (filecopy(param, new_file,info->s->kfile,0L, - (ulong) info->s->base.keystart, "headerblock")) + if (filecopy(param, new_file,share->kfile,0L, + (ulong) share->base.keystart, "headerblock")) goto err; - param->new_file_pos=info->s->base.keystart; - for (key= 0,keyinfo= &info->s->keyinfo[0]; key < info->s->base.keys ; + param->new_file_pos=share->base.keystart; + for (key= 0,keyinfo= &share->keyinfo[0]; key < share->base.keys ; key++,keyinfo++) { - if (!(((ulonglong) 1 << key) & info->s->state.key_map)) + if (!(((ulonglong) 1 << key) & share->state.key_map)) continue; - if (info->s->state.key_root[key] != HA_OFFSET_ERROR) + if (share->state.key_root[key] != HA_OFFSET_ERROR) { index_pos[key]=param->new_file_pos; /* Write first block here */ - if (sort_one_index(param,info,keyinfo,info->s->state.key_root[key], + if (sort_one_index(param,info,keyinfo,share->state.key_root[key], new_file)) goto err; } @@ -1498,19 +1500,24 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name) } /* Flush key cache for this file if we are calling this outside myisamchk */ - flush_key_blocks(info->s->kfile, FLUSH_IGNORE_CHANGED); + flush_key_blocks(share->kfile, FLUSH_IGNORE_CHANGED); /* Put same locks as old file */ - info->s->state.version=(ulong) time((time_t*) 0); - VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE)); - VOID(my_close(info->s->kfile,MYF(MY_WME))); - info->s->kfile = -1; + share->state.version=(ulong) time((time_t*) 0); + r_locks=share->r_locks; w_locks=share->w_locks; + share->r_locks=share->w_locks=0; + (void) _mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE); + VOID(my_close(share->kfile,MYF(MY_WME))); + share->kfile = -1; VOID(my_close(new_file,MYF(MY_WME))); - if (change_to_newfile(info->s->filename,MI_NAME_IEXT,INDEX_TMP_EXT,0, + if (change_to_newfile(share->filename,MI_NAME_IEXT,INDEX_TMP_EXT,0, MYF(0)) || - mi_open_keyfile(info->s)) + mi_open_keyfile(share)) goto err2; - _mi_readinfo(info,F_WRLCK,0); + info->lock_type=F_UNLCK; /* Force mi_readinfo to lock */ + _mi_readinfo(info,F_WRLCK,0); /* Will lock the table */ + info->lock_type=F_WRLCK; + share->r_locks=r_locks; share->w_locks=w_locks; info->state->key_file_length=param->new_file_pos; info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); diff --git a/myisammrg/myrg_info.c b/myisammrg/myrg_info.c index 304216a8276..8ca830339b9 100644 --- a/myisammrg/myrg_info.c +++ b/myisammrg/myrg_info.c @@ -52,8 +52,8 @@ int myrg_status(MYRG_INFO *info,register MYMERGE_INFO *x,int flag) info->data_file_length+=file->table->s->state.state.data_file_length; info->records+=file->table->s->state.state.records; info->del+=file->table->s->state.state.del; - DBUG_PRINT("info2",("table: %s, offset: 0x%08lx", - file->table->filename,(ulong)file->file_offset)); + DBUG_PRINT("info2",("table: %s, offset: %lu", + file->table->filename,(ulong) file->file_offset)); } x->records = info->records; x->deleted = info->del; diff --git a/myisammrg/myrg_rrnd.c b/myisammrg/myrg_rrnd.c index 77fe00a1bb1..46bd3850bb5 100644 --- a/myisammrg/myrg_rrnd.c +++ b/myisammrg/myrg_rrnd.c @@ -36,7 +36,7 @@ int myrg_rrnd(MYRG_INFO *info,byte *buf,ulonglong filepos) int error; MI_INFO *isam_info; DBUG_ENTER("myrg_rrnd"); - DBUG_PRINT("info",("offset: 0x%016qx", (ulonglong)filepos)); + DBUG_PRINT("info",("offset: %lu", (ulong) filepos)); if (filepos == HA_OFFSET_ERROR) { @@ -109,7 +109,7 @@ static MYRG_TABLE *find_table(MYRG_TABLE *start, MYRG_TABLE *end, else start=mid; } - DBUG_PRINT("info",("offset: 0x%016qx, table: %s", - (ulonglong)pos, start->table->filename)); + DBUG_PRINT("info",("offset: %lu, table: %s", + (ulong) pos, start->table->filename)); DBUG_RETURN(start); } diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result index 79c55e45342..1199cd07e2e 100644 --- a/mysql-test/r/distinct.result +++ b/mysql-test/r/distinct.result @@ -153,3 +153,17 @@ j_lj_t3 index id id 4 NULL 2 where used; Using index; Distinct t3_lj index id id 8 NULL 1 where used; Using index; Distinct id 2 +a sec_to_time(sum(time_to_sec(t))) +1 00:06:15 +1 00:36:30 +1 00:36:30 +a sec_to_time(sum(time_to_sec(t))) +1 00:06:15 +1 00:36:30 +a sec_to_time(sum(time_to_sec(t))) +1 00:06:15 +1 00:36:30 +1 00:36:30 +a sec_to_time(sum(time_to_sec(t))) +1 00:06:15 +1 00:36:30 diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index 5ef58bcef3f..aa9ea098e0a 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -106,4 +106,10 @@ incr othr 2 24 4 33 3 53 +count(*) +10 +count(*) +20 +count(*) +20 a diff --git a/mysql-test/t/distinct.test b/mysql-test/t/distinct.test index 9ddc7ac4a9b..29b2fddbe5f 100644 --- a/mysql-test/t/distinct.test +++ b/mysql-test/t/distinct.test @@ -182,3 +182,19 @@ WHERE ((t1.id=j_lj_t2.id AND t2_lj.id IS NULL) OR (t1.id=t2.id AND t2.idx=2)) AND ((t1.id=j_lj_t3.id AND t3_lj.id IS NULL) OR (t1.id=t3.id AND t3.idx=2)); drop table t1,t2,t3; + +# +# Test using DISTINCT on a function that contains a group function +# This also test the case when one doesn't use all fields in GROUP BY. +# + +drop table if exists t1; +create table t1 (a int not null, b int not null, t time); +insert into t1 values (1,1,"00:06:15"),(1,2,"00:06:15"),(1,2,"00:30:15"),(1,3,"00:06:15"),(1,3,"00:30:15"); +select a,sec_to_time(sum(time_to_sec(t))) from t1 group by a,b; +select distinct a,sec_to_time(sum(time_to_sec(t))) from t1 group by a,b; +create table t2 (a int not null primary key, b int); +insert into t2 values (1,1),(2,2),(3,3); +select t1.a,sec_to_time(sum(time_to_sec(t))) from t1 left join t2 on (t1.b=t2.a) group by t1.a,t2.b; +select distinct t1.a,sec_to_time(sum(time_to_sec(t))) from t1 left join t2 on (t1.b=t2.a) group by t1.a,t2.b; +drop table t1,t2; diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test index a3b2c8a11de..2f4482d9723 100644 --- a/mysql-test/t/merge.test +++ b/mysql-test/t/merge.test @@ -35,7 +35,8 @@ select a from t3 order by a desc limit 300,10; # The following should give errors create table t4 (a int not null, b char(10), key(a)) type=MERGE UNION=(t1,t2); -drop table if exists t1,t2,t3,t4; +# Because of windows, it's important that we drop the merge tables first! +drop table if exists t4,t3,t1,t2; create table t1 (c char(10)) type=myisam; create table t2 (c char(10)) type=myisam; @@ -70,6 +71,12 @@ INSERT INTO t1 VALUES (11,20),(13,43),(15,11),(17,22),(19,37); INSERT INTO t2 VALUES (12,25),(14,31),(16,42),(18,27),(10,30); SELECT * from t3 where incr in (1,2,3,4) order by othr; +alter table t3 UNION=(t1); +select count(*) from t3; +alter table t3 UNION=(t1,t2); +select count(*) from t3; +alter table t3 TYPE=MYISAM; +select count(*) from t3; drop table t3,t2,t1; # diff --git a/sql-bench/crash-me.sh b/sql-bench/crash-me.sh index a62e042ffda..2ce5c73c9b2 100644 --- a/sql-bench/crash-me.sh +++ b/sql-bench/crash-me.sh @@ -38,7 +38,7 @@ # as such, and clarify ones such as "mediumint" with comments such as # "3-byte int" or "same as xxx". -$version="1.54"; +$version="1.55"; use DBI; use Getopt::Long; @@ -1315,7 +1315,7 @@ report("default value for column",'create_default', "drop table crash_q $drop_attr"); report("default value function for column",'create_default_func', - "create table crash_q (q integer not null,q1 integer default (1+1)", + "create table crash_q (q integer not null,q1 integer default (1+1))", "drop table crash_q $drop_attr"); report("temporary tables",'temporary_table', @@ -1696,7 +1696,7 @@ if (!report("drop table with cascade/restrict","drop_restrict", report("-- as comment (ANSI)","comment_--", "select * from crash_me -- Testing of comments"); -report("// as comment (ANSI)","comment_//", +report("// as comment","comment_//", "select * from crash_me // Testing of comments"); report("# as comment","comment_#", "select * from crash_me # Testing of comments"); diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index 863054b4837..4c562282090 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -177,6 +177,7 @@ void ha_myisammrg::info(uint flag) errkey = info.errkey; table->keys_in_use=(((key_map) 1) << table->keys)- (key_map) 1; table->db_options_in_use = info.options; + table->is_view=1; mean_rec_length=info.reclength; block_size=0; update_time=0; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 1c236e19bda..375ba081f80 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -811,7 +811,7 @@ bool Item_sum_count_distinct::setup(THD *thd) for (uint i=0; i < arg_count ; i++) if (list.push_back(args[i])) return 1; - count_field_types(tmp_table_param,list); + count_field_types(tmp_table_param,list,0); if (table) { free_tmp_table(thd, table); diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 89e7faa237c..25bbe75e944 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -35,7 +35,7 @@ void mysql_create_db(THD *thd, char *db, uint create_options) long result=1; DBUG_ENTER("mysql_create_db"); - if (!stripp_sp(db) || strlen(db) > NAME_LEN || check_db_name(db)) + if (!stripp_sp(db) || check_db_name(db)) { net_printf(&thd->net,ER_WRONG_DB_NAME, db); DBUG_VOID_RETURN; @@ -103,7 +103,7 @@ void mysql_rm_db(THD *thd,char *db,bool if_exists) MY_DIR *dirp; DBUG_ENTER("mysql_rm_db"); - if (!stripp_sp(db) || strlen(db) > NAME_LEN || check_db_name(db)) + if (!stripp_sp(db) || check_db_name(db)) { net_printf(&thd->net,ER_WRONG_DB_NAME, db); DBUG_VOID_RETURN; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 2d8373ec067..526c78e0856 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -268,7 +268,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, join.first_record=join.sort_and_group=0; join.select_options=select_options; join.result=result; - count_field_types(&join.tmp_table_param,all_fields); + count_field_types(&join.tmp_table_param,all_fields,0); join.const_tables=0; join.having=0; join.group= group != 0; @@ -632,9 +632,14 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, /* ** If we have different sort & group then we must sort the data by group ** and copy it to another tmp table + ** This code is also used if we are using distinct something + ** we haven't been able to store in the temporary table yet + ** like SEC_TO_TIME(SUM(...)). */ - if (group && (!test_if_subpart(group,order) || select_distinct)) + if (group && (!test_if_subpart(group,order) || select_distinct) || + (select_distinct && + join.tmp_table_param.using_indirect_summary_function)) { /* Must copy to another table */ TABLE *tmp_table2; DBUG_PRINT("info",("Creating group table")); @@ -644,11 +649,16 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, if (make_simple_join(&join,tmp_table)) goto err; calc_group_buffer(&join,group); - count_field_types(&join.tmp_table_param,all_fields); + count_field_types(&join.tmp_table_param,all_fields, + select_distinct && !group); + join.tmp_table_param.hidden_field_count=(all_fields.elements- + fields.elements); /* group data to new table */ if (!(tmp_table2 = create_tmp_table(thd,&join.tmp_table_param,all_fields, - (ORDER*) 0, 0 , 1, 0, + (ORDER*) 0, + select_distinct && !group, + 1, 0, join.select_options))) goto err; /* purecov: inspected */ if (group) @@ -657,7 +667,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, if (create_sort_index(join.join_tab,group,HA_POS_ERROR) || alloc_group_fields(&join,group)) { - free_tmp_table(thd,tmp_table2); /* purecov: inspected */ + free_tmp_table(thd,tmp_table2); /* purecov: inspected */ goto err; /* purecov: inspected */ } group=0; @@ -696,14 +706,14 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, if (make_simple_join(&join,tmp_table)) goto err; calc_group_buffer(&join,group); - count_field_types(&join.tmp_table_param,all_fields); + count_field_types(&join.tmp_table_param,all_fields,0); } if (procedure) { if (procedure->change_columns(fields) || result->prepare(fields)) goto err; - count_field_types(&join.tmp_table_param,all_fields); + count_field_types(&join.tmp_table_param,all_fields,0); } if (join.group || join.tmp_table_param.sum_func_count || (procedure && (procedure->flags & PROC_GROUP))) @@ -3265,6 +3275,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, { 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; char *tmpname,path[FN_REFLEN]; @@ -3292,9 +3303,12 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, (*tmp->item)->marker=4; // Store null in key if (param->group_length >= MAX_BLOB_WIDTH) using_unique_constraint=1; + if (group) + distinct=0; // Can't use distinct } field_count=param->field_count+param->func_count+param->sum_func_count; + hidden_field_count=param->hidden_field_count; if (!my_multi_malloc(MYF(MY_WME), &table,sizeof(*table), ®_field,sizeof(Field*)*(field_count+1), @@ -3334,9 +3348,10 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, table->tmp_table=1; table->db_low_byte_first=1; // True for HEAP and MyISAM - /* Calculate with type of fields we will need in heap table */ + /* Calculate which type of fields we will store in the temporary table */ - reclength=blob_count=null_count=group_null_items=0; + reclength=blob_count=null_count=hidden_null_count=group_null_items=0; + param->using_indirect_summary_function=0; List_iterator<Item> li(fields); Item *item; @@ -3344,8 +3359,17 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, while ((item=li++)) { Item::Type type=item->type(); - if (item->with_sum_func && type != Item::SUM_FUNC_ITEM || - item->const_item()) + if (item->with_sum_func && type != Item::SUM_FUNC_ITEM) + { + /* + Mark that the we have ignored an item that refers to a summary + function. We need to know this if someone is going to use + DISTINCT on the result. + */ + param->using_indirect_summary_function=1; + continue; + } + if (item->const_item()) // We don't have to store this continue; if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields) { /* Can't calc group yet */ @@ -3396,6 +3420,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, } *(reg_field++) =new_field; } + if (!--hidden_field_count) + hidden_null_count=null_count; } field_count= (uint) (reg_field - table->field); @@ -3420,8 +3446,16 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, table->blob_fields=blob_count; if (blob_count == 0) - null_count++; // For delete link - reclength+=(null_pack_length=(null_count+7)/8); + { + /* We need to ensure that first byte is not 0 for the delete link */ + if (hidden_null_count) + hidden_null_count++; + else + null_count++; + } + hidden_null_pack_length=(hidden_null_count+7)/8; + null_pack_length=hidden_null_count+(null_count+7)/8; + reclength+=null_pack_length; if (!reclength) reclength=1; // Dummy select @@ -3449,6 +3483,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, bfill(null_flags,null_pack_length,255); // Set null fields } null_count= (blob_count == 0) ? 1 : 0; + hidden_field_count=param->hidden_field_count; for (i=0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++) { Field *field= *reg_field; @@ -3496,6 +3531,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, recinfo->type=FIELD_SKIPP_ENDSPACE; else recinfo->type=FIELD_NORMAL; + if (!--hidden_field_count) + null_count=(null_count+7) & ~7; // move to next byte } param->copy_field_count=(uint) (copy - param->copy_field); @@ -3559,11 +3596,17 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, } } - if (distinct && !group) + if (distinct) { - /* Create an unique key or an unique constraint over all columns */ - keyinfo->key_parts=field_count+ test(null_count); - if (distinct && allow_distinct_limit) + /* + Create an unique key or an unique constraint over all columns + that should be in the result. In the temporary table, there are + 'param->hidden_field_count' extra columns, whose null bits are stored + in the first 'hidden_null_pack_length' bytes of the row. + */ + null_pack_length-=hidden_null_pack_length; + keyinfo->key_parts=field_count+ test(null_pack_length); + if (allow_distinct_limit) { set_if_smaller(table->max_rows,thd->select_limit); param->end_write_records=thd->select_limit; @@ -3585,11 +3628,11 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, keyinfo->flags=HA_NOSAME; keyinfo->key_length=(uint16) reclength; keyinfo->name=(char*) "tmp"; - if (null_count) + if (null_pack_length) { key_part_info->null_bit=0; - key_part_info->offset=0; - key_part_info->length=(null_count+7)/8; + key_part_info->offset=hidden_null_pack_length; + key_part_info->length=null_pack_length; key_part_info->field=new Field_string((char*) table->record[0], (uint32) key_part_info->length, (uchar*) 0, @@ -3600,7 +3643,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, key_part_info->type= HA_KEYTYPE_BINARY; key_part_info++; } - for (i=0,reg_field=table->field; i < field_count; + for (i=param->hidden_field_count, reg_field=table->field + i ; + i < field_count; i++, reg_field++, key_part_info++) { key_part_info->null_bit=0; @@ -5917,13 +5961,14 @@ create_distinct_group(ORDER *order_list,List<Item> &fields) *****************************************************************************/ void -count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields) +count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields, + bool reset_with_sum_func) { List_iterator<Item> li(fields); Item *field; - param->field_count=param->sum_func_count= - param->func_count=0; + param->field_count=param->sum_func_count=param->func_count= + param->hidden_field_count=0; param->quick_group=1; while ((field=li++)) { @@ -5949,7 +5994,11 @@ count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields) } } else + { param->func_count++; + if (reset_with_sum_func) + field->with_sum_func=0; + } } } diff --git a/sql/sql_select.h b/sql/sql_select.h index 8ac00dde4c5..2f7454e4059 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -124,10 +124,13 @@ class TMP_TABLE_PARAM { KEY *keyinfo; ha_rows end_write_records; uint copy_field_count,field_count,sum_func_count,func_count; + uint hidden_field_count; uint group_parts,group_length; uint quick_group; + bool using_indirect_summary_function; - TMP_TABLE_PARAM() :copy_field(0), group_parts(0), group_length(0) {} + TMP_TABLE_PARAM() :copy_field(0), group_parts(0), group_length(0) + {} ~TMP_TABLE_PARAM() { cleanup(); @@ -178,7 +181,8 @@ TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ORDER *group, bool distinct, bool save_sum_fields, bool allow_distinct_limit, uint select_options); void free_tmp_table(THD *thd, TABLE *entry); -void count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields); +void count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields, + bool reset_with_sum_func); bool setup_copy_fields(TMP_TABLE_PARAM *param,List<Item> &fields); void copy_fields(TMP_TABLE_PARAM *param); void copy_funcs(Item_result_field **func_ptr); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 954a1f8efd7..9e720558456 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1443,10 +1443,13 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, thd->cuted_fields=0L; thd->proc_info="copy to tmp table"; next_insert_id=thd->next_insert_id; // Remember for loggin - error=copy_data_between_tables(table,new_table,create_list,handle_duplicates, - order, &copied,&deleted); + copied=deleted=0; + if (!new_table->is_view) + error=copy_data_between_tables(table,new_table,create_list, + handle_duplicates, + order, &copied, &deleted); thd->last_insert_id=next_insert_id; // Needed for correct log - thd->count_cuted_fields=0; /* Don`t calc cuted fields */ + thd->count_cuted_fields=0; // Don`t calc cuted fields new_table->time_stamp=save_time_stamp; if (table->tmp_table) diff --git a/sql/table.cc b/sql/table.cc index 762c28b0fbf..8ee6ee02d68 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1033,6 +1033,7 @@ char *get_field(MEM_ROOT *mem, TABLE *table, uint fieldnr) bool check_db_name(const char *name) { + const char *start=end; while (*name) { #if defined(USE_MB) && defined(USE_MB_IDENT) @@ -1050,7 +1051,7 @@ bool check_db_name(const char *name) return 1; name++; } - return 0; + return (uint) (name - start) > NAME_LEN; } diff --git a/sql/table.h b/sql/table.h index 8121271b479..c17a1eca830 100644 --- a/sql/table.h +++ b/sql/table.h @@ -93,6 +93,7 @@ struct st_table { my_bool locked_by_flush; my_bool locked_by_name; my_bool crashed; + my_bool is_view; Field *next_number_field, /* Set if next_number is activated */ *found_next_number_field, /* Set on open */ *rowid_field; |