Commit 5d16592d authored by Sergei Golubchik's avatar Sergei Golubchik

mysql-5.5.38 merge

parents 2d687cad c1fd09f3
#ifndef ERRMSG_INCLUDED
#define ERRMSG_INCLUDED
/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -32,7 +32,9 @@ extern const char *client_errors[]; /* Error messages */
#define CR_MIN_ERROR 2000 /* For easier client code */
#define CR_MAX_ERROR 2999
#if !defined(ER)
#define ER(X) client_errors[(X)-CR_MIN_ERROR]
#define ER(X) (((X) >= CR_ERROR_FIRST && (X) <= CR_ERROR_LAST)? \
client_errors[(X)-CR_ERROR_FIRST]: client_errors[CR_UNKNOWN_ERROR])
#endif
#define CLIENT_ERRMAP 2 /* Errormap used by my_error() */
......
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -105,6 +105,8 @@ const char** get_client_errmsgs()
void init_client_errs(void)
{
compile_time_assert(array_elements(client_errors) ==
(CR_ERROR_LAST - CR_ERROR_FIRST + 2));
(void) my_error_register(get_client_errmsgs, CR_ERROR_FIRST, CR_ERROR_LAST);
}
......
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates
Copyright (c) 2009, 2013, Monty Program Ab
/* Copyright (c) 2000, 2014, Oracle and/or its affiliates
Copyright (c) 2009, 2014, Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -1339,6 +1339,10 @@ static my_bool my_realloc_str(NET *net, ulong length)
res= net_realloc(net, buf_length + length);
if (res)
{
if (net->last_errno == ER_OUT_OF_RESOURCES)
net->last_errno= CR_OUT_OF_MEMORY;
else if (net->last_errno == ER_NET_PACKET_TOO_LARGE)
net->last_errno= CR_NET_PACKET_TOO_LARGE;
strmov(net->sqlstate, unknown_sqlstate);
strmov(net->last_error, ER(net->last_errno));
}
......
......@@ -13,7 +13,6 @@ main.signal_demo3 @solaris # Bug#11753919 2010-01-20 alik Several
main.sp @solaris # Bug#11753919 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun
main.wait_timeout @solaris # Bug#11758972 2010-04-26 alik wait_timeout fails on OpenSolaris
rpl.rpl_innodb_bug28430 # Bug#11754425
rpl.rpl_row_sp011 @solaris # Bug#11753919 2011-07-25 sven Several test cases fail on Solaris with error Thread stack overrun
rpl.rpl_spec_variables @solaris # Bug #17337114 2013-08-20 Luis Soares failing on pb2 with timeout for 'CHECK WARNINGS'
......
......@@ -520,3 +520,15 @@ LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug11735141.txt' INTO TABLE t1;
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
drop table t1;
End of 5.1 tests
#
# Bug#11759519 INFINITE HANG WITH 100% CPU USAGE WITH LOAD DATA LOCAL AND IMPORT ERRORS
#
SET @old_mode= @@sql_mode;
CREATE TABLE t1 (fld1 INT);
SET sql_mode='strict_all_tables';
# Without fix, load data hangs forever.
LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/mysql' REPLACE INTO TABLE t1
FIELDS TERMINATED BY 't' LINES TERMINATED BY '';
Got one of the listed errors
SET @@sql_mode= @old_mode;
DROP TABLE t1;
......@@ -147,6 +147,14 @@ SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a, b, c;
a b c
1 ABC-АБВ DEF-ÂÃÄ
2 NULL NULL
SELECT * FROM t1;
a b c
1 ABC-АБВ DEF-ÂÃÄ
2 NULL NULL
SELECT * FROM t2;
a b c
1 ABC-АБВ DEF-ÂÃÄ
2 NULL NULL
SELECT * FROM t1 INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' LINES STARTING BY 'ъ';
Warnings:
Warning 1638 Non-ASCII separator arguments are not fully supported
......@@ -175,6 +183,14 @@ SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a, b, c;
a b c
1 ABC-АБВ DEF-ÂÃÄ
2 NULL NULL
SELECT * FROM t1;
a b c
1 ABC-АБВ DEF-ÂÃÄ
2 NULL NULL
SELECT * FROM t2;
a b c
1 ABC-АБВ DEF-ÂÃÄ
2 NULL NULL
# Default (binary) charset:
SELECT * INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' FROM t1;
##################################################
......
RESET MASTER;
connection default;
CREATE TABLE t1(id INT AUTO_INCREMENT PRIMARY KEY, a INT, b INT) ENGINE=INNODB;
INSERT INTO t1(a, b) VALUES(1,2),(2,4),(3,6),(4,8),(5,10);
SET DEBUG_SYNC = "open_and_process_table signal truncate_before_lock wait_for forever";
TRUNCATE t1;
connect con1,localhost,root,,;
SET DEBUG_SYNC = "now wait_for truncate_before_lock";
SELECT ((@id := id) - id) FROM information_schema.processlist WHERE processlist.info LIKE '%TRUNCATE t1%' AND state LIKE '%open_and_process_table%';
((@id := id) - id)
0
KILL QUERY @id;
connection default;
ERROR 70100: Query execution was interrupted
connection con1;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; CREATE TABLE t1(id INT AUTO_INCREMENT PRIMARY KEY, a INT, b INT) ENGINE=INNODB
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Intvar # # INSERT_ID=1
master-bin.000001 # Query # # use `test`; INSERT INTO t1(a, b) VALUES(1,2),(2,4),(3,6),(4,8),(5,10)
master-bin.000001 # Xid # # COMMIT /* XID */
disconnect con1;
connection default;
SELECT * FROM t1;
id a b
1 1 2
2 2 4
3 3 6
4 4 8
5 5 10
DROP TABLE t1;
SET DEBUG_SYNC= 'RESET';
###############################################################################
# Bug#17942050:KILL OF TRUNCATE TABLE WILL LEAD TO BINARY LOG WRITTEN WHILE
# ROWS REMAINS
#
# Problem:
# ========
# When truncate table fails while using transactional based engines even
# though the operation errors out we still continue and log it to binlog.
# Because of this master has data but the truncate will be written to binary
# log which will cause inconsistency.
#
# Test:
# =====
# Make master to wait in "open_table" call during the execution of truncate
# table command and kill the truncate table from other connection. This causes
# open table to return an error saying truncate failed during open table. This
# statement should not be binlogged.
###############################################################################
--source include/have_innodb.inc
--source include/have_debug_sync.inc
--source include/have_binlog_format_statement.inc
RESET MASTER;
--enable_connect_log
--connection default
CREATE TABLE t1(id INT AUTO_INCREMENT PRIMARY KEY, a INT, b INT) ENGINE=INNODB;
INSERT INTO t1(a, b) VALUES(1,2),(2,4),(3,6),(4,8),(5,10);
SET DEBUG_SYNC = "open_and_process_table signal truncate_before_lock wait_for forever";
--send TRUNCATE t1
connect(con1,localhost,root,,);
SET DEBUG_SYNC = "now wait_for truncate_before_lock";
# Wait for one connection to reach open_and_process_table.
--let $show_statement= SHOW PROCESSLIST
--let $field= State
--let $condition= 'debug sync point: open_and_process_table';
--source include/wait_show_condition.inc
SELECT ((@id := id) - id) FROM information_schema.processlist WHERE processlist.info LIKE '%TRUNCATE t1%' AND state LIKE '%open_and_process_table%';
# Test killing from mysql server
KILL QUERY @id;
connection default;
--ERROR ER_QUERY_INTERRUPTED
--reap
connection con1;
--source include/show_binlog_events.inc
disconnect con1;
--source include/wait_until_disconnected.inc
connection default;
SELECT * FROM t1;
DROP TABLE t1;
SET DEBUG_SYNC= 'RESET';
--disable_connect_log
include/master-slave.inc
[connection master]
#
# BUG#17994219: CREATE TABLE .. SELECT PRODUCES INVALID STRUCTURE,
# BREAKS RBR
#
#After the patch, the display width is set to a default
#value of 21.
CREATE TABLE t1 AS SELECT REPEAT('A', 1000) DIV 1 AS a;
Warnings:
Warning 1918 Encountered illegal value '' when converting to DECIMAL
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` bigint(21) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
CREATE TABLE t2 AS SELECT CONVERT(REPEAT('A', 255) USING UCS2) DIV 1 AS a;
Warnings:
Warning 1918 Encountered illegal value '' when converting to DECIMAL
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`a` bigint(21) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
#After the patch, no error is reported.
DROP TABLE t1;
DROP TABLE t2;
include/rpl_end.inc
......@@ -363,13 +363,11 @@ let $result= query_get_value(SELECT ($rcvd_heartbeats_after - $rcvd_heartbeats_b
--connection master
DELETE FROM t1;
DROP EVENT e1;
--sync_slave_with_master
--echo
# Check received heartbeat events while logs flushed on slave
--sync_slave_with_master
--echo *** Flush logs on slave ***
STOP SLAVE;
RESET SLAVE;
......
# Testing table creations for row-based replication.
--source include/have_binlog_format_row.inc
--source include/master-slave.inc
--echo #
--echo # BUG#17994219: CREATE TABLE .. SELECT PRODUCES INVALID STRUCTURE,
--echo # BREAKS RBR
--echo #
connection master;
--echo #After the patch, the display width is set to a default
--echo #value of 21.
CREATE TABLE t1 AS SELECT REPEAT('A', 1000) DIV 1 AS a;
SHOW CREATE TABLE t1;
CREATE TABLE t2 AS SELECT CONVERT(REPEAT('A', 255) USING UCS2) DIV 1 AS a;
SHOW CREATE TABLE t2;
--echo #After the patch, no error is reported.
sync_slave_with_master;
connection master;
DROP TABLE t1;
DROP TABLE t2;
--source include/rpl_end.inc
......@@ -637,3 +637,24 @@ create table t1(a point);
drop table t1;
--echo End of 5.1 tests
--echo #
--echo # Bug#11759519 INFINITE HANG WITH 100% CPU USAGE WITH LOAD DATA LOCAL AND IMPORT ERRORS
--echo #
SET @old_mode= @@sql_mode;
CREATE TABLE t1 (fld1 INT);
--copy_file $EXE_MYSQL $MYSQLTEST_VARDIR/mysql
SET sql_mode='strict_all_tables';
--echo # Without fix, load data hangs forever.
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--error ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,1000
eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/mysql' REPLACE INTO TABLE t1
FIELDS TERMINATED BY 't' LINES TERMINATED BY '';
SET @@sql_mode= @old_mode;
--remove_file $MYSQLTEST_VARDIR/mysql
DROP TABLE t1;
......@@ -169,6 +169,8 @@ TRUNCATE t2;
--eval LOAD DATA INFILE '$file' INTO TABLE t2 CHARACTER SET binary FIELDS TERMINATED BY 'ъ'
--remove_file $file
SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a, b, c;
SELECT * FROM t1;
SELECT * FROM t2;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--eval SELECT * FROM t1 INTO OUTFILE '$file' LINES STARTING BY 'ъ'
......@@ -191,6 +193,8 @@ TRUNCATE t2;
--eval LOAD DATA INFILE '$file' INTO TABLE t2 CHARACTER SET binary LINES TERMINATED BY 'ъ'
--remove_file $file
SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a, b, c;
SELECT * FROM t1;
SELECT * FROM t2;
--echo # Default (binary) charset:
......
......@@ -306,6 +306,9 @@ my_bool my_thread_init(void)
struct st_my_thread_var *tmp;
my_bool error=0;
if (!my_thread_global_init_done)
return 1; /* cannot proceed with unintialized library */
#ifdef EXTRA_DEBUG_THREADS
fprintf(stderr,"my_thread_init(): pthread_self: %p\n", pthread_self());
#endif
......
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
This diff is collapsed.
# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
......@@ -17,6 +17,10 @@
# Any files in this directory are auxiliary files for Solaris "pkg" packages.
# They will be configured during "pkg" creation, not during (binary) build.
IF(NOT CMAKE_SYSTEM_NAME MATCHES "SunOS")
RETURN()
ENDIF()
# Currently, this expands to "support-files/" in most layouts,
# but to "/usr/share/mysql/" in a RPM.
# It is important not to pollute "/usr/bin".
......
......@@ -4319,21 +4319,31 @@ const char * STDCALL mysql_error(MYSQL *mysql)
RETURN
Signed number > 323000
Zero if there is no connection
*/
ulong STDCALL
mysql_get_server_version(MYSQL *mysql)
{
uint major, minor, version;
const char *pos= mysql->server_version;
char *end_pos;
/* Skip possible prefix */
while (*pos && !my_isdigit(&my_charset_latin1, *pos))
pos++;
major= (uint) strtoul(pos, &end_pos, 10); pos=end_pos+1;
minor= (uint) strtoul(pos, &end_pos, 10); pos=end_pos+1;
version= (uint) strtoul(pos, &end_pos, 10);
return (ulong) major*10000L+(ulong) (minor*100+version);
ulong major= 0, minor= 0, version= 0;
if (mysql->server_version)
{
const char *pos= mysql->server_version;
char *end_pos;
/* Skip possible prefix */
while (*pos && !my_isdigit(&my_charset_latin1, *pos))
pos++;
major= strtoul(pos, &end_pos, 10); pos=end_pos+1;
minor= strtoul(pos, &end_pos, 10); pos=end_pos+1;
version= strtoul(pos, &end_pos, 10);
}
else
{
set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
}
return major*10000 + minor*100 + version;
}
......
......@@ -7081,8 +7081,7 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
If content of the 'from'-address is cached in the 'value'-object
it is possible that the content needs a character conversion.
*/
uint32 dummy_offset;
if (!String::needs_conversion(length, cs, field_charset, &dummy_offset))
if (!String::needs_conversion_on_storage(length, cs, field_charset))
{
Field_blob::store_length(length);
bmove(ptr + packlength, &from, sizeof(char*));
......@@ -7650,12 +7649,11 @@ int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs)
{
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
int err= 0;
uint32 not_used;
char buff[STRING_BUFFER_USUAL_SIZE];
String tmpstr(buff,sizeof(buff), &my_charset_bin);
/* Convert character set if necessary */
if (String::needs_conversion(length, cs, field_charset, &not_used))
if (String::needs_conversion_on_storage(length, cs, field_charset))
{
uint dummy_errors;
tmpstr.copy(from, length, cs, field_charset, &dummy_errors);
......@@ -7832,12 +7830,11 @@ int Field_set::store(const char *from,uint length,CHARSET_INFO *cs)
int err= 0;
char *not_used;
uint not_used2;
uint32 not_used_offset;
char buff[STRING_BUFFER_USUAL_SIZE];
String tmpstr(buff,sizeof(buff), &my_charset_bin);
/* Convert character set if necessary */
if (String::needs_conversion(length, cs, field_charset, &not_used_offset))
if (String::needs_conversion_on_storage(length, cs, field_charset))
{
uint dummy_errors;
tmpstr.copy(from, length, cs, field_charset, &dummy_errors);
......
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
Copyright (c) 2009, 2013, Monty Program Ab.
/* Copyright (c) 2000, 2014, Oracle and/or its affiliates.
Copyright (c) 2009, 2014, Monty Program Ab.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -1965,9 +1965,11 @@ void Item_func_int_div::fix_length_and_dec()
{
Item_result argtype= args[0]->result_type();
/* use precision ony for the data type it is applicable for and valid */
max_length=args[0]->max_length -
(argtype == DECIMAL_RESULT || argtype == INT_RESULT ?
args[0]->decimals : 0);
uint32 char_length= args[0]->max_char_length() -
(argtype == DECIMAL_RESULT || argtype == INT_RESULT ?
args[0]->decimals : 0);
fix_char_length(char_length > MY_INT64_NUM_DECIMAL_DIGITS ?
MY_INT64_NUM_DECIMAL_DIGITS : char_length);
maybe_null=1;
unsigned_flag=args[0]->unsigned_flag | args[1]->unsigned_flag;
}
......
/*
Copyright (c) 2000, 2013, Oracle and/or its affiliates.
Copyright (c) 2010, 2013, Monty Progrm Ab
Copyright (c) 2000, 2014, Oracle and/or its affiliates.
Copyright (c) 2010, 2014, Monty Progrm Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -59,13 +59,17 @@ XML_TAG::XML_TAG(int l, String f, String v)
}
#define GET (stack_pos != stack ? *--stack_pos : my_b_get(&cache))
#define PUSH(A) *(stack_pos++)=(A)
class READ_INFO {
File file;
uchar *buffer, /* Buffer for read text */
*end_of_buff; /* Data in bufferts ends here */
uint buff_length, /* Length of buffert */
max_length; /* Max length of row */
char *field_term_ptr,*line_term_ptr,*line_start_ptr,*line_start_end;
const uchar *field_term_ptr,*line_term_ptr;
const char *line_start_ptr,*line_start_end;
uint field_term_length,line_term_length,enclosed_length;
int field_term_char,line_term_char,enclosed_char,escape_char;
int *stack,*stack_pos;
......@@ -89,7 +93,7 @@ public:
int read_fixed_length(void);
int next_line(void);
char unescape(char chr);
int terminator(char *ptr,uint length);
int terminator(const uchar *ptr, uint length);
bool find_start_of_fields();
/* load xml */
List<XML_TAG> taglist;
......@@ -115,6 +119,15 @@ public:
either the table or THD value
*/
void set_io_cache_arg(void* arg) { cache.arg = arg; }
/**
skip all data till the eof.
*/
void skip_data_till_eof()
{
while (GET != my_b_EOF)
;
}
};
static int read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
......@@ -546,8 +559,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
if (error)
{
if (read_file_from_client)
while (!read_info.next_line())
;
read_info.skip_data_till_eof();
#ifndef EMBEDDED_LIBRARY
if (mysql_bin_log.is_open())
......@@ -1335,10 +1347,18 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs,
found_end_of_line(false), eof(false), need_end_io_cache(false),
error(false), line_cuted(false), found_null(false), read_charset(cs)
{
field_term_ptr=(char*) field_term.ptr();
/*
Field and line terminators must be interpreted as sequence of unsigned char.
Otherwise, non-ascii terminators will be negative on some platforms,
and positive on others (depending on the implementation of char).
*/
field_term_ptr=
static_cast<const uchar*>(static_cast<const void*>(field_term.ptr()));
field_term_length= field_term.length();
line_term_ptr=(char*) line_term.ptr();
line_term_ptr=
static_cast<const uchar*>(static_cast<const void*>(line_term.ptr()));
line_term_length= line_term.length();
level= 0; /* for load xml */
if (line_start.length() == 0)
{
......@@ -1347,7 +1367,7 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs,
}
else
{
line_start_ptr=(char*) line_start.ptr();
line_start_ptr= line_start.ptr();
line_start_end=line_start_ptr+line_start.length();
start_of_line= 1;
}
......@@ -1356,12 +1376,12 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs,
!memcmp(field_term_ptr,line_term_ptr,field_term_length))
{
line_term_length=0;
line_term_ptr=(char*) "";
line_term_ptr= NULL;
}
enclosed_char= (enclosed_length=enclosed_par.length()) ?
(uchar) enclosed_par[0] : INT_MAX;
field_term_char= field_term_length ? (uchar) field_term_ptr[0] : INT_MAX;
line_term_char= line_term_length ? (uchar) line_term_ptr[0] : INT_MAX;
field_term_char= field_term_length ? field_term_ptr[0] : INT_MAX;
line_term_char= line_term_length ? line_term_ptr[0] : INT_MAX;
/* Set of a stack for unget if long terminators */
uint length= max(cs->mbmaxlen, max(field_term_length, line_term_length)) + 1;
......@@ -1416,11 +1436,7 @@ READ_INFO::~READ_INFO()
}
#define GET (stack_pos != stack ? *--stack_pos : my_b_get(&cache))
#define PUSH(A) *(stack_pos++)=(A)
inline int READ_INFO::terminator(char *ptr,uint length)
inline int READ_INFO::terminator(const uchar *ptr,uint length)
{
int chr=0; // Keep gcc happy
uint i;
......@@ -1435,7 +1451,7 @@ inline int READ_INFO::terminator(char *ptr,uint length)
return 1;
PUSH(chr);
while (i-- > 1)
PUSH((uchar) *--ptr);
PUSH(*--ptr);
return 0;
}
......@@ -1567,7 +1583,7 @@ int READ_INFO::read_field()
if (my_mbcharlen(read_charset, chr) > 1 &&
to + my_mbcharlen(read_charset, chr) <= end_of_buff)
{
uchar* p= (uchar*) to;
uchar* p= to;
int ml, i;
*to++ = chr;
......@@ -1592,7 +1608,7 @@ int READ_INFO::read_field()
(const char *)to))
continue;
for (i= 0; i < ml; i++)
PUSH((uchar) *--to);
PUSH(*--to);
chr= GET;
}
#endif
......@@ -1741,7 +1757,7 @@ bool READ_INFO::find_start_of_fields()
return 1;
}
} while ((char) chr != line_start_ptr[0]);
for (char *ptr=line_start_ptr+1 ; ptr != line_start_end ; ptr++)
for (const char *ptr=line_start_ptr+1 ; ptr != line_start_end ; ptr++)
{
chr=GET; // Eof will be checked later
if ((char) chr != *ptr)
......@@ -1749,7 +1765,7 @@ bool READ_INFO::find_start_of_fields()
PUSH(chr);
while (--ptr != line_start_ptr)
{ // Restart with next char
PUSH((uchar) *ptr);
PUSH( *ptr);
}
goto try_again;
}
......@@ -1945,7 +1961,7 @@ int READ_INFO::read_xml()
// row tag should be in ROWS IDENTIFIED BY '<row>' - stored in line_term
if((tag.length() == line_term_length -2) &&
(strncmp(tag.c_ptr_safe(), line_term_ptr + 1, tag.length()) == 0))
(memcmp(tag.ptr(), line_term_ptr + 1, tag.length()) == 0))
{
DBUG_PRINT("read_xml", ("start-of-row: %i %s %s",
level,tag.c_ptr_safe(), line_term_ptr));
......@@ -2007,7 +2023,7 @@ int READ_INFO::read_xml()
}
if((tag.length() == line_term_length -2) &&
(strncmp(tag.c_ptr_safe(), line_term_ptr + 1, tag.length()) == 0))
(memcmp(tag.ptr(), line_term_ptr + 1, tag.length()) == 0))
{
DBUG_PRINT("read_xml", ("found end-of-row %i %s",
level, tag.c_ptr_safe()));
......
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
Copyright (c) 2009, 2012, Monty Program Ab.
/* Copyright (c) 2000, 2014, Oracle and/or its affiliates.
Copyright (c) 2009, 2014, Monty Program Ab.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -3112,10 +3112,38 @@ void calc_sum_of_all_status(STATUS_VAR *to)
/* This is only used internally, but we need it here as a forward reference */
extern ST_SCHEMA_TABLE schema_tables[];
/**
Condition pushdown used for INFORMATION_SCHEMA / SHOW queries.
This structure is to implement an optimization when
accessing data dictionary data in the INFORMATION_SCHEMA
or SHOW commands.
When the query contain a TABLE_SCHEMA or TABLE_NAME clause,
narrow the search for data based on the constraints given.
*/
typedef struct st_lookup_field_values
{
LEX_STRING db_value, table_value;
bool wild_db_value, wild_table_value;
/**
Value of a TABLE_SCHEMA clause.
Note that this value length may exceed @c NAME_LEN.
@sa wild_db_value
*/
LEX_STRING db_value;
/**
Value of a TABLE_NAME clause.
Note that this value length may exceed @c NAME_LEN.
@sa wild_table_value
*/
LEX_STRING table_value;
/**
True when @c db_value is a LIKE clause,
false when @c db_value is an '=' clause.
*/
bool wild_db_value;
/**
True when @c table_value is a LIKE clause,
false when @c table_value is an '=' clause.
*/
bool wild_table_value;
} LOOKUP_FIELD_VALUES;
......@@ -3520,14 +3548,22 @@ int make_db_list(THD *thd, List<LEX_STRING> *files,
/*
If we have db lookup vaule we just add it to list and
If we have db lookup value we just add it to list and
exit from the function.
We don't do this for database names longer than the maximum
path length.
name length.
*/
if (lookup_field_vals->db_value.str &&
lookup_field_vals->db_value.length < FN_REFLEN)
if (lookup_field_vals->db_value.str)
{
if (lookup_field_vals->db_value.length > NAME_LEN)
{
/*
Impossible value for a database name,
found in a WHERE DATABASE_NAME = 'xxx' clause.
*/
return 0;
}
if (is_infoschema_db(lookup_field_vals->db_value.str,
lookup_field_vals->db_value.length))
{
......@@ -3664,6 +3700,15 @@ make_table_name_list(THD *thd, List<LEX_STRING> *table_names, LEX *lex,
if (!lookup_field_vals->wild_table_value &&
lookup_field_vals->table_value.str)
{
if (lookup_field_vals->table_value.length > NAME_LEN)
{
/*
Impossible value for a table name,
found in a WHERE TABLE_NAME = 'xxx' clause.
*/
return 0;
}
if (with_i_schema)
{
LEX_STRING *name;
......@@ -4127,6 +4172,9 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables,
bzero((char*) &table_list, sizeof(TABLE_LIST));
bzero((char*) &tbl, sizeof(TABLE));
DBUG_ASSERT(db_name->length <= NAME_LEN);
DBUG_ASSERT(table_name->length <= NAME_LEN);
if (lower_case_table_names)
{
/*
......@@ -4443,6 +4491,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
it.rewind(); /* To get access to new elements in basis list */
while ((db_name= it++))
{
DBUG_ASSERT(db_name->length <= NAME_LEN);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (!(check_access(thd, SELECT_ACL, db_name->str,
&thd->col_access, NULL, 0, 1) ||
......@@ -4463,6 +4512,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
List_iterator_fast<LEX_STRING> it_files(table_names);
while ((table_name= it_files++))
{
DBUG_ASSERT(table_name->length <= NAME_LEN);
restore_record(table, s->default_values);
table->field[schema_table->idx_field1]->
store(db_name->str, db_name->length, system_charset_info);
......@@ -4597,6 +4647,7 @@ int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond)
List_iterator_fast<LEX_STRING> it(db_names);
while ((db_name=it++))
{
DBUG_ASSERT(db_name->length <= NAME_LEN);
if (with_i_schema) // information schema name is always first in list
{
if (store_schema_shemata(thd, table, db_name,
......
......@@ -222,6 +222,42 @@ bool String::needs_conversion(uint32 arg_length,
}
/*
Checks that the source string can just be copied to the destination string
without conversion.
Unlike needs_conversion it will require conversion on incoming binary data
to ensure the data are verified for vailidity first.
@param arg_length Length of string to copy.
@param from_cs Character set to copy from
@param to_cs Character set to copy to
@return conversion needed
*/
bool String::needs_conversion_on_storage(uint32 arg_length,
CHARSET_INFO *cs_from,
CHARSET_INFO *cs_to)
{
uint32 offset;
return (needs_conversion(arg_length, cs_from, cs_to, &offset) ||
/* force conversion when storing a binary string */
(cs_from == &my_charset_bin &&
/* into a non-binary destination */
cs_to != &my_charset_bin &&
/* and any of the following is true :*/
(
/* it's a variable length encoding */
cs_to->mbminlen != cs_to->mbmaxlen ||
/* longer than 2 bytes : neither 1 byte nor ucs2 */
cs_to->mbminlen > 2 ||
/* and is not a multiple of the char byte size */
0 != (arg_length % cs_to->mbmaxlen)
)
)
);
}
/*
Copy a multi-byte character sets with adding leading zeros.
......
......@@ -322,6 +322,9 @@ public:
static bool needs_conversion(uint32 arg_length,
CHARSET_INFO *cs_from, CHARSET_INFO *cs_to,
uint32 *offset);
static bool needs_conversion_on_storage(uint32 arg_length,
CHARSET_INFO *cs_from,
CHARSET_INFO *cs_to);
bool copy_aligned(const char *s, uint32 arg_length, uint32 offset,
CHARSET_INFO *cs);
bool set_or_copy_aligned(const char *s, uint32 arg_length, CHARSET_INFO *cs);
......
/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
/* Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -182,12 +182,19 @@ fk_truncate_illegal_if_parent(THD *thd, TABLE *table)
@param table_ref Table list element for the table to be truncated.
@param is_tmp_table True if element refers to a temp table.
@retval 0 Success.
@retval > 0 Error code.
@retval TRUNCATE_OK Truncate was successful and statement can be safely
binlogged.
@retval TRUNCATE_FAILED_BUT_BINLOG Truncate failed but still go ahead with
binlogging as in case of non transactional tables
partial truncation is possible.
@retval TRUNCATE_FAILED_SKIP_BINLOG Truncate was not successful hence donot
binlong the statement.
*/
int Truncate_statement::handler_truncate(THD *thd, TABLE_LIST *table_ref,
bool is_tmp_table)
enum Truncate_statement::truncate_result
Truncate_statement::handler_truncate(THD *thd, TABLE_LIST *table_ref,
bool is_tmp_table)
{
int error= 0;
uint flags;
......@@ -229,16 +236,30 @@ int Truncate_statement::handler_truncate(THD *thd, TABLE_LIST *table_ref,
/* Open the table as it will handle some required preparations. */
if (open_and_lock_tables(thd, table_ref, FALSE, flags))
DBUG_RETURN(1);
DBUG_RETURN(TRUNCATE_FAILED_SKIP_BINLOG);
/* Whether to truncate regardless of foreign keys. */
if (! (thd->variables.option_bits & OPTION_NO_FOREIGN_KEY_CHECKS))
error= fk_truncate_illegal_if_parent(thd, table_ref->table);
if (fk_truncate_illegal_if_parent(thd, table_ref->table))
DBUG_RETURN(TRUNCATE_FAILED_SKIP_BINLOG);
if (!error && (error= table_ref->table->file->ha_truncate()))
error= table_ref->table->file->ha_truncate();
if (error)
{
table_ref->table->file->print_error(error, MYF(0));
DBUG_RETURN(error);
/*
If truncate method is not implemented then we don't binlog the
statement. If truncation has failed in a transactional engine then also we
donot binlog the statment. Only in non transactional engine we binlog
inspite of errors.
*/
if (error == HA_ERR_WRONG_COMMAND ||
table_ref->table->file->has_transactions())
DBUG_RETURN(TRUNCATE_FAILED_SKIP_BINLOG);
else
DBUG_RETURN(TRUNCATE_FAILED_BUT_BINLOG);
}
DBUG_RETURN(TRUNCATE_OK);
}
......@@ -473,10 +494,14 @@ bool Truncate_statement::truncate_table(THD *thd, TABLE_LIST *table_ref)
/*
All effects of a TRUNCATE TABLE operation are committed even if
truncation fails. Thus, the query must be written to the binary
log. The only exception is a unimplemented truncate method.
truncation fails in the case of non transactional tables. Thus, the
query must be written to the binary log. The only exception is a
unimplemented truncate method.
*/
binlog_stmt= !error || error != HA_ERR_WRONG_COMMAND;
if (error == TRUNCATE_OK || error == TRUNCATE_FAILED_BUT_BINLOG)
binlog_stmt= true;
else
binlog_stmt= false;
}
/*
......
#ifndef SQL_TRUNCATE_INCLUDED
#define SQL_TRUNCATE_INCLUDED
/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
/* Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -47,11 +47,17 @@ public:
bool execute(THD *thd);
protected:
enum truncate_result{
TRUNCATE_OK=0,
TRUNCATE_FAILED_BUT_BINLOG,
TRUNCATE_FAILED_SKIP_BINLOG
};
/** Handle locking a base table for truncate. */
bool lock_table(THD *, TABLE_LIST *, bool *);
/** Truncate table via the handler method. */
int handler_truncate(THD *, TABLE_LIST *, bool);
enum truncate_result handler_truncate(THD *, TABLE_LIST *, bool);
/**
Optimized delete of all rows by doing a full regenerate of the table.
......
/*
Copyright (c) 2004, 2012, Oracle and/or its affiliates
Copyright (c) 2004, 2014, Oracle and/or its affiliates
Copyright (c) 2010, 2014, SkySQL Ab.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
......
......@@ -143,6 +143,7 @@ row_ins_alloc_sys_fields(
const dict_col_t* col;
dfield_t* dfield;
byte* ptr;
uint len;
row = node->row;
table = node->table;
......@@ -151,35 +152,37 @@ row_ins_alloc_sys_fields(
ut_ad(row && table && heap);
ut_ad(dtuple_get_n_fields(row) == dict_table_get_n_cols(table));
/* 1. Allocate buffer for row id */
/* allocate buffer to hold the needed system created hidden columns. */
len = DATA_ROW_ID_LEN + DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN;
ptr = mem_heap_zalloc(heap, len);
/* 1. Populate row-id */
col = dict_table_get_sys_col(table, DATA_ROW_ID);
dfield = dtuple_get_nth_field(row, dict_col_get_no(col));
ptr = mem_heap_zalloc(heap, DATA_ROW_ID_LEN);
dfield_set_data(dfield, ptr, DATA_ROW_ID_LEN);
node->row_id_buf = ptr;
/* 3. Allocate buffer for trx id */
ptr += DATA_ROW_ID_LEN;
/* 2. Populate trx id */
col = dict_table_get_sys_col(table, DATA_TRX_ID);
dfield = dtuple_get_nth_field(row, dict_col_get_no(col));
ptr = mem_heap_zalloc(heap, DATA_TRX_ID_LEN);
dfield_set_data(dfield, ptr, DATA_TRX_ID_LEN);
node->trx_id_buf = ptr;
/* 4. Allocate buffer for roll ptr */
ptr += DATA_TRX_ID_LEN;
/* 3. Populate roll ptr */
col = dict_table_get_sys_col(table, DATA_ROLL_PTR);
dfield = dtuple_get_nth_field(row, dict_col_get_no(col));
ptr = mem_heap_zalloc(heap, DATA_ROLL_PTR_LEN);
dfield_set_data(dfield, ptr, DATA_ROLL_PTR_LEN);
}
......
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