Commit 9934bc54 authored by Tor Didriksen's avatar Tor Didriksen

local merge

parents 39dbf735 7873a6e4
# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
# #
# This program is free software; you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
...@@ -82,9 +82,11 @@ MACRO(CREATE_INFO_BIN) ...@@ -82,9 +82,11 @@ MACRO(CREATE_INFO_BIN)
FILE(WRITE ${INFO_BIN} "===== Information about the build process: =====\n") FILE(WRITE ${INFO_BIN} "===== Information about the build process: =====\n")
IF (WIN32) IF (WIN32)
EXECUTE_PROCESS(COMMAND cmd /c date /T OUTPUT_VARIABLE TMP_DATE) EXECUTE_PROCESS(COMMAND cmd /c date /T
OUTPUT_VARIABLE TMP_DATE OUTPUT_STRIP_TRAILING_WHITESPACE)
ELSEIF(UNIX) ELSEIF(UNIX)
EXECUTE_PROCESS(COMMAND date "+%Y-%m-%d %H:%M:%S" OUTPUT_VARIABLE TMP_DATE OUTPUT_STRIP_TRAILING_WHITESPACE) EXECUTE_PROCESS(COMMAND date "+%Y-%m-%d %H:%M:%S"
OUTPUT_VARIABLE TMP_DATE OUTPUT_STRIP_TRAILING_WHITESPACE)
ELSE() ELSE()
SET(TMP_DATE "(no date command known for this platform)") SET(TMP_DATE "(no date command known for this platform)")
ENDIF() ENDIF()
......
...@@ -54,7 +54,7 @@ MACRO(GET_MYSQL_VERSION) ...@@ -54,7 +54,7 @@ MACRO(GET_MYSQL_VERSION)
ENDIF() ENDIF()
SET(VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}${EXTRA_VERSION}") SET(VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}${EXTRA_VERSION}")
MESSAGE("-- MySQL ${VERSION}") MESSAGE(STATUS "MySQL ${VERSION}")
SET(MYSQL_BASE_VERSION "${MAJOR_VERSION}.${MINOR_VERSION}" CACHE INTERNAL "MySQL Base version") SET(MYSQL_BASE_VERSION "${MAJOR_VERSION}.${MINOR_VERSION}" CACHE INTERNAL "MySQL Base version")
SET(MYSQL_NO_DASH_VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}") SET(MYSQL_NO_DASH_VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}")
# Use NDBVERSION irregardless of whether this is Cluster or not, if not # Use NDBVERSION irregardless of whether this is Cluster or not, if not
......
...@@ -123,7 +123,7 @@ IF(NOT VERSION) ...@@ -123,7 +123,7 @@ IF(NOT VERSION)
SET(package_name "mysql${PRODUCT_TAG}-${VERSION}-${SYSTEM_NAME_AND_PROCESSOR}") SET(package_name "mysql${PRODUCT_TAG}-${VERSION}-${SYSTEM_NAME_AND_PROCESSOR}")
ENDIF() ENDIF()
MESSAGE("-- Packaging as: ${package_name}") MESSAGE(STATUS "Packaging as: ${package_name}")
# Sometimes package suffix is added (something like "-icc-glibc23") # Sometimes package suffix is added (something like "-icc-glibc23")
IF(PACKAGE_SUFFIX) IF(PACKAGE_SUFFIX)
......
...@@ -17,6 +17,7 @@ update test.t1 set value2=value2+1, value3=value3+1 where id=12; ...@@ -17,6 +17,7 @@ update test.t1 set value2=value2+1, value3=value3+1 where id=12;
SET i = i + 1; SET i = i + 1;
END WHILE; END WHILE;
END| END|
set autocommit=0;
CALL update_t1(); CALL update_t1();
select * from t1; select * from t1;
id value value2 value3 id value value2 value3
...@@ -31,11 +32,22 @@ id value value2 value3 ...@@ -31,11 +32,22 @@ id value value2 value3
18 18 18 18 18 18 18 18
19 19 19 19 19 19 19 19
20 20 20 20 20 20 20 20
set autocommit=1;
select * from t1;
id value value2 value3
10 10 10 10
11 11 11 11
12 12 5012 5012
13 13 13 13
14 14 14 14
15 15 15 15
16 16 16 16
17 17 17 17
18 18 18 18
19 19 19 19
20 20 20 20
select * from t1 force index(value) where value=12; select * from t1 force index(value) where value=12;
kill query @id; kill query @id;
ERROR 70100: Query execution was interrupted ERROR 70100: Query execution was interrupted
select * from t1 where value = 12;
id value value2 value3
12 12 12 12
drop procedure if exists update_t1; drop procedure if exists update_t1;
drop table if exists t1; drop table if exists t1;
...@@ -48,9 +48,11 @@ BEGIN ...@@ -48,9 +48,11 @@ BEGIN
END| END|
delimiter ;| delimiter ;|
set autocommit=0;
CALL update_t1(); CALL update_t1();
select * from t1; select * from t1;
set autocommit=1;
select * from t1;
# #
# Now try to fire select query from connection-1 enforcing # Now try to fire select query from connection-1 enforcing
...@@ -66,6 +68,10 @@ select * from t1 force index(value) where value=12; ...@@ -66,6 +68,10 @@ select * from t1 force index(value) where value=12;
# select is going to take good time so let's kill query. # select is going to take good time so let's kill query.
# #
connection conn3; connection conn3;
let $wait_condition=
select * from information_schema.processlist where state = 'Sending data' and
info = 'select * from t1 force index(value) where value=12';
--source include/wait_condition.inc
let $ignore= `SELECT @id := $ID`; let $ignore= `SELECT @id := $ID`;
kill query @id; kill query @id;
...@@ -75,7 +81,6 @@ kill query @id; ...@@ -75,7 +81,6 @@ kill query @id;
connection conn1; connection conn1;
--error ER_QUERY_INTERRUPTED --error ER_QUERY_INTERRUPTED
reap; reap;
select * from t1 where value = 12;
# #
# clean test-bed. # clean test-bed.
......
...@@ -66,6 +66,22 @@ ...@@ -66,6 +66,22 @@
*/ */
#define FMT_G_BUFSIZE(PREC) (3 + (PREC) + 5 + 1) #define FMT_G_BUFSIZE(PREC) (3 + (PREC) + 5 + 1)
/*
Explicit instantiation to unsigned int of template available_buffer
function.
*/
template unsigned int available_buffer<unsigned int>(const char*,
const char*,
unsigned int);
/*
Explicit instantiation to unsigned int of template valid_buffer_range
function.
*/
template bool valid_buffer_range<unsigned int>(unsigned int,
const char*,
const char*,
unsigned int);
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
static int rows_event_stmt_cleanup(Relay_log_info const *rli, THD* thd); static int rows_event_stmt_cleanup(Relay_log_info const *rli, THD* thd);
...@@ -1299,7 +1315,7 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len, ...@@ -1299,7 +1315,7 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
ev = new Rand_log_event(buf, description_event); ev = new Rand_log_event(buf, description_event);
break; break;
case USER_VAR_EVENT: case USER_VAR_EVENT:
ev = new User_var_log_event(buf, description_event); ev = new User_var_log_event(buf, event_len, description_event);
break; break;
case FORMAT_DESCRIPTION_EVENT: case FORMAT_DESCRIPTION_EVENT:
ev = new Format_description_log_event(buf, event_len, description_event); ev = new Format_description_log_event(buf, event_len, description_event);
...@@ -5812,19 +5828,35 @@ void User_var_log_event::pack_info(Protocol* protocol) ...@@ -5812,19 +5828,35 @@ void User_var_log_event::pack_info(Protocol* protocol)
User_var_log_event:: User_var_log_event::
User_var_log_event(const char* buf, User_var_log_event(const char* buf, uint event_len,
const Format_description_log_event* description_event) const Format_description_log_event* description_event)
:Log_event(buf, description_event) :Log_event(buf, description_event)
#ifndef MYSQL_CLIENT #ifndef MYSQL_CLIENT
, deferred(false) , deferred(false)
#endif #endif
{ {
bool error= false;
const char* buf_start= buf;
/* The Post-Header is empty. The Variable Data part begins immediately. */ /* The Post-Header is empty. The Variable Data part begins immediately. */
const char *start= buf; const char *start= buf;
buf+= description_event->common_header_len + buf+= description_event->common_header_len +
description_event->post_header_len[USER_VAR_EVENT-1]; description_event->post_header_len[USER_VAR_EVENT-1];
name_len= uint4korr(buf); name_len= uint4korr(buf);
name= (char *) buf + UV_NAME_LEN_SIZE; name= (char *) buf + UV_NAME_LEN_SIZE;
/*
We don't know yet is_null value, so we must assume that name_len
may have the bigger value possible, is_null= True and there is no
payload for val.
*/
if (0 == name_len ||
!valid_buffer_range<uint>(name_len, buf_start, name,
event_len - UV_VAL_IS_NULL))
{
error= true;
goto err;
}
buf+= UV_NAME_LEN_SIZE + name_len; buf+= UV_NAME_LEN_SIZE + name_len;
is_null= (bool) *buf; is_null= (bool) *buf;
flags= User_var_log_event::UNDEF_F; // defaults to UNDEF_F flags= User_var_log_event::UNDEF_F; // defaults to UNDEF_F
...@@ -5837,6 +5869,14 @@ User_var_log_event(const char* buf, ...@@ -5837,6 +5869,14 @@ User_var_log_event(const char* buf,
} }
else else
{ {
if (!valid_buffer_range<uint>(UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE
+ UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE,
buf_start, buf, event_len))
{
error= true;
goto err;
}
type= (Item_result) buf[UV_VAL_IS_NULL]; type= (Item_result) buf[UV_VAL_IS_NULL];
charset_number= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE); charset_number= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE);
val_len= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE + val_len= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
...@@ -5844,6 +5884,12 @@ User_var_log_event(const char* buf, ...@@ -5844,6 +5884,12 @@ User_var_log_event(const char* buf,
val= (char *) (buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE + val= (char *) (buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE); UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE);
if (!valid_buffer_range<uint>(val_len, buf_start, val, event_len))
{
error= true;
goto err;
}
/** /**
We need to check if this is from an old server We need to check if this is from an old server
that did not pack information for flags. that did not pack information for flags.
...@@ -5865,6 +5911,10 @@ User_var_log_event(const char* buf, ...@@ -5865,6 +5911,10 @@ User_var_log_event(const char* buf,
val_len); val_len);
} }
} }
err:
if (error)
name= 0;
} }
...@@ -6014,8 +6064,9 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info) ...@@ -6014,8 +6064,9 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
char *hex_str; char *hex_str;
CHARSET_INFO *cs; CHARSET_INFO *cs;
if (!(hex_str= (char *)my_alloca(2*val_len+1+2))) // 2 hex digits / byte hex_str= (char *)my_malloc(2*val_len+1+2,MYF(MY_WME)); // 2 hex digits / byte
break; // no error, as we are 'void' if (!hex_str)
return;
str_to_hex(hex_str, val, val_len); str_to_hex(hex_str, val, val_len);
/* /*
For proper behaviour when mysqlbinlog|mysql, we need to explicitely For proper behaviour when mysqlbinlog|mysql, we need to explicitely
...@@ -6033,7 +6084,7 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info) ...@@ -6033,7 +6084,7 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
my_b_printf(&cache, ":=_%s %s COLLATE `%s`%s\n", my_b_printf(&cache, ":=_%s %s COLLATE `%s`%s\n",
cs->csname, hex_str, cs->name, cs->csname, hex_str, cs->name,
print_event_info->delimiter); print_event_info->delimiter);
my_afree(hex_str); my_free(hex_str);
} }
break; break;
case ROW_RESULT: case ROW_RESULT:
......
...@@ -2577,7 +2577,7 @@ public: ...@@ -2577,7 +2577,7 @@ public:
void print(FILE* file, PRINT_EVENT_INFO* print_event_info); void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif #endif
User_var_log_event(const char* buf, User_var_log_event(const char* buf, uint event_len,
const Format_description_log_event *description_event); const Format_description_log_event *description_event);
~User_var_log_event() {} ~User_var_log_event() {}
Log_event_type get_type_code() { return USER_VAR_EVENT;} Log_event_type get_type_code() { return USER_VAR_EVENT;}
...@@ -2591,7 +2591,7 @@ public: ...@@ -2591,7 +2591,7 @@ public:
bool is_deferred() { return deferred; } bool is_deferred() { return deferred; }
void set_deferred() { deferred= true; } void set_deferred() { deferred= true; }
#endif #endif
bool is_valid() const { return 1; } bool is_valid() const { return name != 0; }
private: private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
......
...@@ -8412,6 +8412,13 @@ int QUICK_INDEX_MERGE_SELECT::get_next() ...@@ -8412,6 +8412,13 @@ int QUICK_INDEX_MERGE_SELECT::get_next()
If a Clustered PK scan is present, it is used only to check if row If a Clustered PK scan is present, it is used only to check if row
satisfies its condition (and never used for row retrieval). satisfies its condition (and never used for row retrieval).
Locking: to ensure that exclusive locks are only set on records that
are included in the final result we must release the lock
on all rows we read but do not include in the final result. This
must be done on each index that reads the record and the lock
must be released using the same handler (the same quick object) as
used when reading the record.
RETURN RETURN
0 - Ok 0 - Ok
other - Error code if any error occurred. other - Error code if any error occurred.
...@@ -8421,6 +8428,12 @@ int QUICK_ROR_INTERSECT_SELECT::get_next() ...@@ -8421,6 +8428,12 @@ int QUICK_ROR_INTERSECT_SELECT::get_next()
{ {
List_iterator_fast<QUICK_RANGE_SELECT> quick_it(quick_selects); List_iterator_fast<QUICK_RANGE_SELECT> quick_it(quick_selects);
QUICK_RANGE_SELECT* quick; QUICK_RANGE_SELECT* quick;
/* quick that reads the given rowid first. This is needed in order
to be able to unlock the row using the same handler object that locked
it */
QUICK_RANGE_SELECT* quick_with_last_rowid;
int error, cmp; int error, cmp;
uint last_rowid_count=0; uint last_rowid_count=0;
DBUG_ENTER("QUICK_ROR_INTERSECT_SELECT::get_next"); DBUG_ENTER("QUICK_ROR_INTERSECT_SELECT::get_next");
...@@ -8433,7 +8446,10 @@ int QUICK_ROR_INTERSECT_SELECT::get_next() ...@@ -8433,7 +8446,10 @@ int QUICK_ROR_INTERSECT_SELECT::get_next()
if (cpk_quick) if (cpk_quick)
{ {
while (!error && !cpk_quick->row_in_ranges()) while (!error && !cpk_quick->row_in_ranges())
{
quick->file->unlock_row(); /* row not in range; unlock */
error= quick->get_next(); error= quick->get_next();
}
} }
if (error) if (error)
DBUG_RETURN(error); DBUG_RETURN(error);
...@@ -8441,6 +8457,7 @@ int QUICK_ROR_INTERSECT_SELECT::get_next() ...@@ -8441,6 +8457,7 @@ int QUICK_ROR_INTERSECT_SELECT::get_next()
quick->file->position(quick->record); quick->file->position(quick->record);
memcpy(last_rowid, quick->file->ref, head->file->ref_length); memcpy(last_rowid, quick->file->ref, head->file->ref_length);
last_rowid_count= 1; last_rowid_count= 1;
quick_with_last_rowid= quick;
while (last_rowid_count < quick_selects.elements) while (last_rowid_count < quick_selects.elements)
{ {
...@@ -8453,9 +8470,17 @@ int QUICK_ROR_INTERSECT_SELECT::get_next() ...@@ -8453,9 +8470,17 @@ int QUICK_ROR_INTERSECT_SELECT::get_next()
do do
{ {
if ((error= quick->get_next())) if ((error= quick->get_next()))
{
quick_with_last_rowid->file->unlock_row();
DBUG_RETURN(error); DBUG_RETURN(error);
}
quick->file->position(quick->record); quick->file->position(quick->record);
cmp= head->file->cmp_ref(quick->file->ref, last_rowid); cmp= head->file->cmp_ref(quick->file->ref, last_rowid);
if (cmp < 0)
{
/* This row is being skipped. Release lock on it. */
quick->file->unlock_row();
}
} while (cmp < 0); } while (cmp < 0);
/* Ok, current select 'caught up' and returned ref >= cur_ref */ /* Ok, current select 'caught up' and returned ref >= cur_ref */
...@@ -8466,13 +8491,19 @@ int QUICK_ROR_INTERSECT_SELECT::get_next() ...@@ -8466,13 +8491,19 @@ int QUICK_ROR_INTERSECT_SELECT::get_next()
{ {
while (!cpk_quick->row_in_ranges()) while (!cpk_quick->row_in_ranges())
{ {
quick->file->unlock_row(); /* row not in range; unlock */
if ((error= quick->get_next())) if ((error= quick->get_next()))
{
quick_with_last_rowid->file->unlock_row();
DBUG_RETURN(error); DBUG_RETURN(error);
}
} }
quick->file->position(quick->record); quick->file->position(quick->record);
} }
memcpy(last_rowid, quick->file->ref, head->file->ref_length); memcpy(last_rowid, quick->file->ref, head->file->ref_length);
quick_with_last_rowid->file->unlock_row();
last_rowid_count= 1; last_rowid_count= 1;
quick_with_last_rowid= quick;
} }
else else
{ {
......
...@@ -151,6 +151,41 @@ ...@@ -151,6 +151,41 @@
*/ */
#define OPTION_ALLOW_BATCH (ULL(1) << 36) // THD, intern (slave) #define OPTION_ALLOW_BATCH (ULL(1) << 36) // THD, intern (slave)
/*
Check how many bytes are available on buffer.
@param buf_start Pointer to buffer start.
@param buf_current Pointer to the current position on buffer.
@param buf_len Buffer length.
@return Number of bytes available on event buffer.
*/
template <class T> T available_buffer(const char* buf_start,
const char* buf_current,
T buf_len)
{
return buf_len - (buf_current - buf_start);
}
/*
Check if jump value is within buffer limits.
@param jump Number of positions we want to advance.
@param buf_start Pointer to buffer start
@param buf_current Pointer to the current position on buffer.
@param buf_len Buffer length.
@return True If jump value is within buffer limits.
False Otherwise.
*/
template <class T> bool valid_buffer_range(T jump,
const char* buf_start,
const char* buf_current,
T buf_len)
{
return (jump <= available_buffer(buf_start, buf_current, buf_len));
}
/* The rest of the file is included in the server only */ /* The rest of the file is included in the server only */
#ifndef MYSQL_CLIENT #ifndef MYSQL_CLIENT
......
...@@ -7196,15 +7196,8 @@ void JOIN::cleanup(bool full) ...@@ -7196,15 +7196,8 @@ void JOIN::cleanup(bool full)
} }
} }
} }
/*
We are not using tables anymore
Unlock all tables. We may be in an INSERT .... SELECT statement.
*/
if (full) if (full)
{ {
if (tmp_join)
tmp_table_param.copy_field= 0;
/* /*
Ensure that the following delete_elements() would not be called Ensure that the following delete_elements() would not be called
twice for the same list. twice for the same list.
......
...@@ -112,13 +112,17 @@ innobase_col_to_mysql( ...@@ -112,13 +112,17 @@ innobase_col_to_mysql(
/* These column types should never be shipped to MySQL. */ /* These column types should never be shipped to MySQL. */
ut_ad(0); ut_ad(0);
case DATA_CHAR:
case DATA_FIXBINARY: case DATA_FIXBINARY:
case DATA_FLOAT: case DATA_FLOAT:
case DATA_DOUBLE: case DATA_DOUBLE:
case DATA_DECIMAL: case DATA_DECIMAL:
/* Above are the valid column types for MySQL data. */ /* Above are the valid column types for MySQL data. */
ut_ad(flen == len); ut_ad(flen == len);
/* fall through */
case DATA_CHAR:
/* We may have flen > len when there is a shorter
prefix on a CHAR column. */
ut_ad(flen >= len);
#else /* UNIV_DEBUG */ #else /* UNIV_DEBUG */
default: default:
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
......
...@@ -4847,11 +4847,15 @@ row_search_autoinc_read_column( ...@@ -4847,11 +4847,15 @@ row_search_autoinc_read_column(
rec_offs_init(offsets_); rec_offs_init(offsets_);
offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); offsets = rec_get_offsets(rec, index, offsets, col_no + 1, &heap);
data = rec_get_nth_field(rec, offsets, col_no, &len); if (rec_offs_nth_sql_null(offsets, col_no)) {
/* There is no non-NULL value in the auto-increment column. */
value = 0;
goto func_exit;
}
ut_a(len != UNIV_SQL_NULL); data = rec_get_nth_field(rec, offsets, col_no, &len);
switch (mtype) { switch (mtype) {
case DATA_INT: case DATA_INT:
...@@ -4873,14 +4877,15 @@ row_search_autoinc_read_column( ...@@ -4873,14 +4877,15 @@ row_search_autoinc_read_column(
ut_error; ut_error;
} }
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
if (!unsigned_type && (ib_int64_t) value < 0) { if (!unsigned_type && (ib_int64_t) value < 0) {
value = 0; value = 0;
} }
func_exit:
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(value); return(value);
} }
......
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