Commit 184e24b2 authored by unknown's avatar unknown

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
parent 298ba0d3
...@@ -555,6 +555,7 @@ What Languages Are Supported by MySQL? ...@@ -555,6 +555,7 @@ What Languages Are Supported by MySQL?
* Character sets:: The character set used for data and sorting * Character sets:: The character set used for data and sorting
* Adding character set:: Adding a new character set * Adding character set:: Adding a new character set
* Character arrays::
* String collating:: String collating support * String collating:: String collating support
* Multi-byte characters:: Multi-byte character support * Multi-byte characters:: Multi-byte character support
...@@ -567,7 +568,7 @@ Replication in MySQL ...@@ -567,7 +568,7 @@ Replication in MySQL
* Replication Options:: Replication Options in my.cnf * Replication Options:: Replication Options in my.cnf
* Replication SQL:: SQL Commands related to replication * Replication SQL:: SQL Commands related to replication
* Replication FAQ:: Frequently Asked Questions about 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 Getting Maximum Performance from MySQL
...@@ -863,6 +864,7 @@ Changes in release 4.0.x (Development; Alpha) ...@@ -863,6 +864,7 @@ Changes in release 4.0.x (Development; Alpha)
Changes in release 3.23.x (Stable) 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.32:: Changes in release 3.23.32
* News-3.23.31:: Changes in release 3.23.31 * News-3.23.31:: Changes in release 3.23.31
* News-3.23.30:: Changes in release 3.23.30 * 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 ...@@ -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}. @uref{http://www.mysql.com/Downloads/Contrib/, Contrib directory}.
@cindex @code{Contrib} directory @cindex @code{Contrib} directory
@cindex URLs to MySQL information @cindex URLs to MySQL information
@cindex related information URLs @cindex related information URLs
@strong{MySQL} @strong{MySQL}
...@@ -2265,8 +2266,10 @@ The Mac OS Xclave. Running @strong{MySQL} on Mac OS X ...@@ -2265,8 +2266,10 @@ The Mac OS Xclave. Running @strong{MySQL} on Mac OS X
MySQL for Mac OS X Server. MySQL for Mac OS X Server.
@item @uref{http://www.latencyzero.com/macosx/mysql.html}@* @item @uref{http://www.latencyzero.com/macosx/mysql.html}@*
Bulding MySQL for Mac OS X 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/}@* @item @uref{http://www.lilback.com/macsql/}@*
Client libraries for the Macintosh. Client libraries for Mac OS Classic (Macintosh).
@end itemize @end itemize
@subheading Perl-related Links @subheading Perl-related Links
...@@ -2355,6 +2358,9 @@ MySQL-Databases, creating of new DBs and tables, editing etc. ...@@ -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}@* @item @uref{http://www.scibit.com/Products/Software/Utils/Mascon.asp}@*
Mascon is a powerful Win32 GUI for the administering MySQL server databases. 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 @end itemize
@subheading Distributions that Include MySQL @subheading Distributions that Include MySQL
...@@ -2555,9 +2561,21 @@ any MTA to deliver to users in a @strong{MySQL} database. ...@@ -2555,9 +2561,21 @@ any MTA to deliver to users in a @strong{MySQL} database.
@item @uref{http://www.pbc.ottawa.on.ca}@* @item @uref{http://www.pbc.ottawa.on.ca}@*
Visual Basic class generator for Active X. 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/}@* @item @uref{http://www.lilback.com/macsql/}@*
Client libraries for the Macintosh. 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 404 not found
@c @item @uref{http://tfdec1.fys.kuleuven.ac.be/~michael/fpc-linux/mysql}@* @c @item @uref{http://tfdec1.fys.kuleuven.ac.be/~michael/fpc-linux/mysql}@*
@c @strong{MySQL} binding to Free Pascal. @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 ...@@ -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 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 delete a file that is in use by another threads. (We may in the future
find some way to go around this problem). 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 @end table
Here are some open issues for anyone who might want to help us with the Windows 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: ...@@ -22713,6 +22738,7 @@ the outside of the @code{MySQL} server:
@example @example
shell> cd /mysql-data-directory/current-database shell> cd /mysql-data-directory/current-database
shell> ls -1 t1.MYI t2.MYI > total.MRG shell> ls -1 t1.MYI t2.MYI > total.MRG
shell> mysqladmin flush-tables
@end example @end example
Now you can do things like: Now you can do things like:
...@@ -22731,10 +22757,18 @@ mysql> select * from total; ...@@ -22731,10 +22757,18 @@ mysql> select * from total;
+---+---------+ +---+---------+
@end example @end example
To remap a @code{MERGE} table you must either @code{DROP} it and To remap a @code{MERGE} table you can do one of the following:
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 @itemize @bullet
handler to read the new definition file. @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 @cindex tables, ISAM
@node ISAM, HEAP, MERGE, Table types @node ISAM, HEAP, MERGE, Table types
...@@ -25456,6 +25490,7 @@ your changes with the new @file{errmsg.txt} file. ...@@ -25456,6 +25490,7 @@ your changes with the new @file{errmsg.txt} file.
@menu @menu
* Character sets:: The character set used for data and sorting * Character sets:: The character set used for data and sorting
* Adding character set:: Adding a new character set * Adding character set:: Adding a new character set
* Character arrays::
* String collating:: String collating support * String collating:: String collating support
* Multi-byte characters:: Multi-byte character support * Multi-byte characters:: Multi-byte character support
@end menu @end menu
...@@ -25514,28 +25549,52 @@ default-character-set=character-set-name ...@@ -25514,28 +25549,52 @@ default-character-set=character-set-name
but normally this is never needed. but normally this is never needed.
To add another character set to @strong{MySQL}, use the following procedure.
@cindex character sets, adding @cindex character sets, adding
@cindex adding, character sets @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 @subsection Adding a New Character Set
@enumerate To add another character set to @strong{MySQL}, use the following procedure.
@item
Choose a name for the character set, denoted @code{MYSET} below.
@item
Decide if the set is simple or complex. If the character set Decide if the set is simple or complex. If the character set
does not need to use special string collating routines for 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. 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 @item
If the character set is simple, then create the file Create the file @file{sql/share/charsets/MYSET.conf}.
@file{sql/share/charsets/MYSET.conf}, and add MYSET the (You can use @file{sql/share/charsets/latin1.conf} as a base for this).
@file{sql/share/charsets/Index} file. Read the
@file{sql/share/charsets/README} for more instructions. 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 @item
Add the character set name to the @code{CHARSETS_AVAILABLE} and 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 ...@@ -25544,20 +25603,28 @@ Add the character set name to the @code{CHARSETS_AVAILABLE} and
@item @item
Reconfigure, recompile, and test. Reconfigure, recompile, and test.
@end enumerate
For a complex character set do the following:
@enumerate
@item @item
If the character set is complex, create the file Create the file @file{strings/ctype-MYSET.c} in the @strong{MySQL} source
@file{strings/ctype-MYSET.c} in the @strong{MySQL} source distribution. distribution.
@item @item
Add MYSET to the end of the @file{sql/share/charsets/Index} file. Take Add MYSET to the end of the @file{sql/share/charsets/Index} file.
note of its position in the file - this is its character set number, Assign an unique number to it.
denoted @code{MYNUMBER} below.
@item @item
Look at one of the existing @file{ctype-*.c} files to see what needs to be Look at one of the existing @file{ctype-*.c} files to see what needs to
defined. Note that the arrays in your file must have names like be defined, for example @file{strings/ctype-big5.c}. Note that the
@code{ctype_MYSET}, @code{to_lower_MYSET}, and so on. 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: Near the top of the file, place a special comment like this:
@example @example
...@@ -25579,6 +25646,34 @@ the following sections. Only include them if you the string ...@@ -25579,6 +25646,34 @@ the following sections. Only include them if you the string
collating functions or the multi-byte character set functions, collating functions or the multi-byte character set functions,
respectively. 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 @code{to_lower[]} and @code{to_upper[]} are simple arrays that hold the
lowercase and uppercase characters corresponding to each member of the lowercase and uppercase characters corresponding to each member of the
character set. For example: character set. For example:
...@@ -25593,12 +25688,13 @@ comparison and sorting purposes. For many character sets, this is the same as ...@@ -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). @code{to_upper[]} (which means sorting will be case insensitive).
@strong{MySQL} will sort characters based on the value of @strong{MySQL} will sort characters based on the value of
@code{sort_order[character]}. For more complicated sorting rules, see @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. @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[]} (Note that @code{to_lower[]}, @code{to_upper[]}, and @code{sort_order[]}
are indexed by character value, but @code{ctype[]} is indexed by character 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.) 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}: You can find the following bitmask definitions in @file{m_ctype.h}:
@example @example
...@@ -25613,28 +25709,18 @@ You can find the following bitmask definitions in @file{m_ctype.h}: ...@@ -25613,28 +25709,18 @@ You can find the following bitmask definitions in @file{m_ctype.h}:
@end example @end example
The @code{ctype[]} entry for each character should be the union of the The @code{ctype[]} entry for each character should be the union of the
applicable bitmask values that describe the character. applicable bitmask values that describe the character. For example,
For example, @code{'A'} is an uppercase character (@code{_U}) as well as a @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: hexadecimal digit (@code{_X}), so @code{ctype['A'+1]} should contain the
value:
@example @example
_U + _X = 01 + 0200 = 0201 _U + _X = 01 + 0200 = 0201
@end example @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 collating, strings
@cindex string collating @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 @subsection String Collating Support
If the sorting rules for your language are too complex to be handled If the sorting rules for your language are too complex to be handled
...@@ -25647,7 +25733,7 @@ character sets for examples. ...@@ -25647,7 +25733,7 @@ character sets for examples.
You must specify the @code{strxfrm_multiply_MYSET=N} value in the 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 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). must be a positive integer).
@cindex characters, multi-byte @cindex characters, multi-byte
...@@ -25737,7 +25823,7 @@ tables}. ...@@ -25737,7 +25823,7 @@ tables}.
* Replication Options:: Replication Options in my.cnf * Replication Options:: Replication Options in my.cnf
* Replication SQL:: SQL Commands related to replication * Replication SQL:: SQL Commands related to replication
* Replication FAQ:: Frequently Asked Questions about 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 @end menu
@node Replication Intro, Replication Implementation, Replication, Replication @node Replication Intro, Replication Implementation, Replication, Replication
...@@ -33108,8 +33194,9 @@ symbols that start with @code{mysql_}, like the following: ...@@ -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 you should be able to solve this by adding @code{-Lpath-to-the-mysql-library
-lmysqlclient} @strong{LAST} on your link line. -lmysqlclient} @strong{LAST} on your link line.
If you get @code{undefined reference} errors for the @code{compress} function, If you get @code{undefined reference} errors for the @code{uncompress}
add @code{-lgz} @strong{LAST} on your link line and try again! 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 If you get @code{undefined reference} errors for functions that should
exist on your system, like @code{connect}, check the man page for the 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. ...@@ -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 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 recompile PHP with built-in @strong{MySQL} support. This is described in
detail in the PHP manual. 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 @end itemize
@cindex C++ APIs @cindex C++ APIs
...@@ -39875,6 +39966,8 @@ colour coding, dump functionality and much more. ...@@ -39875,6 +39966,8 @@ colour coding, dump functionality and much more.
@uref{http://www.scibit.com/Products/Software/Utils/Mascon.asp,Mascon home page}. @uref{http://www.scibit.com/Products/Software/Utils/Mascon.asp,Mascon home page}.
@item @uref{http://www.virtualbeer.net/dbui/,DBUI} @item @uref{http://www.virtualbeer.net/dbui/,DBUI}
DBUI is a Gtk graphical database editor. 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 @end itemize
@cindex Web clients @cindex Web clients
...@@ -40816,6 +40909,12 @@ not yet 100 % confident in this code. ...@@ -40816,6 +40909,12 @@ not yet 100 % confident in this code.
@appendixsubsec Changes in release 3.23.33 @appendixsubsec Changes in release 3.23.33
@itemize bullet @itemize bullet
@item @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 Fixed bug in replication that broke slave server start with existing
@code{master.info} - bug introduced in 3.23.32 @code{master.info} - bug introduced in 3.23.32
@item @item
...@@ -40840,6 +40939,13 @@ Fixed several timing bugs in the test suite ...@@ -40840,6 +40939,13 @@ Fixed several timing bugs in the test suite
@item @item
Extended @code{mysqltest} to take care of the timing issues in the test Extended @code{mysqltest} to take care of the timing issues in the test
suite. 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 @end itemize
...@@ -45514,10 +45620,6 @@ The following problems are known and will be fixed in due time: ...@@ -45514,10 +45620,6 @@ The following problems are known and will be fixed in due time:
@itemize @bullet @itemize @bullet
@item @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 @code{mysqldump} on a @code{MERGE} table doesn't include the current
mapped tables. mapped tables.
@item @item
...@@ -62,7 +62,7 @@ int handle_locking; ...@@ -62,7 +62,7 @@ int handle_locking;
{ {
if ((end=buff+length)[-1] == '\n') if ((end=buff+length)[-1] == '\n')
end[-1]='\0'; end[-1]='\0';
if (buff[0]) /* Skipp empty lines */ if (buff[0] && buff[0] != '#') /* Skipp empty lines and comments */
{ {
last_isam=isam; last_isam=isam;
if (!test_if_hard_path(buff)) if (!test_if_hard_path(buff))
......
...@@ -1462,6 +1462,8 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name) ...@@ -1462,6 +1462,8 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name)
reg1 MI_KEYDEF *keyinfo; reg1 MI_KEYDEF *keyinfo;
File new_file; File new_file;
my_off_t index_pos[MI_MAX_POSSIBLE_KEY]; my_off_t index_pos[MI_MAX_POSSIBLE_KEY];
uint r_locks,w_locks;
MYISAM_SHARE *share=info->s;
DBUG_ENTER("sort_index"); DBUG_ENTER("sort_index");
if (!(param->testflag & T_SILENT)) if (!(param->testflag & T_SILENT))
...@@ -1475,21 +1477,21 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name) ...@@ -1475,21 +1477,21 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name)
param->temp_filename); param->temp_filename);
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
if (filecopy(param, new_file,info->s->kfile,0L, if (filecopy(param, new_file,share->kfile,0L,
(ulong) info->s->base.keystart, "headerblock")) (ulong) share->base.keystart, "headerblock"))
goto err; goto err;
param->new_file_pos=info->s->base.keystart; param->new_file_pos=share->base.keystart;
for (key= 0,keyinfo= &info->s->keyinfo[0]; key < info->s->base.keys ; for (key= 0,keyinfo= &share->keyinfo[0]; key < share->base.keys ;
key++,keyinfo++) key++,keyinfo++)
{ {
if (!(((ulonglong) 1 << key) & info->s->state.key_map)) if (!(((ulonglong) 1 << key) & share->state.key_map))
continue; 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 */ 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)) new_file))
goto err; goto err;
} }
...@@ -1498,19 +1500,24 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name) ...@@ -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 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 */ /* Put same locks as old file */
info->s->state.version=(ulong) time((time_t*) 0); share->state.version=(ulong) time((time_t*) 0);
VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE)); r_locks=share->r_locks; w_locks=share->w_locks;
VOID(my_close(info->s->kfile,MYF(MY_WME))); share->r_locks=share->w_locks=0;
info->s->kfile = -1; (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))); 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)) || MYF(0)) ||
mi_open_keyfile(info->s)) mi_open_keyfile(share))
goto err2; 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->state->key_file_length=param->new_file_pos;
info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
......
...@@ -52,8 +52,8 @@ int myrg_status(MYRG_INFO *info,register MYMERGE_INFO *x,int flag) ...@@ -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->data_file_length+=file->table->s->state.state.data_file_length;
info->records+=file->table->s->state.state.records; info->records+=file->table->s->state.state.records;
info->del+=file->table->s->state.state.del; info->del+=file->table->s->state.state.del;
DBUG_PRINT("info2",("table: %s, offset: 0x%08lx", DBUG_PRINT("info2",("table: %s, offset: %lu",
file->table->filename,(ulong)file->file_offset)); file->table->filename,(ulong) file->file_offset));
} }
x->records = info->records; x->records = info->records;
x->deleted = info->del; x->deleted = info->del;
......
...@@ -36,7 +36,7 @@ int myrg_rrnd(MYRG_INFO *info,byte *buf,ulonglong filepos) ...@@ -36,7 +36,7 @@ int myrg_rrnd(MYRG_INFO *info,byte *buf,ulonglong filepos)
int error; int error;
MI_INFO *isam_info; MI_INFO *isam_info;
DBUG_ENTER("myrg_rrnd"); DBUG_ENTER("myrg_rrnd");
DBUG_PRINT("info",("offset: 0x%016qx", (ulonglong)filepos)); DBUG_PRINT("info",("offset: %lu", (ulong) filepos));
if (filepos == HA_OFFSET_ERROR) if (filepos == HA_OFFSET_ERROR)
{ {
...@@ -109,7 +109,7 @@ static MYRG_TABLE *find_table(MYRG_TABLE *start, MYRG_TABLE *end, ...@@ -109,7 +109,7 @@ static MYRG_TABLE *find_table(MYRG_TABLE *start, MYRG_TABLE *end,
else else
start=mid; start=mid;
} }
DBUG_PRINT("info",("offset: 0x%016qx, table: %s", DBUG_PRINT("info",("offset: %lu, table: %s",
(ulonglong)pos, start->table->filename)); (ulong) pos, start->table->filename));
DBUG_RETURN(start); DBUG_RETURN(start);
} }
...@@ -153,3 +153,17 @@ j_lj_t3 index id id 4 NULL 2 where used; Using index; Distinct ...@@ -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 t3_lj index id id 8 NULL 1 where used; Using index; Distinct
id id
2 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
...@@ -106,4 +106,10 @@ incr othr ...@@ -106,4 +106,10 @@ incr othr
2 24 2 24
4 33 4 33
3 53 3 53
count(*)
10
count(*)
20
count(*)
20
a a
...@@ -182,3 +182,19 @@ WHERE ...@@ -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)) ((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)); 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; 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;
...@@ -35,7 +35,8 @@ select a from t3 order by a desc limit 300,10; ...@@ -35,7 +35,8 @@ select a from t3 order by a desc limit 300,10;
# The following should give errors # The following should give errors
create table t4 (a int not null, b char(10), key(a)) type=MERGE UNION=(t1,t2); 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 t1 (c char(10)) type=myisam;
create table t2 (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); ...@@ -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); 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; 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; drop table t3,t2,t1;
# #
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
# as such, and clarify ones such as "mediumint" with comments such as # as such, and clarify ones such as "mediumint" with comments such as
# "3-byte int" or "same as xxx". # "3-byte int" or "same as xxx".
$version="1.54"; $version="1.55";
use DBI; use DBI;
use Getopt::Long; use Getopt::Long;
...@@ -1315,7 +1315,7 @@ report("default value for column",'create_default', ...@@ -1315,7 +1315,7 @@ report("default value for column",'create_default',
"drop table crash_q $drop_attr"); "drop table crash_q $drop_attr");
report("default value function for column",'create_default_func', 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"); "drop table crash_q $drop_attr");
report("temporary tables",'temporary_table', report("temporary tables",'temporary_table',
...@@ -1696,7 +1696,7 @@ if (!report("drop table with cascade/restrict","drop_restrict", ...@@ -1696,7 +1696,7 @@ if (!report("drop table with cascade/restrict","drop_restrict",
report("-- as comment (ANSI)","comment_--", report("-- as comment (ANSI)","comment_--",
"select * from crash_me -- Testing of comments"); "select * from crash_me -- Testing of comments");
report("// as comment (ANSI)","comment_//", report("// as comment","comment_//",
"select * from crash_me // Testing of comments"); "select * from crash_me // Testing of comments");
report("# as comment","comment_#", report("# as comment","comment_#",
"select * from crash_me # Testing of comments"); "select * from crash_me # Testing of comments");
......
...@@ -177,6 +177,7 @@ void ha_myisammrg::info(uint flag) ...@@ -177,6 +177,7 @@ void ha_myisammrg::info(uint flag)
errkey = info.errkey; errkey = info.errkey;
table->keys_in_use=(((key_map) 1) << table->keys)- (key_map) 1; table->keys_in_use=(((key_map) 1) << table->keys)- (key_map) 1;
table->db_options_in_use = info.options; table->db_options_in_use = info.options;
table->is_view=1;
mean_rec_length=info.reclength; mean_rec_length=info.reclength;
block_size=0; block_size=0;
update_time=0; update_time=0;
......
...@@ -811,7 +811,7 @@ bool Item_sum_count_distinct::setup(THD *thd) ...@@ -811,7 +811,7 @@ bool Item_sum_count_distinct::setup(THD *thd)
for (uint i=0; i < arg_count ; i++) for (uint i=0; i < arg_count ; i++)
if (list.push_back(args[i])) if (list.push_back(args[i]))
return 1; return 1;
count_field_types(tmp_table_param,list); count_field_types(tmp_table_param,list,0);
if (table) if (table)
{ {
free_tmp_table(thd, table); free_tmp_table(thd, table);
......
...@@ -35,7 +35,7 @@ void mysql_create_db(THD *thd, char *db, uint create_options) ...@@ -35,7 +35,7 @@ void mysql_create_db(THD *thd, char *db, uint create_options)
long result=1; long result=1;
DBUG_ENTER("mysql_create_db"); 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); net_printf(&thd->net,ER_WRONG_DB_NAME, db);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
...@@ -103,7 +103,7 @@ void mysql_rm_db(THD *thd,char *db,bool if_exists) ...@@ -103,7 +103,7 @@ void mysql_rm_db(THD *thd,char *db,bool if_exists)
MY_DIR *dirp; MY_DIR *dirp;
DBUG_ENTER("mysql_rm_db"); 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); net_printf(&thd->net,ER_WRONG_DB_NAME, db);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
......
...@@ -268,7 +268,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -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.first_record=join.sort_and_group=0;
join.select_options=select_options; join.select_options=select_options;
join.result=result; 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.const_tables=0;
join.having=0; join.having=0;
join.group= group != 0; join.group= group != 0;
...@@ -632,9 +632,14 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -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 ** If we have different sort & group then we must sort the data by group
** and copy it to another tmp table ** 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 */ { /* Must copy to another table */
TABLE *tmp_table2; TABLE *tmp_table2;
DBUG_PRINT("info",("Creating group table")); DBUG_PRINT("info",("Creating group table"));
...@@ -644,11 +649,16 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -644,11 +649,16 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
if (make_simple_join(&join,tmp_table)) if (make_simple_join(&join,tmp_table))
goto err; goto err;
calc_group_buffer(&join,group); 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 */ /* group data to new table */
if (!(tmp_table2 = create_tmp_table(thd,&join.tmp_table_param,all_fields, 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))) join.select_options)))
goto err; /* purecov: inspected */ goto err; /* purecov: inspected */
if (group) if (group)
...@@ -657,7 +667,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -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) || if (create_sort_index(join.join_tab,group,HA_POS_ERROR) ||
alloc_group_fields(&join,group)) 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 */ goto err; /* purecov: inspected */
} }
group=0; group=0;
...@@ -696,14 +706,14 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -696,14 +706,14 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
if (make_simple_join(&join,tmp_table)) if (make_simple_join(&join,tmp_table))
goto err; goto err;
calc_group_buffer(&join,group); 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)
{ {
if (procedure->change_columns(fields) || if (procedure->change_columns(fields) ||
result->prepare(fields)) result->prepare(fields))
goto err; 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 || if (join.group || join.tmp_table_param.sum_func_count ||
(procedure && (procedure->flags & PROC_GROUP))) (procedure && (procedure->flags & PROC_GROUP)))
...@@ -3265,6 +3275,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -3265,6 +3275,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
{ {
TABLE *table; TABLE *table;
uint i,field_count,reclength,null_count,null_pack_length, 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; blob_count,group_null_items;
bool using_unique_constraint=0; bool using_unique_constraint=0;
char *tmpname,path[FN_REFLEN]; char *tmpname,path[FN_REFLEN];
...@@ -3292,9 +3303,12 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -3292,9 +3303,12 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
(*tmp->item)->marker=4; // Store null in key (*tmp->item)->marker=4; // Store null in key
if (param->group_length >= MAX_BLOB_WIDTH) if (param->group_length >= MAX_BLOB_WIDTH)
using_unique_constraint=1; using_unique_constraint=1;
if (group)
distinct=0; // Can't use distinct
} }
field_count=param->field_count+param->func_count+param->sum_func_count; 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), if (!my_multi_malloc(MYF(MY_WME),
&table,sizeof(*table), &table,sizeof(*table),
&reg_field,sizeof(Field*)*(field_count+1), &reg_field,sizeof(Field*)*(field_count+1),
...@@ -3334,9 +3348,10 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -3334,9 +3348,10 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
table->tmp_table=1; table->tmp_table=1;
table->db_low_byte_first=1; // True for HEAP and MyISAM 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); List_iterator<Item> li(fields);
Item *item; Item *item;
...@@ -3344,8 +3359,17 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -3344,8 +3359,17 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
while ((item=li++)) while ((item=li++))
{ {
Item::Type type=item->type(); Item::Type type=item->type();
if (item->with_sum_func && type != Item::SUM_FUNC_ITEM || if (item->with_sum_func && type != Item::SUM_FUNC_ITEM)
item->const_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; continue;
if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields) if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields)
{ /* Can't calc group yet */ { /* Can't calc group yet */
...@@ -3396,6 +3420,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -3396,6 +3420,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
} }
*(reg_field++) =new_field; *(reg_field++) =new_field;
} }
if (!--hidden_field_count)
hidden_null_count=null_count;
} }
field_count= (uint) (reg_field - table->field); field_count= (uint) (reg_field - table->field);
...@@ -3420,8 +3446,16 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -3420,8 +3446,16 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
table->blob_fields=blob_count; table->blob_fields=blob_count;
if (blob_count == 0) 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) if (!reclength)
reclength=1; // Dummy select reclength=1; // Dummy select
...@@ -3449,6 +3483,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -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 bfill(null_flags,null_pack_length,255); // Set null fields
} }
null_count= (blob_count == 0) ? 1 : 0; 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++) for (i=0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++)
{ {
Field *field= *reg_field; Field *field= *reg_field;
...@@ -3496,6 +3531,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -3496,6 +3531,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
recinfo->type=FIELD_SKIPP_ENDSPACE; recinfo->type=FIELD_SKIPP_ENDSPACE;
else else
recinfo->type=FIELD_NORMAL; 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); 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, ...@@ -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); Create an unique key or an unique constraint over all columns
if (distinct && allow_distinct_limit) 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); set_if_smaller(table->max_rows,thd->select_limit);
param->end_write_records=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, ...@@ -3585,11 +3628,11 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
keyinfo->flags=HA_NOSAME; keyinfo->flags=HA_NOSAME;
keyinfo->key_length=(uint16) reclength; keyinfo->key_length=(uint16) reclength;
keyinfo->name=(char*) "tmp"; keyinfo->name=(char*) "tmp";
if (null_count) if (null_pack_length)
{ {
key_part_info->null_bit=0; key_part_info->null_bit=0;
key_part_info->offset=0; key_part_info->offset=hidden_null_pack_length;
key_part_info->length=(null_count+7)/8; key_part_info->length=null_pack_length;
key_part_info->field=new Field_string((char*) table->record[0], key_part_info->field=new Field_string((char*) table->record[0],
(uint32) key_part_info->length, (uint32) key_part_info->length,
(uchar*) 0, (uchar*) 0,
...@@ -3600,7 +3643,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -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->type= HA_KEYTYPE_BINARY;
key_part_info++; 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++) i++, reg_field++, key_part_info++)
{ {
key_part_info->null_bit=0; key_part_info->null_bit=0;
...@@ -5917,13 +5961,14 @@ create_distinct_group(ORDER *order_list,List<Item> &fields) ...@@ -5917,13 +5961,14 @@ create_distinct_group(ORDER *order_list,List<Item> &fields)
*****************************************************************************/ *****************************************************************************/
void 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); List_iterator<Item> li(fields);
Item *field; Item *field;
param->field_count=param->sum_func_count= param->field_count=param->sum_func_count=param->func_count=
param->func_count=0; param->hidden_field_count=0;
param->quick_group=1; param->quick_group=1;
while ((field=li++)) while ((field=li++))
{ {
...@@ -5949,7 +5994,11 @@ count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields) ...@@ -5949,7 +5994,11 @@ count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields)
} }
} }
else else
{
param->func_count++; param->func_count++;
if (reset_with_sum_func)
field->with_sum_func=0;
}
} }
} }
......
...@@ -124,10 +124,13 @@ class TMP_TABLE_PARAM { ...@@ -124,10 +124,13 @@ class TMP_TABLE_PARAM {
KEY *keyinfo; KEY *keyinfo;
ha_rows end_write_records; ha_rows end_write_records;
uint copy_field_count,field_count,sum_func_count,func_count; uint copy_field_count,field_count,sum_func_count,func_count;
uint hidden_field_count;
uint group_parts,group_length; uint group_parts,group_length;
uint quick_group; 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() ~TMP_TABLE_PARAM()
{ {
cleanup(); cleanup();
...@@ -178,7 +181,8 @@ TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -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, ORDER *group, bool distinct, bool save_sum_fields,
bool allow_distinct_limit, uint select_options); bool allow_distinct_limit, uint select_options);
void free_tmp_table(THD *thd, TABLE *entry); 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); bool setup_copy_fields(TMP_TABLE_PARAM *param,List<Item> &fields);
void copy_fields(TMP_TABLE_PARAM *param); void copy_fields(TMP_TABLE_PARAM *param);
void copy_funcs(Item_result_field **func_ptr); void copy_funcs(Item_result_field **func_ptr);
......
...@@ -1443,10 +1443,13 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -1443,10 +1443,13 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
thd->cuted_fields=0L; thd->cuted_fields=0L;
thd->proc_info="copy to tmp table"; thd->proc_info="copy to tmp table";
next_insert_id=thd->next_insert_id; // Remember for loggin next_insert_id=thd->next_insert_id; // Remember for loggin
error=copy_data_between_tables(table,new_table,create_list,handle_duplicates, copied=deleted=0;
order, &copied,&deleted); 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->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; new_table->time_stamp=save_time_stamp;
if (table->tmp_table) if (table->tmp_table)
......
...@@ -1033,6 +1033,7 @@ char *get_field(MEM_ROOT *mem, TABLE *table, uint fieldnr) ...@@ -1033,6 +1033,7 @@ char *get_field(MEM_ROOT *mem, TABLE *table, uint fieldnr)
bool check_db_name(const char *name) bool check_db_name(const char *name)
{ {
const char *start=end;
while (*name) while (*name)
{ {
#if defined(USE_MB) && defined(USE_MB_IDENT) #if defined(USE_MB) && defined(USE_MB_IDENT)
...@@ -1050,7 +1051,7 @@ bool check_db_name(const char *name) ...@@ -1050,7 +1051,7 @@ bool check_db_name(const char *name)
return 1; return 1;
name++; name++;
} }
return 0; return (uint) (name - start) > NAME_LEN;
} }
......
...@@ -93,6 +93,7 @@ struct st_table { ...@@ -93,6 +93,7 @@ struct st_table {
my_bool locked_by_flush; my_bool locked_by_flush;
my_bool locked_by_name; my_bool locked_by_name;
my_bool crashed; my_bool crashed;
my_bool is_view;
Field *next_number_field, /* Set if next_number is activated */ Field *next_number_field, /* Set if next_number is activated */
*found_next_number_field, /* Set on open */ *found_next_number_field, /* Set on open */
*rowid_field; *rowid_field;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment