diff options
39 files changed, 612 insertions, 341 deletions
diff --git a/client/Makefile.am b/client/Makefile.am index d3e96dd126f..d9d458fa31f 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -79,6 +79,8 @@ DEFS = -DUNDEF_THREADS_HACK \ -DDATADIR="\"$(localstatedir)\"" EXTRA_DIST = get_password.c CMakeLists.txt +EXTRA_DIST = get_password.c CMakeLists.txt + link_sources: for f in $(sql_src) ; do \ rm -f $$f; \ diff --git a/dbug/Makefile.am b/dbug/Makefile.am index 60a95a82be5..ee337b24b47 100644 --- a/dbug/Makefile.am +++ b/dbug/Makefile.am @@ -22,7 +22,8 @@ noinst_HEADERS = dbug_long.h libdbug_a_SOURCES = dbug.c sanity.c EXTRA_DIST = CMakeLists.txt example1.c example2.c example3.c \ user.r monty.doc dbug_add_tags.pl \ - my_main.c main.c factorial.c dbug_analyze.c + my_main.c main.c factorial.c dbug_analyze.c \ + CMakeLists.txt NROFF_INC = example1.r example2.r example3.r main.r \ factorial.r output1.r output2.r output3.r \ output4.r output5.r diff --git a/include/mysql_com.h b/include/mysql_com.h index f1c48112467..d0bf1b1fec0 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -26,6 +26,9 @@ #define USERNAME_LENGTH 16 #define SERVER_VERSION_LENGTH 60 #define SQLSTATE_LENGTH 5 +#define SYSTEM_CHARSET_MBMAXLEN 3 +#define NAME_BYTE_LEN NAME_LEN*SYSTEM_CHARSET_MBMAXLEN +#define USERNAME_BYTE_LENGTH USERNAME_LENGTH*SYSTEM_CHARSET_MBMAXLEN /* USER_HOST_BUFF_SIZE -- length of string buffer, that is enough to contain @@ -33,7 +36,7 @@ MySQL standard format: user_name_part@host_name_part\0 */ -#define USER_HOST_BUFF_SIZE HOSTNAME_LENGTH + USERNAME_LENGTH + 2 +#define USER_HOST_BUFF_SIZE HOSTNAME_LENGTH + USERNAME_BYTE_LENGTH + 2 #define LOCAL_HOST "localhost" #define LOCAL_HOST_NAMEDPIPE "." diff --git a/libmysql/mytest.c b/libmysql/mytest.c index e1acf3e2136..2d5c576b72a 100644 --- a/libmysql/mytest.c +++ b/libmysql/mytest.c @@ -1,103 +1,54 @@ -/*C4*/
+/*C4*/ +/****************************************************************/ +/* Author: Jethro Wright, III TS : 3/ 4/1998 9:15 */ +/* Date: 02/18/1998 */ +/* mytest.c : do some testing of the libmySQL.DLL.... */ +/* */ +/* History: */ +/* 02/18/1998 jw3 also sprach zarathustra.... */ +/****************************************************************/ -/****************************************************************/
-/* Author: Jethro Wright, III TS : 3/ 4/1998 9:15 */
+#include <windows.h> +#include <stdio.h> +#include <string.h> -/* Date: 02/18/1998 */
+#include <mysql.h> -/* mytest.c : do some testing of the libmySQL.DLL.... */
+#define DEFALT_SQL_STMT "SELECT * FROM db" +#ifndef offsetof +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#endif -/* */
-/* History: */
+/******************************************************** +** +** main :- +** +********************************************************/ -/* 02/18/1998 jw3 also sprach zarathustra.... */
- -/****************************************************************/
-
-
- - - -#include <windows.h>
- -#include <stdio.h>
- -#include <string.h>
-
- - -#include <mysql.h>
-
- - -#define DEFALT_SQL_STMT "SELECT * FROM db"
- -#ifndef offsetof
- -#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
- -#endif
-
-
- - - -/********************************************************
- -**
- -** main :-
- -**
- -********************************************************/
-
- - -int
- -main( int argc, char * argv[] )
- -{
-
- - - char szSQL[ 200 ], aszFlds[ 25 ][ 25 ], szDB[ 50 ] ;
+int +main( int argc, char * argv[] ) +{ + char szSQL[ 200 ], aszFlds[ 25 ][ 25 ], szDB[ 50 ] ; const char *pszT; - int i, j, k, l, x ;
- - MYSQL * myData ;
- - MYSQL_RES * res ;
- - MYSQL_FIELD * fd ;
- - MYSQL_ROW row ;
-
- - - //....just curious....
+ int i, j, k, l, x ; + MYSQL * myData ; + MYSQL_RES * res ; + MYSQL_FIELD * fd ; + MYSQL_ROW row ; + //....just curious.... printf( "sizeof( MYSQL ) == %d\n", (int) sizeof( MYSQL ) ) ; - if ( argc == 2 )
- - {
- - strcpy( szDB, argv[ 1 ] ) ;
- - strcpy( szSQL, DEFALT_SQL_STMT ) ;
- - if (!strcmp(szDB,"--debug"))
- - {
- - strcpy( szDB, "mysql" ) ;
- - printf("Some mysql struct information (size and offset):\n");
- + if ( argc == 2 ) + { + strcpy( szDB, argv[ 1 ] ) ; + strcpy( szSQL, DEFALT_SQL_STMT ) ; + if (!strcmp(szDB,"--debug")) + { + strcpy( szDB, "mysql" ) ; + printf("Some mysql struct information (size and offset):\n"); printf("net:\t%3d %3d\n",(int) sizeof(myData->net), (int) offsetof(MYSQL,net)); printf("host:\t%3d %3d\n",(int) sizeof(myData->host), @@ -123,200 +74,102 @@ main( int argc, char * argv[] ) (int) offsetof(MYSQL,free_me)); printf("options:\t%3d %3d\n",(int) sizeof(myData->options), (int) offsetof(MYSQL,options)); - puts("");
- - }
- - }
- - else if ( argc > 2 ) {
- - strcpy( szDB, argv[ 1 ] ) ;
- - strcpy( szSQL, argv[ 2 ] ) ;
- - }
- - else {
- - strcpy( szDB, "mysql" ) ;
- - strcpy( szSQL, DEFALT_SQL_STMT ) ;
- - }
- - //....
- -
- - if ( (myData = mysql_init((MYSQL*) 0)) &&
- - mysql_real_connect( myData, NULL, NULL, NULL, NULL, MYSQL_PORT,
- - NULL, 0 ) )
- - {
- + puts(""); + } + } + else if ( argc > 2 ) { + strcpy( szDB, argv[ 1 ] ) ; + strcpy( szSQL, argv[ 2 ] ) ; + } + else { + strcpy( szDB, "mysql" ) ; + strcpy( szSQL, DEFALT_SQL_STMT ) ; + } + //.... + + if ( (myData = mysql_init((MYSQL*) 0)) && + mysql_real_connect( myData, NULL, NULL, NULL, NULL, MYSQL_PORT, + NULL, 0 ) ) + { myData->reconnect= 1; - if ( mysql_select_db( myData, szDB ) < 0 ) {
- - printf( "Can't select the %s database !\n", szDB ) ;
- - mysql_close( myData ) ;
- - return 2 ;
- - }
- - }
- - else {
- - printf( "Can't connect to the mysql server on port %d !\n",
- - MYSQL_PORT ) ;
- - mysql_close( myData ) ;
- - return 1 ;
- - }
- - //....
- - if ( ! mysql_query( myData, szSQL ) ) {
- - res = mysql_store_result( myData ) ;
- - i = (int) mysql_num_rows( res ) ; l = 1 ;
- - printf( "Query: %s\nNumber of records found: %ld\n", szSQL, i ) ;
- - //....we can get the field-specific characteristics here....
- - for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ )
- - strcpy( aszFlds[ x ], fd->name ) ;
- - //....
- - while ( row = mysql_fetch_row( res ) ) {
- - j = mysql_num_fields( res ) ;
- - printf( "Record #%ld:-\n", l++ ) ;
- - for ( k = 0 ; k < j ; k++ )
- - printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ],
- - (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ;
- - puts( "==============================\n" ) ;
- - }
- - mysql_free_result( res ) ;
- - }
- - else printf( "Couldn't execute %s on the server !\n", szSQL ) ;
- - //....
- - puts( "==== Diagnostic info ====" ) ;
- - pszT = mysql_get_client_info() ;
- - printf( "Client info: %s\n", pszT ) ;
- - //....
- - pszT = mysql_get_host_info( myData ) ;
- - printf( "Host info: %s\n", pszT ) ;
- - //....
- - pszT = mysql_get_server_info( myData ) ;
- - printf( "Server info: %s\n", pszT ) ;
- - //....
- - res = mysql_list_processes( myData ) ; l = 1 ;
- - if (res)
- - {
- - for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ )
- - strcpy( aszFlds[ x ], fd->name ) ;
- - while ( row = mysql_fetch_row( res ) ) {
- - j = mysql_num_fields( res ) ;
- - printf( "Process #%ld:-\n", l++ ) ;
- - for ( k = 0 ; k < j ; k++ )
- - printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ],
- - (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ;
- - puts( "==============================\n" ) ;
- - }
- - }
- - else
- - {
- - printf("Got error %s when retreiving processlist\n",mysql_error(myData));
- - }
- - //....
- - res = mysql_list_tables( myData, "%" ) ; l = 1 ;
- - for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ )
- - strcpy( aszFlds[ x ], fd->name ) ;
- - while ( row = mysql_fetch_row( res ) ) {
- - j = mysql_num_fields( res ) ;
- - printf( "Table #%ld:-\n", l++ ) ;
- - for ( k = 0 ; k < j ; k++ )
- - printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ],
- - (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ;
- - puts( "==============================\n" ) ;
- - }
- - //....
- - pszT = mysql_stat( myData ) ;
- - puts( pszT ) ;
- - //....
- - mysql_close( myData ) ;
- - return 0 ;
-
- - -}
- + if ( mysql_select_db( myData, szDB ) < 0 ) { + printf( "Can't select the %s database !\n", szDB ) ; + mysql_close( myData ) ; + return 2 ; + } + } + else { + printf( "Can't connect to the mysql server on port %d !\n", + MYSQL_PORT ) ; + mysql_close( myData ) ; + return 1 ; + } + //.... + if ( ! mysql_query( myData, szSQL ) ) { + res = mysql_store_result( myData ) ; + i = (int) mysql_num_rows( res ) ; l = 1 ; + printf( "Query: %s\nNumber of records found: %ld\n", szSQL, i ) ; + //....we can get the field-specific characteristics here.... + for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ ) + strcpy( aszFlds[ x ], fd->name ) ; + //.... + while ( row = mysql_fetch_row( res ) ) { + j = mysql_num_fields( res ) ; + printf( "Record #%ld:-\n", l++ ) ; + for ( k = 0 ; k < j ; k++ ) + printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ], + (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ; + puts( "==============================\n" ) ; + } + mysql_free_result( res ) ; + } + else printf( "Couldn't execute %s on the server !\n", szSQL ) ; + //.... + puts( "==== Diagnostic info ====" ) ; + pszT = mysql_get_client_info() ; + printf( "Client info: %s\n", pszT ) ; + //.... + pszT = mysql_get_host_info( myData ) ; + printf( "Host info: %s\n", pszT ) ; + //.... + pszT = mysql_get_server_info( myData ) ; + printf( "Server info: %s\n", pszT ) ; + //.... + res = mysql_list_processes( myData ) ; l = 1 ; + if (res) + { + for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ ) + strcpy( aszFlds[ x ], fd->name ) ; + while ( row = mysql_fetch_row( res ) ) { + j = mysql_num_fields( res ) ; + printf( "Process #%ld:-\n", l++ ) ; + for ( k = 0 ; k < j ; k++ ) + printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ], + (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ; + puts( "==============================\n" ) ; + } + } + else + { + printf("Got error %s when retreiving processlist\n",mysql_error(myData)); + } + //.... + res = mysql_list_tables( myData, "%" ) ; l = 1 ; + for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ ) + strcpy( aszFlds[ x ], fd->name ) ; + while ( row = mysql_fetch_row( res ) ) { + j = mysql_num_fields( res ) ; + printf( "Table #%ld:-\n", l++ ) ; + for ( k = 0 ; k < j ; k++ ) + printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ], + (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ; + puts( "==============================\n" ) ; + } + //.... + pszT = mysql_stat( myData ) ; + puts( pszT ) ; + //.... + mysql_close( myData ) ; + return 0 ; + +} diff --git a/mysql-test/include/loaddata_autocom.inc b/mysql-test/include/loaddata_autocom.inc new file mode 100644 index 00000000000..e5071c73c49 --- /dev/null +++ b/mysql-test/include/loaddata_autocom.inc @@ -0,0 +1,21 @@ +# Test if the engine does autocommit in LOAD DATA INFILE, or not +# (NDB wants to do, others don't). + +eval SET SESSION STORAGE_ENGINE = $engine_type; + +--disable_warnings +drop table if exists t1; +--enable_warnings + +create table t1 (a text, b text); +start transaction; +load data infile '../std_data_ln/loaddata2.dat' into table t1 fields terminated by ',' enclosed by ''''; +commit; +select count(*) from t1; +truncate table t1; +start transaction; +load data infile '../std_data_ln/loaddata2.dat' into table t1 fields terminated by ',' enclosed by ''''; +rollback; +select count(*) from t1; + +drop table t1; diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 2b9602215fb..f5e4054a385 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -1340,6 +1340,19 @@ select a from t1 group by a; a e drop table t1; +set names utf8; +grant select on test.* to юзер_юзер@localhost; +user() +юзер_юзер@localhost +revoke all on test.* from юзер_юзер@localhost; +drop user юзер_юзер@localhost; +create database имя_базы_в_кодировке_утф8_длиной_больше_чем_45; +use имя_базы_в_кодировке_утф8_длиной_больше_чем_45; +select database(); +database() +имя_базы_в_кодировке_утф8_длиной_больше_чем_45 +drop database имя_базы_в_кодировке_утф8_длиной_больше_чем_45; +use test; CREATE TABLE t1(id varchar(20) NOT NULL) DEFAULT CHARSET=utf8; INSERT INTO t1 VALUES ('xxx'), ('aa'), ('yyy'), ('aa'); SELECT id FROM t1; diff --git a/mysql-test/r/limit.result b/mysql-test/r/limit.result index 1e38f762dd1..be2776ef533 100644 --- a/mysql-test/r/limit.result +++ b/mysql-test/r/limit.result @@ -76,3 +76,17 @@ a a 1 drop table t1; +create table t1 (a int); +insert into t1 values (1),(2),(3),(4),(5),(6),(7); +explain select count(*) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 7 Using where; Using temporary +select count(*) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3; +c +7 +explain select sum(a) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 7 Using where; Using temporary +select sum(a) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3; +c +28 diff --git a/mysql-test/r/loaddata_autocom_innodb.result b/mysql-test/r/loaddata_autocom_innodb.result new file mode 100644 index 00000000000..10da6b5dde7 --- /dev/null +++ b/mysql-test/r/loaddata_autocom_innodb.result @@ -0,0 +1,21 @@ +SET SESSION STORAGE_ENGINE = InnoDB; +drop table if exists t1; +create table t1 (a text, b text); +start transaction; +load data infile '../std_data_ln/loaddata2.dat' into table t1 fields terminated by ',' enclosed by ''''; +Warnings: +Warning 1261 Row 3 doesn't contain data for all columns +commit; +select count(*) from t1; +count(*) +4 +truncate table t1; +start transaction; +load data infile '../std_data_ln/loaddata2.dat' into table t1 fields terminated by ',' enclosed by ''''; +Warnings: +Warning 1261 Row 3 doesn't contain data for all columns +rollback; +select count(*) from t1; +count(*) +0 +drop table t1; diff --git a/mysql-test/r/loaddata_autocom_ndb.result b/mysql-test/r/loaddata_autocom_ndb.result new file mode 100644 index 00000000000..94e5f825fa2 --- /dev/null +++ b/mysql-test/r/loaddata_autocom_ndb.result @@ -0,0 +1,23 @@ +SET SESSION STORAGE_ENGINE = ndbcluster; +drop table if exists t1; +create table t1 (a text, b text); +start transaction; +load data infile '../std_data_ln/loaddata2.dat' into table t1 fields terminated by ',' enclosed by ''''; +Warnings: +Warning 1261 Row 3 doesn't contain data for all columns +commit; +select count(*) from t1; +count(*) +4 +truncate table t1; +start transaction; +load data infile '../std_data_ln/loaddata2.dat' into table t1 fields terminated by ',' enclosed by ''''; +Warnings: +Warning 1261 Row 3 doesn't contain data for all columns +rollback; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +select count(*) from t1; +count(*) +4 +drop table t1; diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index 703d92979f1..684d216f856 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -949,18 +949,24 @@ COUNT(*) Warnings: Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1 Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1 +Warning 1292 Truncated incorrect DOUBLE value: '20050327 invalid' +Warning 1292 Truncated incorrect DOUBLE value: '20050327 invalid' SELECT COUNT(*) FROM t1 WHERE date BETWEEN '20050326' AND '20050328 invalid'; COUNT(*) 0 Warnings: Warning 1292 Incorrect datetime value: '20050328 invalid' for column 'date' at row 1 Warning 1292 Incorrect datetime value: '20050328 invalid' for column 'date' at row 1 +Warning 1292 Truncated incorrect DOUBLE value: '20050328 invalid' +Warning 1292 Truncated incorrect DOUBLE value: '20050328 invalid' SELECT COUNT(*) FROM t1 WHERE date BETWEEN '20050326' AND '20050327 invalid'; COUNT(*) 0 Warnings: Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1 Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1 +Warning 1292 Truncated incorrect DOUBLE value: '20050327 invalid' +Warning 1292 Truncated incorrect DOUBLE value: '20050327 invalid' show status like "Qcache_queries_in_cache"; Variable_name Value Qcache_queries_in_cache 0 diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result index 776a86ad2d5..4141e6061d2 100644 --- a/mysql-test/r/range.result +++ b/mysql-test/r/range.result @@ -896,3 +896,48 @@ EXPLAIN SELECT * FROM t1 WHERE 0 NOT BETWEEN b AND c; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge idx1,idx2 idx1,idx2 4,4 NULL 4 Using sort_union(idx1,idx2); Using where DROP TABLE t1; +CREATE TABLE t1 ( +item char(20) NOT NULL default '', +started datetime NOT NULL default '0000-00-00 00:00:00', +price decimal(16,3) NOT NULL default '0.000', +PRIMARY KEY (item,started) +) ENGINE=MyISAM; +INSERT INTO t1 VALUES +('A1','2005-11-01 08:00:00',1000), +('A1','2005-11-15 00:00:00',2000), +('A1','2005-12-12 08:00:00',3000), +('A2','2005-12-01 08:00:00',1000); +EXPLAIN SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref PRIMARY PRIMARY 20 const 2 Using where +Warnings: +Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1 +Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1 +SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00'; +item started price +A1 2005-11-01 08:00:00 1000.000 +A1 2005-11-15 00:00:00 2000.000 +Warnings: +Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1 +Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1 +SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-02 00:00:00'; +item started price +A1 2005-11-01 08:00:00 1000.000 +A1 2005-11-15 00:00:00 2000.000 +DROP INDEX `PRIMARY` ON t1; +EXPLAIN SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where +Warnings: +Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1 +SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00'; +item started price +A1 2005-11-01 08:00:00 1000.000 +A1 2005-11-15 00:00:00 2000.000 +Warnings: +Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1 +SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-02 00:00:00'; +item started price +A1 2005-11-01 08:00:00 1000.000 +A1 2005-11-15 00:00:00 2000.000 +DROP TABLE t1; diff --git a/mysql-test/r/rpl_ndb_innodb_trans.result b/mysql-test/r/rpl_ndb_innodb_trans.result new file mode 100644 index 00000000000..148e6247b03 --- /dev/null +++ b/mysql-test/r/rpl_ndb_innodb_trans.result @@ -0,0 +1,103 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; +create table t1 (a int, unique(a)) engine=ndbcluster; +create table t2 (a int, unique(a)) engine=innodb; +begin; +insert into t1 values(1); +insert into t2 values(1); +rollback; +select count(*) from t1; +count(*) +0 +select count(*) from t2; +count(*) +0 +select count(*) from t1; +count(*) +0 +select count(*) from t2; +count(*) +0 +begin; +load data infile '../std_data_ln/rpl_loaddata.dat' into table t2; +Warnings: +Warning 1262 Row 1 was truncated; it contained more data than there were input columns +Warning 1262 Row 2 was truncated; it contained more data than there were input columns +load data infile '../std_data_ln/rpl_loaddata.dat' into table t1; +Warnings: +Warning 1262 Row 1 was truncated; it contained more data than there were input columns +Warning 1262 Row 2 was truncated; it contained more data than there were input columns +rollback; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +select count(*) from t1; +count(*) +2 +select count(*) from t2; +count(*) +0 +select count(*) from t1; +count(*) +2 +select count(*) from t2; +count(*) +0 +delete from t1; +delete from t2; +begin; +load data infile '../std_data_ln/rpl_loaddata.dat' into table t2; +Warnings: +Warning 1262 Row 1 was truncated; it contained more data than there were input columns +Warning 1262 Row 2 was truncated; it contained more data than there were input columns +load data infile '../std_data_ln/rpl_loaddata.dat' into table t1; +Warnings: +Warning 1262 Row 1 was truncated; it contained more data than there were input columns +Warning 1262 Row 2 was truncated; it contained more data than there were input columns +rollback; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +select count(*) from t1; +count(*) +2 +select count(*) from t2; +count(*) +0 +select count(*) from t1; +count(*) +2 +select count(*) from t2; +count(*) +0 +delete from t1; +delete from t2; +begin; +insert into t2 values(3),(4); +insert into t1 values(3),(4); +load data infile '../std_data_ln/rpl_loaddata.dat' into table t2; +Warnings: +Warning 1262 Row 1 was truncated; it contained more data than there were input columns +Warning 1262 Row 2 was truncated; it contained more data than there were input columns +load data infile '../std_data_ln/rpl_loaddata.dat' into table t1; +Warnings: +Warning 1262 Row 1 was truncated; it contained more data than there were input columns +Warning 1262 Row 2 was truncated; it contained more data than there were input columns +rollback; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +select count(*) from t1; +count(*) +4 +select count(*) from t2; +count(*) +0 +select count(*) from t1; +count(*) +4 +select count(*) from t2; +count(*) +0 +drop table t1,t2; diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index 5e3a3f640b1..54ded650a1e 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -1069,6 +1069,23 @@ explain select a from t1 group by a; select a from t1 group by a; drop table t1; +# +# Bug#20393: User name truncation in mysql client +# Bug#21432: Database/Table name limited to 64 bytes, not chars, problems with multi-byte +# +set names utf8; +#create user юзер_юзер@localhost; +grant select on test.* to юзер_юзер@localhost; +--exec $MYSQL --default-character-set=utf8 --user=юзер_юзер -e "select user()" +revoke all on test.* from юзер_юзер@localhost; +drop user юзер_юзер@localhost; + +create database имя_базы_в_кодировке_утф8_длиной_больше_чем_45; +use имя_базы_в_кодировке_утф8_длиной_больше_чем_45; +select database(); +drop database имя_базы_в_кодировке_утф8_длиной_больше_чем_45; +use test; + # End of 4.1 tests # diff --git a/mysql-test/t/limit.test b/mysql-test/t/limit.test index 6df865278f6..cf7789428b2 100644 --- a/mysql-test/t/limit.test +++ b/mysql-test/t/limit.test @@ -60,4 +60,14 @@ select 1 as a from t1 union all select 1 from dual limit 1; (select 1 as a from t1) union all (select 1 from dual) limit 1; drop table t1; +# +# Bug #21787: COUNT(*) + ORDER BY + LIMIT returns wrong result +# +create table t1 (a int); +insert into t1 values (1),(2),(3),(4),(5),(6),(7); +explain select count(*) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3; +select count(*) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3; +explain select sum(a) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3; +select sum(a) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3; + # End of 4.1 tests diff --git a/mysql-test/t/loaddata_autocom_innodb.test b/mysql-test/t/loaddata_autocom_innodb.test new file mode 100644 index 00000000000..d7f152cb286 --- /dev/null +++ b/mysql-test/t/loaddata_autocom_innodb.test @@ -0,0 +1,4 @@ +--source include/have_innodb.inc +let $engine_type= InnoDB; + +--source include/loaddata_autocom.inc diff --git a/mysql-test/t/loaddata_autocom_ndb.test b/mysql-test/t/loaddata_autocom_ndb.test new file mode 100644 index 00000000000..f4a6743aabe --- /dev/null +++ b/mysql-test/t/loaddata_autocom_ndb.test @@ -0,0 +1,4 @@ +--source include/have_ndb.inc +let $engine_type=ndbcluster; + +--source include/loaddata_autocom.inc diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test index 735d3f11359..89508f468a7 100644 --- a/mysql-test/t/range.test +++ b/mysql-test/t/range.test @@ -709,5 +709,34 @@ EXPLAIN SELECT * FROM t1 WHERE 0 NOT BETWEEN b AND c; DROP TABLE t1; +# +# Bug #16249: different results for a range with an without index +# when a range condition use an invalid datetime constant +# + +CREATE TABLE t1 ( + item char(20) NOT NULL default '', + started datetime NOT NULL default '0000-00-00 00:00:00', + price decimal(16,3) NOT NULL default '0.000', + PRIMARY KEY (item,started) +) ENGINE=MyISAM; + +INSERT INTO t1 VALUES +('A1','2005-11-01 08:00:00',1000), +('A1','2005-11-15 00:00:00',2000), +('A1','2005-12-12 08:00:00',3000), +('A2','2005-12-01 08:00:00',1000); + +EXPLAIN SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00'; +SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00'; +SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-02 00:00:00'; + +DROP INDEX `PRIMARY` ON t1; + +EXPLAIN SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00'; +SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00'; +SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-02 00:00:00'; + +DROP TABLE t1; # End of 5.0 tests diff --git a/mysql-test/t/rpl_ndb_innodb_trans-slave.opt b/mysql-test/t/rpl_ndb_innodb_trans-slave.opt new file mode 100644 index 00000000000..627becdbfb5 --- /dev/null +++ b/mysql-test/t/rpl_ndb_innodb_trans-slave.opt @@ -0,0 +1 @@ +--innodb diff --git a/mysql-test/t/rpl_ndb_innodb_trans.test b/mysql-test/t/rpl_ndb_innodb_trans.test new file mode 100644 index 00000000000..127c2464570 --- /dev/null +++ b/mysql-test/t/rpl_ndb_innodb_trans.test @@ -0,0 +1,66 @@ +# Test of a transaction mixing the two engines + +-- source include/have_ndb.inc +-- source include/have_innodb.inc +-- source include/master-slave.inc + +create table t1 (a int, unique(a)) engine=ndbcluster; +create table t2 (a int, unique(a)) engine=innodb; + + +begin; +insert into t1 values(1); +insert into t2 values(1); +rollback; + +select count(*) from t1; +select count(*) from t2; +sync_slave_with_master; +select count(*) from t1; +select count(*) from t2; +connection master; + +begin; +load data infile '../std_data_ln/rpl_loaddata.dat' into table t2; +load data infile '../std_data_ln/rpl_loaddata.dat' into table t1; +rollback; + +select count(*) from t1; +select count(*) from t2; +sync_slave_with_master; +select count(*) from t1; +select count(*) from t2; +connection master; + +delete from t1; +delete from t2; +begin; +load data infile '../std_data_ln/rpl_loaddata.dat' into table t2; +load data infile '../std_data_ln/rpl_loaddata.dat' into table t1; +rollback; + +select count(*) from t1; +select count(*) from t2; +sync_slave_with_master; +select count(*) from t1; +select count(*) from t2; +connection master; + +delete from t1; +delete from t2; +begin; +insert into t2 values(3),(4); +insert into t1 values(3),(4); +load data infile '../std_data_ln/rpl_loaddata.dat' into table t2; +load data infile '../std_data_ln/rpl_loaddata.dat' into table t1; +rollback; + +select count(*) from t1; +select count(*) from t2; +sync_slave_with_master; +select count(*) from t1; +select count(*) from t2; +connection master; + +drop table t1,t2; +sync_slave_with_master; diff --git a/server-tools/instance-manager/Makefile.am b/server-tools/instance-manager/Makefile.am index 4719828081a..cf296266843 100644 --- a/server-tools/instance-manager/Makefile.am +++ b/server-tools/instance-manager/Makefile.am @@ -18,7 +18,8 @@ INCLUDES= @ZLIB_INCLUDES@ -I$(top_srcdir)/include \ @openssl_includes@ -I$(top_builddir)/include DEFS= -DMYSQL_INSTANCE_MANAGER -DMYSQL_SERVER - +EXTRA_DIST = IMService.cpp IMService.h WindowsService.cpp WindowsService.h \ + CMakeLists.txt # As all autoconf variables depend from ${prefix} and being resolved only when # make is run, we can not put these defines to a header file (e.g. to # default_options.h, generated from default_options.h.in) diff --git a/sql-common/client.c b/sql-common/client.c index 79a5be938b2..6722597531d 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1753,7 +1753,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, const char *passwd, const char *db, uint port, const char *unix_socket,ulong client_flag) { - char buff[NAME_LEN+USERNAME_LENGTH+100]; + char buff[NAME_BYTE_LEN+USERNAME_BYTE_LENGTH+100]; char *end,*host_info; my_socket sock; in_addr_t ip_addr; @@ -2212,7 +2212,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, mysql->server_status, client_flag)); /* This needs to be changed as it's not useful with big packets */ if (user && user[0]) - strmake(end,user,USERNAME_LENGTH); /* Max user name */ + strmake(end,user,USERNAME_BYTE_LENGTH); /* Max user name */ else read_user_name((char*) end); @@ -2242,7 +2242,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, /* Add database if needed */ if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB)) { - end= strmake(end, db, NAME_LEN) + 1; + end= strmake(end, db, NAME_BYTE_LEN) + 1; mysql->db= my_strdup(db,MYF(MY_WME)); db= 0; } diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index f73d83f6030..e2232443e4f 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -3986,7 +3986,14 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) if (lock_type != F_UNLCK) { DBUG_PRINT("info", ("lock_type != F_UNLCK")); - if (!thd->transaction.on) + if (thd->lex->sql_command == SQLCOM_LOAD) + { + m_transaction_on= FALSE; + /* Would be simpler if has_transactions() didn't always say "yes" */ + thd->options|= OPTION_STATUS_NO_TRANS_UPDATE; + thd->no_trans_update= TRUE; + } + else if (!thd->transaction.on) m_transaction_on= FALSE; else m_transaction_on= thd->variables.ndb_use_transactions; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 58935337aa0..7b6be33d715 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -290,7 +290,9 @@ Item_sum::Item_sum(THD *thd, Item_sum *item): void Item_sum::mark_as_sum_func() { - current_thd->lex->current_select->with_sum_func= 1; + SELECT_LEX *cur_select= current_thd->lex->current_select; + cur_select->n_sum_items++; + cur_select->with_sum_func= 1; with_sum_func= 1; } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 473de1951e5..cc16beedd9e 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -584,7 +584,8 @@ void get_default_definer(THD *thd, LEX_USER *definer); LEX_USER *create_default_definer(THD *thd); LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name); LEX_USER *get_current_user(THD *thd, LEX_USER *user); -bool check_string_length(LEX_STRING *str, const char *err_msg, uint max_length); +bool check_string_length(CHARSET_INFO *cs, LEX_STRING *str, + const char *err_msg, uint max_length); enum enum_mysql_completiontype { ROLLBACK_RELEASE=-2, ROLLBACK=1, ROLLBACK_AND_CHAIN=7, diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 3f133924469..2f8fda3122d 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -5427,6 +5427,7 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field, MEM_ROOT *alloc= param->mem_root; char *str; ulong orig_sql_mode; + int err; DBUG_ENTER("get_mm_leaf"); /* @@ -5581,7 +5582,13 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field, (field->type() == FIELD_TYPE_DATE || field->type() == FIELD_TYPE_DATETIME)) field->table->in_use->variables.sql_mode|= MODE_INVALID_DATES; - if (value->save_in_field_no_warnings(field, 1) < 0) + err= value->save_in_field_no_warnings(field, 1); + if (err > 0 && field->cmp_type() != value->result_type()) + { + tree= 0; + goto end; + } + if (err < 0) { field->table->in_use->variables.sql_mode= orig_sql_mode; /* This happens when we try to insert a NULL field in a not null column */ diff --git a/sql/slave.h b/sql/slave.h index 053358dc686..9d76277da0d 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -152,7 +152,7 @@ typedef struct st_master_info /* the variables below are needed because we can change masters on the fly */ char master_log_name[FN_REFLEN]; char host[HOSTNAME_LENGTH+1]; - char user[USERNAME_LENGTH+1]; + char user[USERNAME_BYTE_LENGTH+1]; char password[MAX_PASSWORD_LENGTH+1]; my_bool ssl; // enables use of SSL connection if true char ssl_ca[FN_REFLEN], ssl_capath[FN_REFLEN], ssl_cert[FN_REFLEN]; diff --git a/sql/sp.cc b/sql/sp.cc index b799cde14a2..7ae335a1a3d 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -406,15 +406,16 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, { LEX *old_lex= thd->lex, newlex; String defstr; - char old_db_buf[NAME_LEN+1]; + char old_db_buf[NAME_BYTE_LEN+1]; LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) }; bool dbchanged; ulong old_sql_mode= thd->variables.sql_mode; ha_rows old_select_limit= thd->variables.select_limit; sp_rcontext *old_spcont= thd->spcont; - char definer_user_name_holder[USERNAME_LENGTH + 1]; - LEX_STRING definer_user_name= { definer_user_name_holder, USERNAME_LENGTH }; + char definer_user_name_holder[USERNAME_BYTE_LENGTH + 1]; + LEX_STRING definer_user_name= { definer_user_name_holder, + USERNAME_BYTE_LENGTH }; char definer_host_name_holder[HOSTNAME_LENGTH + 1]; LEX_STRING definer_host_name= { definer_host_name_holder, HOSTNAME_LENGTH }; @@ -513,7 +514,7 @@ db_create_routine(THD *thd, int type, sp_head *sp) int ret; TABLE *table; char definer[USER_HOST_BUFF_SIZE]; - char old_db_buf[NAME_LEN+1]; + char old_db_buf[NAME_BYTE_LEN+1]; LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) }; bool dbchanged; DBUG_ENTER("db_create_routine"); diff --git a/sql/sp_head.cc b/sql/sp_head.cc index fc4aa5e26d6..151e5785261 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -953,7 +953,7 @@ bool sp_head::execute(THD *thd) { DBUG_ENTER("sp_head::execute"); - char old_db_buf[NAME_LEN+1]; + char old_db_buf[NAME_BYTE_LEN+1]; LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) }; bool dbchanged; sp_rcontext *ctx; @@ -1998,8 +1998,8 @@ sp_head::set_info(longlong created, longlong modified, void sp_head::set_definer(const char *definer, uint definerlen) { - char user_name_holder[USERNAME_LENGTH + 1]; - LEX_STRING user_name= { user_name_holder, USERNAME_LENGTH }; + char user_name_holder[USERNAME_BYTE_LENGTH + 1]; + LEX_STRING user_name= { user_name_holder, USERNAME_BYTE_LENGTH }; char host_name_holder[HOSTNAME_LENGTH + 1]; LEX_STRING host_name= { host_name_holder, HOSTNAME_LENGTH }; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 70b2c7a3bfe..318f0798c5d 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -169,7 +169,7 @@ static byte* acl_entry_get_key(acl_entry *entry,uint *length, } #define IP_ADDR_STRLEN (3+1+3+1+3+1+3) -#define ACL_KEY_LENGTH (IP_ADDR_STRLEN+1+NAME_LEN+1+USERNAME_LENGTH+1) +#define ACL_KEY_LENGTH (IP_ADDR_STRLEN+1+NAME_BYTE_LEN+1+USERNAME_BYTE_LENGTH+1) static DYNAMIC_ARRAY acl_hosts,acl_users,acl_dbs; static MEM_ROOT mem, memex; @@ -312,7 +312,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) READ_RECORD read_record_info; my_bool return_val= 1; bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE; - char tmp_name[NAME_LEN+1]; + char tmp_name[NAME_BYTE_LEN+1]; int password_length; DBUG_ENTER("acl_load"); @@ -2401,7 +2401,7 @@ static GRANT_NAME *name_hash_search(HASH *name_hash, const char *user, const char *tname, bool exact) { - char helping [NAME_LEN*2+USERNAME_LENGTH+3]; + char helping [NAME_BYTE_LEN*2+USERNAME_BYTE_LENGTH+3]; uint len; GRANT_NAME *grant_name,*found=0; HASH_SEARCH_STATE state; @@ -3308,7 +3308,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list, { List_iterator <LEX_USER> str_list (list); LEX_USER *Str, *tmp_Str; - char tmp_db[NAME_LEN+1]; + char tmp_db[NAME_BYTE_LEN+1]; bool create_new_users=0; TABLE_LIST tables[2]; DBUG_ENTER("mysql_grant"); @@ -4012,7 +4012,7 @@ err2: bool check_grant_db(THD *thd,const char *db) { Security_context *sctx= thd->security_ctx; - char helping [NAME_LEN+USERNAME_LENGTH+2]; + char helping [NAME_BYTE_LEN+USERNAME_BYTE_LENGTH+2]; uint len; bool error= 1; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index b9e52b62244..9ad2e052331 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1531,10 +1531,10 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num) */ Query_arena *arena= thd->stmt_arena; return (ref_pointer_array= - (Item **)arena->alloc(sizeof(Item*) * - (item_list.elements + - select_n_having_items + - order_group_num)* 5)) == 0; + (Item **)arena->alloc(sizeof(Item*) * (n_child_sum_items + + item_list.elements + + select_n_having_items + + order_group_num)*5)) == 0; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index ce0af39a041..64426dd45d6 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -575,6 +575,12 @@ public: bool braces; /* SELECT ... UNION (SELECT ... ) <- this braces */ /* TRUE when having fix field called in processing of this SELECT */ bool having_fix_field; + + /* Number of Item_sum-derived objects in this SELECT */ + uint n_sum_items; + /* Number of Item_sum-derived objects in children and descendant SELECTs */ + uint n_child_sum_items; + /* explicit LIMIT clause was used */ bool explicit_limit; /* @@ -667,7 +673,7 @@ public: bool test_limit(); friend void lex_start(THD *thd, const uchar *buf, uint length); - st_select_lex() {} + st_select_lex() : n_sum_items(0), n_child_sum_items(0) {} void make_empty_select() { init_query(); diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 7e93fa28980..b85610eaa6f 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -146,10 +146,6 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, MYF(0)); DBUG_RETURN(TRUE); } - /* - This needs to be done before external_lock - */ - ha_enable_transaction(thd, FALSE); if (open_and_lock_tables(thd, table_list)) DBUG_RETURN(TRUE); if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context, @@ -393,7 +389,6 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); table->next_number_field=0; } - ha_enable_transaction(thd, TRUE); if (file >= 0) my_close(file,MYF(0)); free_blobs(table); /* if pack_blob was used */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 357fcf8a01c..d0bdd77fe8e 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1047,8 +1047,8 @@ static int check_connection(THD *thd) char *passwd= strend(user)+1; uint user_len= passwd - user - 1; char *db= passwd; - char db_buff[NAME_LEN+1]; // buffer to store db in utf8 - char user_buff[USERNAME_LENGTH+1]; // buffer to store user in utf8 + char db_buff[NAME_BYTE_LEN + 1]; // buffer to store db in utf8 + char user_buff[USERNAME_BYTE_LENGTH + 1]; // buffer to store user in utf8 uint dummy_errors; /* @@ -1724,7 +1724,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, password. New clients send the size (1 byte) + string (not null terminated, so also '\0' for empty string). */ - char db_buff[NAME_LEN+1]; // buffer to store db in utf8 + char db_buff[NAME_BYTE_LEN+1]; // buffer to store db in utf8 char *db= passwd; uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ? *passwd++ : strlen(passwd); @@ -7803,6 +7803,7 @@ LEX_USER *get_current_user(THD *thd, LEX_USER *user) SYNOPSIS check_string_length() + cs string charset str string to be checked err_msg error message to be displayed if the string is too long max_length max length @@ -7812,13 +7813,13 @@ LEX_USER *get_current_user(THD *thd, LEX_USER *user) TRUE the passed string is longer than max_length */ -bool check_string_length(LEX_STRING *str, const char *err_msg, - uint max_length) +bool check_string_length(CHARSET_INFO *cs, LEX_STRING *str, + const char *err_msg, uint max_length) { - if (str->length <= max_length) - return FALSE; + if (cs->cset->charpos(cs, str->str, str->str + str->length, + max_length) >= str->length) + return FALSE; my_error(ER_WRONG_STRING_LENGTH, MYF(0), str->str, err_msg, max_length); - return TRUE; } diff --git a/sql/sql_repl.h b/sql/sql_repl.h index 789de64da85..45d3254dad0 100644 --- a/sql/sql_repl.h +++ b/sql/sql_repl.h @@ -24,7 +24,7 @@ typedef struct st_slave_info uint32 server_id; uint32 rpl_recovery_rank, master_id; char host[HOSTNAME_LENGTH+1]; - char user[USERNAME_LENGTH+1]; + char user[USERNAME_BYTE_LENGTH+1]; char password[MAX_PASSWORD_LENGTH+1]; uint16 port; THD* thd; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 39eebd25814..b3e4bf39a8f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -9094,11 +9094,6 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, keyinfo->key_length+= key_part_info->length; } } - else - { - set_if_smaller(table->s->max_rows, rows_limit); - param->end_write_records= rows_limit; - } if (distinct && field_count != param->hidden_field_count) { @@ -9113,8 +9108,6 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, null_pack_length-=hidden_null_pack_length; keyinfo->key_parts= ((field_count-param->hidden_field_count)+ test(null_pack_length)); - set_if_smaller(share->max_rows, rows_limit); - param->end_write_records= rows_limit; table->distinct= 1; share->keys= 1; if (blob_count) @@ -9169,6 +9162,20 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, 0 : FIELDFLAG_BINARY; } } + + /* + Push the LIMIT clause to the temporary table creation, so that we + materialize only up to 'rows_limit' records instead of all result records. + This optimization is not applicable when there is GROUP BY or there is + no GROUP BY, but there are aggregate functions, because both must be + computed for all result rows. + */ + if (!group && !thd->lex->current_select->with_sum_func) + { + set_if_smaller(table->s->max_rows, rows_limit); + param->end_write_records= rows_limit; + } + if (thd->is_fatal_error) // If end of memory goto err; /* purecov: inspected */ share->db_record_offset= 1; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index b1a1e9cb9af..d4cf094e371 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -9346,7 +9346,8 @@ user: $$->host.str= (char *) "%"; $$->host.length= 1; - if (check_string_length(&$$->user, ER(ER_USERNAME), USERNAME_LENGTH)) + if (check_string_length(system_charset_info, &$$->user, + ER(ER_USERNAME), USERNAME_LENGTH)) YYABORT; } | ident_or_text '@' ident_or_text @@ -9356,9 +9357,10 @@ user: YYABORT; $$->user = $1; $$->host=$3; - if (check_string_length(&$$->user, ER(ER_USERNAME), USERNAME_LENGTH) || - check_string_length(&$$->host, ER(ER_HOSTNAME), - HOSTNAME_LENGTH)) + if (check_string_length(system_charset_info, &$$->user, + ER(ER_USERNAME), USERNAME_LENGTH) || + check_string_length(&my_charset_latin1, &$$->host, + ER(ER_HOSTNAME), HOSTNAME_LENGTH)) YYABORT; } | CURRENT_USER optional_braces @@ -10834,8 +10836,10 @@ subselect_end: { LEX *lex=Lex; lex->pop_context(); + SELECT_LEX *child= lex->current_select; lex->current_select = lex->current_select->return_after_parsing(); lex->nest_level--; + lex->current_select->n_child_sum_items += child->n_sum_items; }; /************************************************************************** diff --git a/sql/table.cc b/sql/table.cc index fe83398115d..bcc17fd805b 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2257,7 +2257,7 @@ char *get_field(MEM_ROOT *mem, Field *field) bool check_db_name(char *name) { - char *start=name; + uint name_length= 0; // name length in symbols /* Used to catch empty names and names with end space */ bool last_char_is_space= TRUE; @@ -2277,13 +2277,15 @@ bool check_db_name(char *name) name += len; continue; } + name_length++; } #else last_char_is_space= *name==' '; #endif + name_length++; name++; } - return last_char_is_space || (uint) (name - start) > NAME_LEN; + return last_char_is_space || name_length > NAME_LEN; } diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 3029b1db53e..0bceede27d8 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -728,7 +728,7 @@ int ha_archive::create(const char *name, TABLE *table_arg, goto error; } } - if (!azdopen(&archive, create_file, O_WRONLY|O_BINARY)) + if (!azdopen(&archive, dup(create_file), O_WRONLY|O_BINARY)) { error= errno; goto error2; diff --git a/storage/innobase/Makefile.am b/storage/innobase/Makefile.am index bdab35f1dc0..f784f57d4ff 100644 --- a/storage/innobase/Makefile.am +++ b/storage/innobase/Makefile.am @@ -36,6 +36,7 @@ SUBDIRS = os ut btr buf data dict dyn eval fil fsp fut \ ha ibuf lock log mach mem mtr page \ handler \ pars que read rem row srv sync thr trx usr +EXTRA_DIST = CMakeLists.txt EXTRA_DIST = include/btr0btr.h include/btr0btr.ic include/btr0cur.h include/btr0cur.ic \ include/btr0pcur.h include/btr0pcur.ic include/btr0sea.h include/btr0sea.ic \ |