diff options
author | Ignacio Galarza <iggy@mysql.com> | 2009-03-19 09:58:56 -0400 |
---|---|---|
committer | Ignacio Galarza <iggy@mysql.com> | 2009-03-19 09:58:56 -0400 |
commit | e8c13e6a5482947d4d41a60826460dd76bcce975 (patch) | |
tree | 5c7a85b5f844a534948edfe0b884fe79e953cabf | |
parent | 675c3ce2bbe7f033930822dd0ef9126ebb25d44b (diff) | |
parent | 26211b5ccdcf9d59841a509c6265e0cabbf88e91 (diff) | |
download | mariadb-git-e8c13e6a5482947d4d41a60826460dd76bcce975.tar.gz |
auto-merge
-rw-r--r-- | client/my_readline.h | 2 | ||||
-rw-r--r-- | client/mysql.cc | 24 | ||||
-rw-r--r-- | client/mysqldump.c | 3 | ||||
-rw-r--r-- | client/readline.cc | 46 | ||||
-rw-r--r-- | mysql-test/r/ctype_collate.result | 19 | ||||
-rw-r--r-- | mysql-test/r/federated.result | 20 | ||||
-rw-r--r-- | mysql-test/r/mysql.result | 9 | ||||
-rw-r--r-- | mysql-test/r/union.result | 16 | ||||
-rw-r--r-- | mysql-test/t/ctype_collate.test | 14 | ||||
-rw-r--r-- | mysql-test/t/federated.test | 22 | ||||
-rw-r--r-- | mysql-test/t/mysql.test | 33 | ||||
-rw-r--r-- | mysql-test/t/union.test | 43 | ||||
-rw-r--r-- | sql/item.cc | 19 | ||||
-rw-r--r-- | sql/tztime.cc | 77 |
14 files changed, 279 insertions, 68 deletions
diff --git a/client/my_readline.h b/client/my_readline.h index 47be7fa9294..32d6da4c626 100644 --- a/client/my_readline.h +++ b/client/my_readline.h @@ -29,5 +29,5 @@ typedef struct st_line_buffer extern LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file); extern LINE_BUFFER *batch_readline_command(LINE_BUFFER *buffer, my_string str); -extern char *batch_readline(LINE_BUFFER *buffer); +extern char *batch_readline(LINE_BUFFER *buffer, bool *truncated); extern void batch_readline_end(LINE_BUFFER *buffer); diff --git a/client/mysql.cc b/client/mysql.cc index ed46042115f..1b151b60e93 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -112,6 +112,8 @@ extern "C" { #define PROMPT_CHAR '\\' #define DEFAULT_DELIMITER ";" +#define MAX_BATCH_BUFFER_SIZE (1024L * 1024L) + typedef struct st_status { int exit_status; @@ -1035,7 +1037,7 @@ static void fix_history(String *final_command); static COMMANDS *find_command(char *name,char cmd_name); static bool add_line(String &buffer,char *line,char *in_string, - bool *ml_comment); + bool *ml_comment, bool truncated); static void remove_cntrl(String &buffer); static void print_table_data(MYSQL_RES *result); static void print_table_data_html(MYSQL_RES *result); @@ -1117,7 +1119,7 @@ int main(int argc,char *argv[]) exit(1); } if (status.batch && !status.line_buff && - !(status.line_buff=batch_readline_init(opt_max_allowed_packet+512,stdin))) + !(status.line_buff= batch_readline_init(MAX_BATCH_BUFFER_SIZE, stdin))) { free_defaults(defaults_argv); my_end(0); @@ -1197,7 +1199,7 @@ int main(int argc,char *argv[]) #endif sprintf(buff, "%s", #ifndef NOT_YET - "Type 'help;' or '\\h' for help. Type '\\c' to clear the buffer.\n"); + "Type 'help;' or '\\h' for help. Type '\\c' to clear the current input statement.\n"); #else "Type 'help [[%]function name[%]]' to get help on usage of function.\n"); #endif @@ -1766,13 +1768,14 @@ static int read_and_execute(bool interactive) ulong line_number=0; bool ml_comment= 0; COMMANDS *com; + bool truncated= 0; status.exit_status=1; for (;;) { if (!interactive) { - line=batch_readline(status.line_buff); + line=batch_readline(status.line_buff, &truncated); /* Skip UTF8 Byte Order Marker (BOM) 0xEFBBBF. Editors like "notepad" put this marker in @@ -1891,7 +1894,7 @@ static int read_and_execute(bool interactive) #endif continue; } - if (add_line(glob_buffer,line,&in_string,&ml_comment)) + if (add_line(glob_buffer,line,&in_string,&ml_comment, truncated)) break; } /* if in batch mode, send last query even if it doesn't end with \g or go */ @@ -1977,7 +1980,7 @@ static COMMANDS *find_command(char *name,char cmd_char) static bool add_line(String &buffer,char *line,char *in_string, - bool *ml_comment) + bool *ml_comment, bool truncated) { uchar inchar; char buff[80], *pos, *out; @@ -2224,9 +2227,10 @@ static bool add_line(String &buffer,char *line,char *in_string, { uint length=(uint) (out-line); - if (length < 9 || - my_strnncoll (charset_info, - (uchar *)line, 9, (const uchar *) "delimiter", 9)) + if (!truncated && + (length < 9 || + my_strnncoll (charset_info, + (uchar *)line, 9, (const uchar *) "delimiter", 9))) { /* Don't add a new line in case there's a DELIMITER command to be @@ -3886,7 +3890,7 @@ static int com_source(String *buffer, char *line) return put_info(buff, INFO_ERROR, 0); } - if (!(line_buff=batch_readline_init(opt_max_allowed_packet+512,sql_file))) + if (!(line_buff= batch_readline_init(MAX_BATCH_BUFFER_SIZE, sql_file))) { my_fclose(sql_file,MYF(0)); return put_info("Can't initialize batch_readline", INFO_ERROR, 0); diff --git a/client/mysqldump.c b/client/mysqldump.c index f19f147bbc3..a9d2788de05 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -3577,7 +3577,8 @@ char check_if_ignore_table(const char *table_name, char *table_type) If these two types, we do want to skip dumping the table */ if (!opt_no_data && - (!strcmp(table_type,"MRG_MyISAM") || !strcmp(table_type,"MRG_ISAM"))) + (!strcmp(table_type,"MRG_MyISAM") || !strcmp(table_type,"MRG_ISAM") || + !strcmp(table_type,"FEDERATED"))) result= IGNORE_DATA; } mysql_free_result(res); diff --git a/client/readline.cc b/client/readline.cc index ad42ed2ee10..726d9cd9415 100644 --- a/client/readline.cc +++ b/client/readline.cc @@ -24,7 +24,7 @@ static bool init_line_buffer(LINE_BUFFER *buffer,File file,ulong size, ulong max_size); static bool init_line_buffer_from_string(LINE_BUFFER *buffer,my_string str); static uint fill_buffer(LINE_BUFFER *buffer); -static char *intern_read_line(LINE_BUFFER *buffer,ulong *out_length); +static char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length, bool *truncated); LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file) @@ -42,12 +42,13 @@ LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file) } -char *batch_readline(LINE_BUFFER *line_buff) +char *batch_readline(LINE_BUFFER *line_buff, bool *truncated) { char *pos; ulong out_length; + DBUG_ASSERT(truncated != NULL); - if (!(pos=intern_read_line(line_buff,&out_length))) + if (!(pos=intern_read_line(line_buff,&out_length, truncated))) return 0; if (out_length && pos[out_length-1] == '\n') if (--out_length && pos[out_length-1] == '\r') /* Remove '\n' */ @@ -149,6 +150,14 @@ static uint fill_buffer(LINE_BUFFER *buffer) read_count=(buffer->bufread - bufbytes)/IO_SIZE; if ((read_count*=IO_SIZE)) break; + if (buffer->bufread * 2 > buffer->max_size) + { + /* + So we must grow the buffer but we cannot due to the max_size limit. + Return 0 w/o setting buffer->eof to signal this condition. + */ + return 0; + } buffer->bufread *= 2; if (!(buffer->buffer = (char*) my_realloc(buffer->buffer, buffer->bufread+1, @@ -172,11 +181,15 @@ static uint fill_buffer(LINE_BUFFER *buffer) DBUG_PRINT("fill_buff", ("Got %d bytes", read_count)); - /* Kludge to pretend every nonempty file ends with a newline. */ - if (!read_count && bufbytes && buffer->end[-1] != '\n') + if (!read_count) { - buffer->eof = read_count = 1; - *buffer->end = '\n'; + buffer->eof = 1; + /* Kludge to pretend every nonempty file ends with a newline. */ + if (bufbytes && buffer->end[-1] != '\n') + { + read_count = 1; + *buffer->end = '\n'; + } } buffer->end_of_line=(buffer->start_of_line=buffer->buffer)+bufbytes; buffer->end+=read_count; @@ -186,7 +199,7 @@ static uint fill_buffer(LINE_BUFFER *buffer) -char *intern_read_line(LINE_BUFFER *buffer,ulong *out_length) +char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length, bool *truncated) { char *pos; uint length; @@ -200,14 +213,23 @@ char *intern_read_line(LINE_BUFFER *buffer,ulong *out_length) pos++; if (pos == buffer->end) { - if ((uint) (pos - buffer->start_of_line) < buffer->max_size) + /* + fill_buffer() can return 0 either on EOF in which case we abort + or when the internal buffer has hit the size limit. In the latter case + return what we have read so far and signal string truncation. + */ + if (!(length=fill_buffer(buffer)) || length == (uint) -1) { - if (!(length=fill_buffer(buffer)) || length == (uint) -1) - DBUG_RETURN(0); - continue; + if (buffer->eof) + DBUG_RETURN(0); } + else + continue; pos--; /* break line here */ + *truncated= 1; } + else + *truncated= 0; buffer->end_of_line=pos+1; *out_length=(ulong) (pos + 1 - buffer->eof - buffer->start_of_line); DBUG_RETURN(buffer->start_of_line); diff --git a/mysql-test/r/ctype_collate.result b/mysql-test/r/ctype_collate.result index 7e9513f06e9..8bcd488cb69 100644 --- a/mysql-test/r/ctype_collate.result +++ b/mysql-test/r/ctype_collate.result @@ -611,3 +611,22 @@ check table t1 extended; Table Op Msg_type Msg_text test.t1 check status OK drop table t1; +select least(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci); +least(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci) +a +create table t1 +select least(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci) as f1; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` varchar(1) character set latin5 NOT NULL default '' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +select case _latin1'a' when _latin2'b' then 1 when _latin5'c' collate +latin5_turkish_ci then 2 else 3 end; +case _latin1'a' when _latin2'b' then 1 when _latin5'c' collate +latin5_turkish_ci then 2 else 3 end +3 +select concat(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci); +concat(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci) +abc diff --git a/mysql-test/r/federated.result b/mysql-test/r/federated.result index f0de3e9b04a..026886cb07d 100644 --- a/mysql-test/r/federated.result +++ b/mysql-test/r/federated.result @@ -2094,6 +2094,26 @@ SELECT t1.a FROM t1, t1 as t2 WHERE t2.b NOT LIKE t1.b; a DROP TABLE t1; DROP TABLE t1; +# +# BUG#21360 - mysqldump error on federated tables +# +#Switch to Connection Slave +CREATE TABLE t1(id VARCHAR(20) NOT NULL, PRIMARY KEY(id)); +INSERT INTO t1 VALUES ('text1'),('text2'),('text3'),('text4'); +#Switch to Connection Master +CREATE TABLE t1(id VARCHAR(20) NOT NULL, PRIMARY KEY(id)) ENGINE=FEDERATED +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1'; +# Dump table t1 using mysqldump tool +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t1` ( + `id` varchar(20) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=FEDERATED DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1'; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE t1; +#Switch to Connection Slave +DROP TABLE t1; End of 5.0 tests SET @@GLOBAL.CONCURRENT_INSERT= @OLD_MASTER_CONCURRENT_INSERT; SET @@GLOBAL.CONCURRENT_INSERT= @OLD_SLAVE_CONCURRENT_INSERT; diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result index 10537f6da16..cef5e08ec6b 100644 --- a/mysql-test/r/mysql.result +++ b/mysql-test/r/mysql.result @@ -192,4 +192,13 @@ delimiter 1 1 1 +set @old_max_allowed_packet = @@global.max_allowed_packet; +set @@global.max_allowed_packet = 2 * 1024 * 1024 + 1024; +CREATE TABLE t1(data LONGBLOB); +INSERT INTO t1 SELECT REPEAT('1', 2*1024*1024); +SELECT LENGTH(data) FROM t1; +LENGTH(data) +2097152 +DROP TABLE t1; +set @@global.max_allowed_packet = @old_max_allowed_packet; End of 5.0 tests diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 6007fdd403a..04bd818df89 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -1447,12 +1447,12 @@ SELECT a FROM t1 UNION SELECT a FROM t1 ) alias; -SELECT a INTO OUTFILE 'union.out.file' FROM ( +SELECT a INTO OUTFILE '<MYSQLTEST_VARDIR>/tmp/union.out.file' FROM ( SELECT a FROM t1 UNION SELECT a FROM t1 WHERE 0 ) alias; -SELECT a INTO DUMPFILE 'union.out.file2' FROM ( +SELECT a INTO DUMPFILE '<MYSQLTEST_VARDIR>/tmp/union.out.file' FROM ( SELECT a FROM t1 UNION SELECT a FROM t1 WHERE 0 @@ -1465,21 +1465,21 @@ SELECT a INTO @v FROM t1 SELECT a FROM ( SELECT a FROM t1 UNION -SELECT a INTO OUTFILE 'union.out.file3' FROM t1 +SELECT a INTO OUTFILE '<MYSQLTEST_VARDIR>/tmp/union.out.file' FROM t1 ) alias; SELECT a FROM ( SELECT a FROM t1 UNION -SELECT a INTO DUMPFILE 'union.out.file4' FROM t1 +SELECT a INTO DUMPFILE '<MYSQLTEST_VARDIR>/tmp/union.out.file' FROM t1 ) alias; SELECT a FROM t1 UNION SELECT a INTO @v FROM t1; -SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file5' FROM t1; -SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file6' FROM t1; +SELECT a FROM t1 UNION SELECT a INTO OUTFILE '<MYSQLTEST_VARDIR>/tmp/union.out.file' FROM t1; +SELECT a FROM t1 UNION SELECT a INTO DUMPFILE '<MYSQLTEST_VARDIR>/tmp/union.out.file' FROM t1; SELECT a INTO @v FROM t1 UNION SELECT a FROM t1; ERROR HY000: Incorrect usage of UNION and INTO -SELECT a INTO OUTFILE 'union.out.file7' FROM t1 UNION SELECT a FROM t1; +SELECT a INTO OUTFILE '<MYSQLTEST_VARDIR>/tmp/union.out.file' FROM t1 UNION SELECT a FROM t1; ERROR HY000: Incorrect usage of UNION and INTO -SELECT a INTO DUMPFILE 'union.out.file8' FROM t1 UNION SELECT a FROM t1; +SELECT a INTO DUMPFILE '<MYSQLTEST_VARDIR>/tmp/union.out.file' FROM t1 UNION SELECT a FROM t1; ERROR HY000: Incorrect usage of UNION and INTO DROP TABLE t1; CREATE TABLE t1 (a INT); diff --git a/mysql-test/t/ctype_collate.test b/mysql-test/t/ctype_collate.test index cfef8dfe81a..6b6abbcfbcc 100644 --- a/mysql-test/t/ctype_collate.test +++ b/mysql-test/t/ctype_collate.test @@ -229,3 +229,17 @@ insert into t1 set a=0x6c; insert into t1 set a=0x4c98; check table t1 extended; drop table t1; + +# +# Bug#41627 Illegal mix of collations in LEAST / GREATEST / CASE +# +select least(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci); +create table t1 +select least(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci) as f1; +show create table t1; +drop table t1; + +select case _latin1'a' when _latin2'b' then 1 when _latin5'c' collate +latin5_turkish_ci then 2 else 3 end; + +select concat(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci); diff --git a/mysql-test/t/federated.test b/mysql-test/t/federated.test index c977cb65fa0..ee9d1981558 100644 --- a/mysql-test/t/federated.test +++ b/mysql-test/t/federated.test @@ -1843,6 +1843,28 @@ DROP TABLE t1; connection master; DROP TABLE t1; +--echo # +--echo # BUG#21360 - mysqldump error on federated tables +--echo # +connection slave; +--echo #Switch to Connection Slave +CREATE TABLE t1(id VARCHAR(20) NOT NULL, PRIMARY KEY(id)); +INSERT INTO t1 VALUES ('text1'),('text2'),('text3'),('text4'); + +connection master; +--echo #Switch to Connection Master +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval CREATE TABLE t1(id VARCHAR(20) NOT NULL, PRIMARY KEY(id)) ENGINE=FEDERATED + CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t1'; +--echo # Dump table t1 using mysqldump tool +--replace_result $SLAVE_MYPORT SLAVE_PORT +--exec $MYSQL_DUMP --compact test t1 +DROP TABLE t1; + +connection slave; +--echo #Switch to Connection Slave +DROP TABLE t1; + connection default; --echo End of 5.0 tests diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index 12431e26596..54b204d3821 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -341,4 +341,37 @@ EOF remove_file $MYSQLTEST_VARDIR/tmp/bug31060.sql; +# +# Bug #41486: extra character appears in BLOB for every ~40Mb after +# mysqldump/import +# + +# Have to change the global variable as the session variable is +# read-only. +set @old_max_allowed_packet = @@global.max_allowed_packet; +# 2 MB blob length + some space for the rest of INSERT query +set @@global.max_allowed_packet = 2 * 1024 * 1024 + 1024; + +# Create a new connection since the global max_allowed_packet +# has no effect for the current connection +connect (con1, localhost, root,,); +connection con1; + +CREATE TABLE t1(data LONGBLOB); +INSERT INTO t1 SELECT REPEAT('1', 2*1024*1024); + +--exec $MYSQL_DUMP test t1 >$MYSQLTEST_VARDIR/tmp/bug41486.sql +# Check that the mysql client does not insert extra newlines when loading +# strings longer than client's max_allowed_packet +--exec $MYSQL --max_allowed_packet=1M test < $MYSQLTEST_VARDIR/tmp/bug41486.sql 2>&1 +SELECT LENGTH(data) FROM t1; + +remove_file $MYSQLTEST_VARDIR/tmp/bug41486.sql; +DROP TABLE t1; + +connection default; +disconnect con1; + +set @@global.max_allowed_packet = @old_max_allowed_packet; + --echo End of 5.0 tests diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index 44f21abda19..3c792f28d4f 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -933,17 +933,25 @@ SELECT a INTO @v FROM ( SELECT a FROM t1 ) alias; -SELECT a INTO OUTFILE 'union.out.file' FROM ( +--let $outfile = $MYSQLTEST_VARDIR/tmp/union.out.file +--error 0,1 +--remove_file $outfile + +--replace_result $MYSQLTEST_VARDIR <MYSQLTEST_VARDIR> +eval SELECT a INTO OUTFILE '$outfile' FROM ( SELECT a FROM t1 UNION SELECT a FROM t1 WHERE 0 ) alias; +--remove_file $outfile -SELECT a INTO DUMPFILE 'union.out.file2' FROM ( +--replace_result $MYSQLTEST_VARDIR <MYSQLTEST_VARDIR> +eval SELECT a INTO DUMPFILE '$outfile' FROM ( SELECT a FROM t1 UNION SELECT a FROM t1 WHERE 0 ) alias; +--remove_file $outfile # # INTO will not be allowed in subqueries in version 5.1 and above. @@ -954,27 +962,42 @@ SELECT a FROM ( SELECT a INTO @v FROM t1 ) alias; -SELECT a FROM ( +--replace_result $MYSQLTEST_VARDIR <MYSQLTEST_VARDIR> +eval SELECT a FROM ( SELECT a FROM t1 UNION - SELECT a INTO OUTFILE 'union.out.file3' FROM t1 + SELECT a INTO OUTFILE '$outfile' FROM t1 ) alias; +--remove_file $outfile -SELECT a FROM ( +--replace_result $MYSQLTEST_VARDIR <MYSQLTEST_VARDIR> +eval SELECT a FROM ( SELECT a FROM t1 UNION - SELECT a INTO DUMPFILE 'union.out.file4' FROM t1 + SELECT a INTO DUMPFILE '$outfile' FROM t1 ) alias; +--remove_file $outfile SELECT a FROM t1 UNION SELECT a INTO @v FROM t1; -SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file5' FROM t1; -SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file6' FROM t1; + +--replace_result $MYSQLTEST_VARDIR <MYSQLTEST_VARDIR> +eval SELECT a FROM t1 UNION SELECT a INTO OUTFILE '$outfile' FROM t1; +--remove_file $outfile + +--replace_result $MYSQLTEST_VARDIR <MYSQLTEST_VARDIR> +eval SELECT a FROM t1 UNION SELECT a INTO DUMPFILE '$outfile' FROM t1; +--remove_file $outfile + --error ER_WRONG_USAGE SELECT a INTO @v FROM t1 UNION SELECT a FROM t1; + +--replace_result $MYSQLTEST_VARDIR <MYSQLTEST_VARDIR> --error ER_WRONG_USAGE -SELECT a INTO OUTFILE 'union.out.file7' FROM t1 UNION SELECT a FROM t1; +eval SELECT a INTO OUTFILE '$outfile' FROM t1 UNION SELECT a FROM t1; + +--replace_result $MYSQLTEST_VARDIR <MYSQLTEST_VARDIR> --error ER_WRONG_USAGE -SELECT a INTO DUMPFILE 'union.out.file8' FROM t1 UNION SELECT a FROM t1; +eval SELECT a INTO DUMPFILE '$outfile' FROM t1 UNION SELECT a FROM t1; DROP TABLE t1; diff --git a/sql/item.cc b/sql/item.cc index 263915644df..6ae52d8be59 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1498,7 +1498,8 @@ bool DTCollation::aggregate(DTCollation &dt, uint flags) else { // Cannot apply conversion - set(0, DERIVATION_NONE, 0); + set(&my_charset_bin, DERIVATION_NONE, + (dt.repertoire|repertoire)); return 1; } } @@ -1581,15 +1582,31 @@ bool agg_item_collations(DTCollation &c, const char *fname, { uint i; Item **arg; + bool unknown_cs= 0; + c.set(av[0]->collation); for (i= 1, arg= &av[item_sep]; i < count; i++, arg++) { if (c.aggregate((*arg)->collation, flags)) { + if (c.derivation == DERIVATION_NONE && + c.collation == &my_charset_bin) + { + unknown_cs= 1; + continue; + } my_coll_agg_error(av, count, fname, item_sep); return TRUE; } } + + if (unknown_cs && + c.derivation != DERIVATION_EXPLICIT) + { + my_coll_agg_error(av, count, fname, item_sep); + return TRUE; + } + if ((flags & MY_COLL_DISALLOW_NONE) && c.derivation == DERIVATION_NONE) { diff --git a/sql/tztime.cc b/sql/tztime.cc index d3d952e3c1e..d73a1ca0111 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1871,6 +1871,12 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) #ifdef ABBR_ARE_USED char chars[max(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1)))]; #endif + /* + Used as a temporary tz_info until we decide that we actually want to + allocate and keep the tz info and tz name in tz_storage. + */ + TIME_ZONE_INFO tmp_tz_info; + memset(&tmp_tz_info, 0, sizeof(TIME_ZONE_INFO)); DBUG_ENTER("tz_load_from_open_tables"); @@ -1914,7 +1920,8 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) Most probably user has mistyped time zone name, so no need to bark here unless we need it for debugging. */ - sql_print_error("Can't find description of time zone '%s'", tz_name_buff); + sql_print_error("Can't find description of time zone '%.*s'", + tz_name->length(), tz_name->ptr()); #endif goto end; } @@ -1943,8 +1950,8 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) /* If Uses_leap_seconds == 'Y' */ if (table->field[1]->val_int() == 1) { - tz_info->leapcnt= tz_leapcnt; - tz_info->lsis= tz_lsis; + tmp_tz_info.leapcnt= tz_leapcnt; + tmp_tz_info.lsis= tz_lsis; } (void)table->file->ha_index_end(); @@ -1981,18 +1988,18 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) #ifdef ABBR_ARE_USED // FIXME should we do something with duplicates here ? table->field[4]->val_str(&abbr, &abbr); - if (tz_info->charcnt + abbr.length() + 1 > sizeof(chars)) + if (tmp_tz_info.charcnt + abbr.length() + 1 > sizeof(chars)) { sql_print_error("Error while loading time zone description from " "mysql.time_zone_transition_type table: not enough " "room for abbreviations"); goto end; } - ttis[ttid].tt_abbrind= tz_info->charcnt; - memcpy(chars + tz_info->charcnt, abbr.ptr(), abbr.length()); - tz_info->charcnt+= abbr.length(); - chars[tz_info->charcnt]= 0; - tz_info->charcnt++; + ttis[ttid].tt_abbrind= tmp_tz_info.charcnt; + memcpy(chars + tmp_tz_info.charcnt, abbr.ptr(), abbr.length()); + tmp_tz_info.charcnt+= abbr.length(); + chars[tmp_tz_info.charcnt]= 0; + tmp_tz_info.charcnt++; DBUG_PRINT("info", ("time_zone_transition_type table: tz_id=%u tt_id=%u tt_gmtoff=%ld " @@ -2005,9 +2012,9 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) #endif /* ttid is increasing because we are reading using index */ - DBUG_ASSERT(ttid >= tz_info->typecnt); + DBUG_ASSERT(ttid >= tmp_tz_info.typecnt); - tz_info->typecnt= ttid + 1; + tmp_tz_info.typecnt= ttid + 1; res= table->file->index_next_same(table->record[0], (byte*)table->field[0]->ptr, 4); @@ -2040,14 +2047,14 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) ttime= (my_time_t)table->field[1]->val_int(); ttid= (uint)table->field[2]->val_int(); - if (tz_info->timecnt + 1 > TZ_MAX_TIMES) + if (tmp_tz_info.timecnt + 1 > TZ_MAX_TIMES) { sql_print_error("Error while loading time zone description from " "mysql.time_zone_transition table: " "too much transitions"); goto end; } - if (ttid + 1 > tz_info->typecnt) + if (ttid + 1 > tmp_tz_info.typecnt) { sql_print_error("Error while loading time zone description from " "mysql.time_zone_transition table: " @@ -2055,9 +2062,9 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) goto end; } - ats[tz_info->timecnt]= ttime; - types[tz_info->timecnt]= ttid; - tz_info->timecnt++; + ats[tmp_tz_info.timecnt]= ttime; + types[tmp_tz_info.timecnt]= ttid; + tmp_tz_info.timecnt++; DBUG_PRINT("info", ("time_zone_transition table: tz_id: %u tt_time: %lu tt_id: %u", @@ -2082,6 +2089,34 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) table= 0; /* + Let us check how correct our time zone description is. We don't check for + tz->timecnt < 1 since it is ok for GMT. + */ + if (tmp_tz_info.typecnt < 1) + { + sql_print_error("loading time zone without transition types"); + goto end; + } + + /* Allocate memory for the timezone info and timezone name in tz_storage. */ + if (!(alloc_buff= (char*) alloc_root(&tz_storage, sizeof(TIME_ZONE_INFO) + + tz_name->length() + 1))) + { + sql_print_error("Out of memory while loading time zone description"); + return 0; + } + + /* Move the temporary tz_info into the allocated area */ + tz_info= (TIME_ZONE_INFO *)alloc_buff; + memcpy(tz_info, &tmp_tz_info, sizeof(TIME_ZONE_INFO)); + tz_name_buff= alloc_buff + sizeof(TIME_ZONE_INFO); + /* + By writing zero to the end we guarantee that we can call ptr() + instead of c_ptr() for time zone name. + */ + strmake(tz_name_buff, tz_name->ptr(), tz_name->length()); + + /* Now we will allocate memory and init TIME_ZONE_INFO structure. */ if (!(alloc_buff= alloc_root(&tz_storage, @@ -2112,15 +2147,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) tz_info->ttis= (TRAN_TYPE_INFO *)alloc_buff; memcpy(tz_info->ttis, ttis, tz_info->typecnt * sizeof(TRAN_TYPE_INFO)); - /* - Let us check how correct our time zone description and build - reversed map. We don't check for tz->timecnt < 1 since it ok for GMT. - */ - if (tz_info->typecnt < 1) - { - sql_print_error("loading time zone without transition types"); - goto end; - } + /* Build reversed map. */ if (prepare_tz_info(tz_info, &tz_storage)) { sql_print_error("Unable to build mktime map for time zone"); |