mirror of
https://github.com/MariaDB/server.git
synced 2026-04-19 06:45:32 +02:00
Applied all changes from Igor and Sanja
This commit is contained in:
parent
3143ad589a
commit
5f1f2fc0e4
162 changed files with 11674 additions and 6268 deletions
7
TODO
7
TODO
|
|
@ -32,12 +32,10 @@ Short time TODO:
|
|||
- add support for host_error()
|
||||
- Enable performance_schema.host_cache in scripts/mysql_system_tables.sql
|
||||
|
||||
- Add full support for automatic timestamp.
|
||||
(remove timestamp handling from ha_write())
|
||||
- Timour is working on this
|
||||
|
||||
- Add Sys_my_bind_addr(); Needed for perfschema
|
||||
|
||||
- Add support for format_section_buff in unireg.cc and table.cc
|
||||
|
||||
- mysql_socket_shutdown() was removed from vio/viosocket.cc.
|
||||
It was replaced with inline function in include/mysql/psi/mysql_socket.h
|
||||
but this doesn't call DisconnectEx(). We should check if we need to
|
||||
|
|
@ -60,4 +58,3 @@ Sergei's notes:
|
|||
rpl_slave.cc
|
||||
XXX in mysql_client_test
|
||||
net_serv.cc
|
||||
|
||||
|
|
|
|||
|
|
@ -138,6 +138,38 @@ extern MY_UNI_CTYPE my_uni_ctype[256];
|
|||
#define MY_REPERTOIRE_EXTENDED 2 /* Extended characters: U+0080..U+FFFF */
|
||||
#define MY_REPERTOIRE_UNICODE30 3 /* ASCII | EXTENDED: U+0000..U+FFFF */
|
||||
|
||||
/* Flags for strxfrm */
|
||||
#define MY_STRXFRM_LEVEL1 0x00000001 /* for primary weights */
|
||||
#define MY_STRXFRM_LEVEL2 0x00000002 /* for secondary weights */
|
||||
#define MY_STRXFRM_LEVEL3 0x00000004 /* for tertiary weights */
|
||||
#define MY_STRXFRM_LEVEL4 0x00000008 /* fourth level weights */
|
||||
#define MY_STRXFRM_LEVEL5 0x00000010 /* fifth level weights */
|
||||
#define MY_STRXFRM_LEVEL6 0x00000020 /* sixth level weights */
|
||||
#define MY_STRXFRM_LEVEL_ALL 0x0000003F /* Bit OR for the above six */
|
||||
#define MY_STRXFRM_NLEVELS 6 /* Number of possible levels*/
|
||||
|
||||
#define MY_STRXFRM_PAD_WITH_SPACE 0x00000040 /* if pad result with spaces */
|
||||
#define MY_STRXFRM_PAD_TO_MAXLEN 0x00000080 /* if pad tail(for filesort) */
|
||||
|
||||
#define MY_STRXFRM_DESC_LEVEL1 0x00000100 /* if desc order for level1 */
|
||||
#define MY_STRXFRM_DESC_LEVEL2 0x00000200 /* if desc order for level2 */
|
||||
#define MY_STRXFRM_DESC_LEVEL3 0x00000300 /* if desc order for level3 */
|
||||
#define MY_STRXFRM_DESC_LEVEL4 0x00000800 /* if desc order for level4 */
|
||||
#define MY_STRXFRM_DESC_LEVEL5 0x00001000 /* if desc order for level5 */
|
||||
#define MY_STRXFRM_DESC_LEVEL6 0x00002000 /* if desc order for level6 */
|
||||
#define MY_STRXFRM_DESC_SHIFT 8
|
||||
|
||||
#define MY_STRXFRM_UNUSED_00004000 0x00004000 /* for future extensions */
|
||||
#define MY_STRXFRM_UNUSED_00008000 0x00008000 /* for future extensions */
|
||||
|
||||
#define MY_STRXFRM_REVERSE_LEVEL1 0x00010000 /* if reverse order for level1 */
|
||||
#define MY_STRXFRM_REVERSE_LEVEL2 0x00020000 /* if reverse order for level2 */
|
||||
#define MY_STRXFRM_REVERSE_LEVEL3 0x00040000 /* if reverse order for level3 */
|
||||
#define MY_STRXFRM_REVERSE_LEVEL4 0x00080000 /* if reverse order for level4 */
|
||||
#define MY_STRXFRM_REVERSE_LEVEL5 0x00100000 /* if reverse order for level5 */
|
||||
#define MY_STRXFRM_REVERSE_LEVEL6 0x00200000 /* if reverse order for level6 */
|
||||
#define MY_STRXFRM_REVERSE_SHIFT 16
|
||||
|
||||
struct my_uni_idx_st
|
||||
{
|
||||
uint16 from;
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ extern uint bitmap_set_next(MY_BITMAP *map);
|
|||
extern uint bitmap_get_first(const MY_BITMAP *map);
|
||||
extern uint bitmap_get_first_set(const MY_BITMAP *map);
|
||||
extern uint bitmap_bits_set(const MY_BITMAP *map);
|
||||
extern uint bitmap_get_next_set(const MY_BITMAP *map, uint bitmap_bit);
|
||||
extern void bitmap_free(MY_BITMAP *map);
|
||||
extern void bitmap_set_above(MY_BITMAP *map, uint from_byte, uint use_bit);
|
||||
extern void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size);
|
||||
|
|
|
|||
|
|
@ -1,34 +0,0 @@
|
|||
# Install script for directory: /my/maria-10.0-merge/libevent
|
||||
|
||||
# Set the install prefix
|
||||
IF(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
||||
SET(CMAKE_INSTALL_PREFIX "/usr/local/mysql")
|
||||
ENDIF(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
||||
STRING(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
|
||||
|
||||
# Set the install configuration name.
|
||||
IF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
|
||||
IF(BUILD_TYPE)
|
||||
STRING(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
|
||||
CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
|
||||
ELSE(BUILD_TYPE)
|
||||
SET(CMAKE_INSTALL_CONFIG_NAME "Debug")
|
||||
ENDIF(BUILD_TYPE)
|
||||
MESSAGE(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
|
||||
ENDIF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
|
||||
|
||||
# Set the component getting installed.
|
||||
IF(NOT CMAKE_INSTALL_COMPONENT)
|
||||
IF(COMPONENT)
|
||||
MESSAGE(STATUS "Install component: \"${COMPONENT}\"")
|
||||
SET(CMAKE_INSTALL_COMPONENT "${COMPONENT}")
|
||||
ELSE(COMPONENT)
|
||||
SET(CMAKE_INSTALL_COMPONENT)
|
||||
ENDIF(COMPONENT)
|
||||
ENDIF(NOT CMAKE_INSTALL_COMPONENT)
|
||||
|
||||
# Install shared libraries without execute permission?
|
||||
IF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)
|
||||
SET(CMAKE_INSTALL_SO_NO_EXE "0")
|
||||
ENDIF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)
|
||||
|
||||
|
|
@ -64,7 +64,8 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
|
|||
../sql/sql_analyse.cc ../sql/sql_base.cc ../sql/sql_cache.cc
|
||||
../sql/sql_class.cc ../sql/sql_crypt.cc ../sql/sql_cursor.cc
|
||||
../sql/sql_db.cc ../sql/sql_delete.cc ../sql/sql_derived.cc
|
||||
../sql/sql_do.cc ../sql/sql_error.cc ../sql/sql_handler.cc
|
||||
../sql/sql_do.cc ../sql/sql_error.cc ../sql/sql_handler.cc
|
||||
../sql/sql_get_diagnostics.cc
|
||||
../sql/sql_help.cc ../sql/sql_insert.cc ../sql/datadict.cc
|
||||
../sql/sql_admin.cc ../sql/sql_truncate.cc ../sql/sql_reload.cc
|
||||
../sql/sql_lex.cc ../sql/keycaches.cc
|
||||
|
|
@ -118,7 +119,7 @@ ENDIF()
|
|||
|
||||
|
||||
SET(LIBS
|
||||
dbug strings regex mysys vio
|
||||
dbug strings regex mysys mysys_ssl vio
|
||||
${ZLIB_LIBRARY} ${SSL_LIBRARIES}
|
||||
${LIBWRAP} ${LIBCRYPT} ${LIBDL}
|
||||
${MYSQLD_STATIC_PLUGIN_LIBS}
|
||||
|
|
|
|||
|
|
@ -487,7 +487,7 @@ int emb_load_querycache_result(THD *thd, Querycache_stream *src)
|
|||
data->embedded_info->prev_ptr= prev_row;
|
||||
return_ok:
|
||||
net_send_eof(thd, thd->server_status,
|
||||
thd->warning_info->statement_warn_count());
|
||||
thd->get_stmt_da()->statement_warn_count());
|
||||
DBUG_RETURN(0);
|
||||
err:
|
||||
DBUG_RETURN(1);
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
|
|||
|
||||
/* Clear result variables */
|
||||
thd->clear_error();
|
||||
thd->stmt_da->reset_diagnostics_area();
|
||||
thd->get_stmt_da()->reset_diagnostics_area();
|
||||
mysql->affected_rows= ~(my_ulonglong) 0;
|
||||
mysql->field_count= 0;
|
||||
net_clear_error(net);
|
||||
|
|
@ -241,7 +241,7 @@ static my_bool emb_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt)
|
|||
stmt->stmt_id= thd->client_stmt_id;
|
||||
stmt->param_count= thd->client_param_count;
|
||||
stmt->field_count= 0;
|
||||
mysql->warning_count= thd->warning_info->statement_warn_count();
|
||||
mysql->warning_count= thd->get_stmt_da()->statement_warn_count();
|
||||
|
||||
if (thd->first_data)
|
||||
{
|
||||
|
|
@ -428,7 +428,7 @@ static void emb_free_embedded_thd(MYSQL *mysql)
|
|||
static const char * emb_read_statistics(MYSQL *mysql)
|
||||
{
|
||||
THD *thd= (THD*)mysql->thd;
|
||||
return thd->is_error() ? thd->stmt_da->message() : "";
|
||||
return thd->is_error() ? thd->get_stmt_da()->message() : "";
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1045,7 +1045,7 @@ bool Protocol::send_result_set_metadata(List<Item> *list, uint flags)
|
|||
|
||||
if (flags & SEND_EOF)
|
||||
write_eof_packet(thd, thd->server_status,
|
||||
thd->warning_info->statement_warn_count());
|
||||
thd->get_stmt_da()->statement_warn_count());
|
||||
|
||||
DBUG_RETURN(prepare_for_send(list->elements));
|
||||
err:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2007, 2010, Oracle and/or its affiliates
|
||||
# Copyright (c) 2007, 2012, Oracle and/or its affiliates
|
||||
# Copyright (c) 2010, 2012, Monty Program Ab
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
|
|
@ -50,18 +50,36 @@ loose-innodb_log_files_in_group= 2
|
|||
|
||||
slave-net-timeout=120
|
||||
|
||||
# MAINTAINER:
|
||||
# the loose- syntax is to make sure the cnf file is also
|
||||
# valid when building without the performance schema.
|
||||
|
||||
# Run tests with the performance schema instrumentation
|
||||
loose-enable-performance-schema
|
||||
# Run tests with a small number of instrumented objects
|
||||
# to limit memory consumption with MTR
|
||||
loose-performance-schema-accounts-size=100
|
||||
loose-performance-schema-digests-size=200
|
||||
loose-performance-schema-hosts-size=100
|
||||
loose-performance-schema-users-size=100
|
||||
loose-performance-schema-max-mutex-instances=5000
|
||||
loose-performance-schema-max-rwlock-instances=5000
|
||||
loose-performance-schema-max-cond-instances=1000
|
||||
loose-performance-schema-max-file-instances=10000
|
||||
loose-performance-schema-max-socket-instances=1000
|
||||
loose-performance-schema-max-table-instances=500
|
||||
loose-performance-schema-max-table-handles=1000
|
||||
|
||||
loose-performance-schema-events-waits-history-size=10
|
||||
loose-performance-schema-events-waits-history-long-size=10000
|
||||
loose-performance-schema-events-stages-history-size=10
|
||||
loose-performance-schema-events-stages-history-long-size=1000
|
||||
loose-performance-schema-events-statements-history-size=10
|
||||
loose-performance-schema-events-statements-history-long-size=1000
|
||||
loose-performance-schema-max-thread-instances=200
|
||||
loose-performance-schema-session-connect-attrs-size=2048
|
||||
|
||||
# Enable everything, for maximun code exposure during testing
|
||||
|
||||
loose-performance-schema-instrument='%=ON'
|
||||
|
||||
|
|
|
|||
15
mysql-test/suite/perfschema/include/sizing_auto.inc
Normal file
15
mysql-test/suite/perfschema/include/sizing_auto.inc
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
show variables like "table_definition_cache";
|
||||
show variables like "table_open_cache";
|
||||
show variables like "max_connections";
|
||||
# Results vary by platform:
|
||||
# show variables like "open_files_limit";
|
||||
show variables like "%performance_schema%";
|
||||
show status like "%performance_schema%";
|
||||
|
||||
# Each test script should provide a different test.cnf file,
|
||||
# with different settings.
|
||||
# This output will show the sizes computed automatically.
|
||||
# Note that this output is very dependent on the platform.
|
||||
|
||||
show engine performance_schema status;
|
||||
|
|
@ -67,7 +67,8 @@ static my_hash_value_type calc_hash(const HASH *hash,
|
|||
@param[in] get_key get the key for the hash
|
||||
@param[in] free_element pointer to the function that
|
||||
does cleanup
|
||||
@return inidicates success or failure of initialization
|
||||
@param[in] flags flags set in the hash
|
||||
@return indicates success or failure of initialization
|
||||
@retval 0 success
|
||||
@retval 1 failure
|
||||
*/
|
||||
|
|
|
|||
329
mysys/md5.c
329
mysys/md5.c
|
|
@ -1,329 +0,0 @@
|
|||
/* Copyright (C) 2000 MySQL 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
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
/*
|
||||
* This code implements the MD5 message-digest algorithm.
|
||||
* The algorithm is due to Ron Rivest. This code was
|
||||
* written by Colin Plumb in 1993, no copyright is claimed.
|
||||
* This code is in the public domain; do with it what you wish.
|
||||
*
|
||||
* Equivalent code is available from RSA Data Security, Inc.
|
||||
* This code has been tested against that, and is equivalent,
|
||||
* except that you don't need to include two pages of legalese
|
||||
* with every copy.
|
||||
*
|
||||
* To compute the message digest of a chunk of bytes, declare an
|
||||
* MD5Context structure, pass it to MD5Init, call MD5Update as
|
||||
* needed on buffers full of bytes, and then call MD5Final, which
|
||||
* will fill a supplied 16-byte array with the digest.
|
||||
*/
|
||||
|
||||
/* This code was modified in 1997 by Jim Kingdon of Cyclic Software to
|
||||
not require an integer type which is exactly 32 bits. This work
|
||||
draws on the changes for the same purpose by Tatu Ylonen
|
||||
<ylo@cs.hut.fi> as part of SSH, but since I didn't actually use
|
||||
that code, there is no copyright issue. I hereby disclaim
|
||||
copyright in any changes I have made; this code remains in the
|
||||
public domain. */
|
||||
|
||||
/*
|
||||
Skip entirely if built with OpenSSL/YaSSL support.
|
||||
*/
|
||||
#if !defined(HAVE_OPENSSL) && !defined(HAVE_YASSL)
|
||||
|
||||
#include <my_global.h>
|
||||
#include <m_string.h>
|
||||
#include "my_md5.h"
|
||||
|
||||
static void
|
||||
my_MD5Transform (cvs_uint32 buf[4], const unsigned char in[64]);
|
||||
|
||||
/* Little-endian byte-swapping routines. Note that these do not
|
||||
depend on the size of datatypes such as uint32, nor do they require
|
||||
us to detect the endianness of the machine we are running on. It
|
||||
is possible they should be macros for speed, but I would be
|
||||
surprised if they were a performance bottleneck for MD5. */
|
||||
|
||||
static uint32 getu32 (const unsigned char *addr)
|
||||
{
|
||||
return (((((unsigned long)addr[3] << 8) | addr[2]) << 8)
|
||||
| addr[1]) << 8 | addr[0];
|
||||
}
|
||||
|
||||
static void
|
||||
putu32 (uint32 data, unsigned char *addr)
|
||||
{
|
||||
addr[0] = (unsigned char)data;
|
||||
addr[1] = (unsigned char)(data >> 8);
|
||||
addr[2] = (unsigned char)(data >> 16);
|
||||
addr[3] = (unsigned char)(data >> 24);
|
||||
}
|
||||
|
||||
/*
|
||||
Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
|
||||
initialization constants.
|
||||
*/
|
||||
void
|
||||
my_MD5Init (my_MD5Context *ctx)
|
||||
{
|
||||
ctx->buf[0] = 0x67452301;
|
||||
ctx->buf[1] = 0xefcdab89;
|
||||
ctx->buf[2] = 0x98badcfe;
|
||||
ctx->buf[3] = 0x10325476;
|
||||
|
||||
ctx->bits[0] = 0;
|
||||
ctx->bits[1] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Update context to reflect the concatenation of another buffer full
|
||||
of bytes.
|
||||
*/
|
||||
void
|
||||
my_MD5Update (my_MD5Context *ctx, unsigned char const *buf, unsigned len)
|
||||
{
|
||||
uint32 t;
|
||||
|
||||
/* Update bitcount */
|
||||
|
||||
t = ctx->bits[0];
|
||||
if ((ctx->bits[0] = (t + ((uint32)len << 3)) & 0xffffffff) < t)
|
||||
ctx->bits[1]++; /* Carry from low to high */
|
||||
ctx->bits[1] += len >> 29;
|
||||
|
||||
t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
|
||||
|
||||
/* Handle any leading odd-sized chunks */
|
||||
|
||||
if ( t ) {
|
||||
unsigned char *p = ctx->in + t;
|
||||
|
||||
t = 64-t;
|
||||
if (len < t) {
|
||||
memcpy(p, buf, len);
|
||||
return;
|
||||
}
|
||||
memcpy(p, buf, t);
|
||||
my_MD5Transform (ctx->buf, ctx->in);
|
||||
buf += t;
|
||||
len -= t;
|
||||
}
|
||||
|
||||
/* Process data in 64-byte chunks */
|
||||
|
||||
while (len >= 64) {
|
||||
memcpy(ctx->in, buf, 64);
|
||||
my_MD5Transform (ctx->buf, ctx->in);
|
||||
buf += 64;
|
||||
len -= 64;
|
||||
}
|
||||
|
||||
/* Handle any remaining bytes of data. */
|
||||
|
||||
memcpy(ctx->in, buf, len);
|
||||
}
|
||||
|
||||
/*
|
||||
Final wrapup - pad to 64-byte boundary with the bit pattern
|
||||
1 0* (64-bit count of bits processed, MSB-first)
|
||||
*/
|
||||
void
|
||||
my_MD5Final (unsigned char digest[16], my_MD5Context *ctx)
|
||||
{
|
||||
unsigned count;
|
||||
unsigned char *p;
|
||||
|
||||
/* Compute number of bytes mod 64 */
|
||||
count = (ctx->bits[0] >> 3) & 0x3F;
|
||||
|
||||
/* Set the first char of padding to 0x80. This is safe since there is
|
||||
always at least one byte free */
|
||||
p = ctx->in + count;
|
||||
*p++ = 0x80;
|
||||
|
||||
/* Bytes of padding needed to make 64 bytes */
|
||||
count = 64 - 1 - count;
|
||||
|
||||
/* Pad out to 56 mod 64 */
|
||||
if (count < 8) {
|
||||
/* Two lots of padding: Pad the first block to 64 bytes */
|
||||
memset(p, 0, count);
|
||||
my_MD5Transform (ctx->buf, ctx->in);
|
||||
|
||||
/* Now fill the next block with 56 bytes */
|
||||
memset(ctx->in, 0, 56);
|
||||
} else {
|
||||
/* Pad block to 56 bytes */
|
||||
memset(p, 0, count-8);
|
||||
}
|
||||
|
||||
/* Append length in bits and transform */
|
||||
putu32(ctx->bits[0], ctx->in + 56);
|
||||
putu32(ctx->bits[1], ctx->in + 60);
|
||||
|
||||
my_MD5Transform (ctx->buf, ctx->in);
|
||||
putu32(ctx->buf[0], digest);
|
||||
putu32(ctx->buf[1], digest + 4);
|
||||
putu32(ctx->buf[2], digest + 8);
|
||||
putu32(ctx->buf[3], digest + 12);
|
||||
memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
|
||||
}
|
||||
|
||||
#ifndef ASM_MD5
|
||||
|
||||
/* The four core functions - F1 is optimized somewhat */
|
||||
|
||||
/* #define F1(x, y, z) (x & y | ~x & z) */
|
||||
#define F1(x, y, z) (z ^ (x & (y ^ z)))
|
||||
#define F2(x, y, z) F1(z, x, y)
|
||||
#define F3(x, y, z) (x ^ y ^ z)
|
||||
#define F4(x, y, z) (y ^ (x | ~z))
|
||||
|
||||
/* This is the central step in the MD5 algorithm. */
|
||||
#define MD5STEP(f, w, x, y, z, data, s) \
|
||||
( w += f(x, y, z) + data, w &= 0xffffffff, w = w<<s | w>>(32-s), w += x )
|
||||
|
||||
/*
|
||||
* The core of the MD5 algorithm, this alters an existing MD5 hash to
|
||||
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
||||
* the data and converts bytes into longwords for this routine.
|
||||
*/
|
||||
static void
|
||||
my_MD5Transform (uint32 buf[4], const unsigned char inraw[64])
|
||||
{
|
||||
register uint32 a, b, c, d;
|
||||
uint32 in[16];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
in[i] = getu32 (inraw + 4 * i);
|
||||
|
||||
a = buf[0];
|
||||
b = buf[1];
|
||||
c = buf[2];
|
||||
d = buf[3];
|
||||
|
||||
MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[12]+0x6b901122, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
|
||||
|
||||
MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[10]+0x02441453, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
|
||||
|
||||
MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
|
||||
|
||||
MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
|
||||
|
||||
buf[0] += a;
|
||||
buf[1] += b;
|
||||
buf[2] += c;
|
||||
buf[3] += d;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
/*
|
||||
Simple test program. Can use it to manually run the tests from
|
||||
RFC1321 for example.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
my_MD5Context context;
|
||||
unsigned char checksum[16];
|
||||
int i;
|
||||
int j;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
fprintf (stderr, "usage: %s string-to-hash\n", argv[0]);
|
||||
exit (1);
|
||||
}
|
||||
for (j = 1; j < argc; ++j)
|
||||
{
|
||||
printf ("MD5 (\"%s\") = ", argv[j]);
|
||||
my_MD5Init (&context);
|
||||
my_MD5Update (&context, argv[j], strlen (argv[j]));
|
||||
my_MD5Final (checksum, &context);
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
printf ("%02x", (unsigned int) checksum[i]);
|
||||
}
|
||||
printf ("\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* TEST */
|
||||
|
||||
#endif /* !defined(HAVE_OPENSSL) && !defined(HAVE_YASSL) */
|
||||
|
|
@ -493,7 +493,7 @@ process_flags:
|
|||
if (my_b_write(info, (uchar*) buff, length2))
|
||||
goto err;
|
||||
}
|
||||
else if ((*fmt == 'l' && fmt[1] == 'd') || fmt[1] == 'u')
|
||||
else if ((*fmt == 'l' && (fmt[1] == 'd' || fmt[1] == 'u')))
|
||||
/* long parameter */
|
||||
{
|
||||
register long iarg;
|
||||
|
|
|
|||
|
|
@ -147,6 +147,26 @@ static inline void bitmap_unlock(MY_BITMAP *map __attribute__((unused)))
|
|||
}
|
||||
|
||||
|
||||
static inline uint get_first_set(my_bitmap_map value, uint word_pos)
|
||||
{
|
||||
uchar *byte_ptr= (uchar*)&value;
|
||||
uchar byte_value;
|
||||
uint byte_pos, bit_pos;
|
||||
|
||||
DBUG_ASSERT(value);
|
||||
for (byte_pos=0; ; byte_pos++, byte_ptr++)
|
||||
{
|
||||
if ((byte_value= *byte_ptr))
|
||||
{
|
||||
for (bit_pos=0; ; bit_pos++)
|
||||
if (byte_value & (1 << bit_pos))
|
||||
return (word_pos*32) + (byte_pos*8) + bit_pos;
|
||||
}
|
||||
}
|
||||
return MY_BIT_NONE; /* Impossible */
|
||||
}
|
||||
|
||||
|
||||
my_bool bitmap_init(MY_BITMAP *map, my_bitmap_map *buf, uint n_bits,
|
||||
my_bool thread_safe __attribute__((unused)))
|
||||
{
|
||||
|
|
@ -597,12 +617,10 @@ void bitmap_copy(MY_BITMAP *map, const MY_BITMAP *map2)
|
|||
|
||||
uint bitmap_get_first_set(const MY_BITMAP *map)
|
||||
{
|
||||
uchar *byte_ptr;
|
||||
uint i,j,k;
|
||||
my_bitmap_map *data_ptr, *end= map->last_word_ptr;
|
||||
uint i;
|
||||
my_bitmap_map *data_ptr= map->bitmap, *end= map->last_word_ptr;
|
||||
|
||||
DBUG_ASSERT(map->bitmap);
|
||||
data_ptr= map->bitmap;
|
||||
|
||||
for (i=0; data_ptr < end; data_ptr++, i++)
|
||||
if (*data_ptr)
|
||||
|
|
@ -611,25 +629,66 @@ uint bitmap_get_first_set(const MY_BITMAP *map)
|
|||
return MY_BIT_NONE;
|
||||
|
||||
found:
|
||||
{
|
||||
byte_ptr= (uchar*)data_ptr;
|
||||
for (j=0; ; j++, byte_ptr++)
|
||||
{
|
||||
if (*byte_ptr)
|
||||
{
|
||||
for (k=0; ; k++)
|
||||
{
|
||||
if (*byte_ptr & (1 << k))
|
||||
return (i*32) + (j*8) + k;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DBUG_ASSERT(0);
|
||||
return MY_BIT_NONE; /* Impossible */
|
||||
return get_first_set(*data_ptr, i);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Get the next set bit.
|
||||
|
||||
@param map Bitmap
|
||||
@param bitmap_bit Bit to start search from
|
||||
|
||||
@return Index to first bit set after bitmap_bit
|
||||
*/
|
||||
|
||||
uint bitmap_get_next_set(const MY_BITMAP *map, uint bitmap_bit)
|
||||
{
|
||||
uint word_pos, byte_to_mask, i;
|
||||
union { my_bitmap_map bitmap ; uchar bitmap_buff[sizeof(my_bitmap_map)]; }
|
||||
first_word;
|
||||
uchar *ptr= &first_word.bitmap_buff[0];
|
||||
my_bitmap_map *data_ptr, *end= map->last_word_ptr;
|
||||
|
||||
DBUG_ASSERT(map->bitmap);
|
||||
|
||||
/* Look for the next bit */
|
||||
bitmap_bit++;
|
||||
if (bitmap_bit >= map->n_bits)
|
||||
return MY_BIT_NONE;
|
||||
word_pos= bitmap_bit / 32;
|
||||
data_ptr= map->bitmap + word_pos;
|
||||
first_word.bitmap= *data_ptr;
|
||||
|
||||
/* Mask out previous bits from first_word */
|
||||
byte_to_mask= (bitmap_bit % 32) / 8;
|
||||
for (i= 0; i < byte_to_mask; i++)
|
||||
ptr[i]= 0;
|
||||
ptr[byte_to_mask]&= 0xFFU << (bitmap_bit & 7);
|
||||
|
||||
if (data_ptr == end)
|
||||
{
|
||||
if (first_word.bitmap & ~map->last_word_mask)
|
||||
return get_first_set(first_word.bitmap, word_pos);
|
||||
else
|
||||
return MY_BIT_NONE;
|
||||
}
|
||||
|
||||
if (first_word.bitmap)
|
||||
return get_first_set(first_word.bitmap, word_pos);
|
||||
|
||||
for (data_ptr++, word_pos++; data_ptr < end; data_ptr++, word_pos++)
|
||||
if (*data_ptr)
|
||||
return get_first_set(*data_ptr, word_pos);
|
||||
|
||||
if (!(*end & ~map->last_word_mask))
|
||||
return MY_BIT_NONE;
|
||||
return get_first_set(*end, word_pos);
|
||||
}
|
||||
|
||||
|
||||
/* Get first free bit */
|
||||
|
||||
uint bitmap_get_first(const MY_BITMAP *map)
|
||||
{
|
||||
uchar *byte_ptr;
|
||||
|
|
@ -647,17 +706,15 @@ uint bitmap_get_first(const MY_BITMAP *map)
|
|||
return MY_BIT_NONE;
|
||||
|
||||
found:
|
||||
byte_ptr= (uchar*)data_ptr;
|
||||
for (j=0; ; j++, byte_ptr++)
|
||||
{
|
||||
byte_ptr= (uchar*)data_ptr;
|
||||
for (j=0; ; j++, byte_ptr++)
|
||||
if (*byte_ptr != 0xFF)
|
||||
{
|
||||
if (*byte_ptr != 0xFF)
|
||||
for (k=0; ; k++)
|
||||
{
|
||||
for (k=0; ; k++)
|
||||
{
|
||||
if (!(*byte_ptr & (1 << k)))
|
||||
return (i*32) + (j*8) + k;
|
||||
}
|
||||
if (!(*byte_ptr & (1 << k)))
|
||||
return (i*32) + (j*8) + k;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
# CMake generated Testfile for
|
||||
# Source directory: /my/maria-10.0-merge/mysys_ssl
|
||||
# Build directory: /my/maria-10.0-merge/mysys_ssl
|
||||
#
|
||||
# This file includes the relevent testing commands required for
|
||||
# testing this directory and lists subdirectories to be tested as well.
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
# Install script for directory: /my/maria-10.0-merge/mysys_ssl
|
||||
|
||||
# Set the install prefix
|
||||
IF(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
||||
SET(CMAKE_INSTALL_PREFIX "/usr/local/mysql")
|
||||
ENDIF(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
||||
STRING(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
|
||||
|
||||
# Set the install configuration name.
|
||||
IF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
|
||||
IF(BUILD_TYPE)
|
||||
STRING(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
|
||||
CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
|
||||
ELSE(BUILD_TYPE)
|
||||
SET(CMAKE_INSTALL_CONFIG_NAME "Debug")
|
||||
ENDIF(BUILD_TYPE)
|
||||
MESSAGE(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
|
||||
ENDIF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
|
||||
|
||||
# Set the component getting installed.
|
||||
IF(NOT CMAKE_INSTALL_COMPONENT)
|
||||
IF(COMPONENT)
|
||||
MESSAGE(STATUS "Install component: \"${COMPONENT}\"")
|
||||
SET(CMAKE_INSTALL_COMPONENT "${COMPONENT}")
|
||||
ELSE(COMPONENT)
|
||||
SET(CMAKE_INSTALL_COMPONENT)
|
||||
ENDIF(COMPONENT)
|
||||
ENDIF(NOT CMAKE_INSTALL_COMPONENT)
|
||||
|
||||
# Install shared libraries without execute permission?
|
||||
IF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)
|
||||
SET(CMAKE_INSTALL_SO_NO_EXE "0")
|
||||
ENDIF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)
|
||||
|
||||
|
|
@ -762,7 +762,7 @@ dbcontext::cmd_find_internal(dbcallback_i& cb, const prep_stmt& pst,
|
|||
return cb.dbcb_resp_short(2, "idxnum");
|
||||
}
|
||||
KEY& kinfo = table->key_info[pst.get_idxnum()];
|
||||
if (args.kvalslen > kinfo.key_parts) {
|
||||
if (args.kvalslen > kinfo.user_defined_key_parts) {
|
||||
return cb.dbcb_resp_short(2, "kpnum");
|
||||
}
|
||||
uchar *const key_buf = DENA_ALLOCA_ALLOCATE(uchar, kinfo.key_length);
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@ SET (SQL_SOURCE
|
|||
sp_rcontext.cc spatial.cc sql_acl.cc sql_analyse.cc sql_base.cc
|
||||
sql_cache.cc sql_class.cc sql_client.cc sql_crypt.cc sql_crypt.h
|
||||
sql_cursor.cc sql_db.cc sql_delete.cc sql_derived.cc sql_do.cc
|
||||
sql_error.cc sql_handler.cc sql_help.cc sql_insert.cc sql_lex.cc
|
||||
sql_error.cc sql_handler.cc sql_get_diagnostics.cc
|
||||
sql_help.cc sql_insert.cc sql_lex.cc
|
||||
sql_list.cc sql_load.cc sql_manager.cc
|
||||
sql_parse.cc sql_bootstrap.cc sql_bootstrap.h
|
||||
sql_partition.cc sql_plugin.cc sql_prepare.cc sql_rename.cc
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ static bool report_wrong_value(THD *thd, const char *name, const char *val,
|
|||
return 1;
|
||||
}
|
||||
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_BAD_OPTION_VALUE,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_BAD_OPTION_VALUE,
|
||||
ER(ER_BAD_OPTION_VALUE), val, name);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -109,7 +109,7 @@ static bool report_unknown_option(THD *thd, engine_option_value *val,
|
|||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_UNKNOWN_OPTION, ER(ER_UNKNOWN_OPTION), val->name.str);
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -734,11 +734,6 @@ static st_debug_sync_action *debug_sync_get_action(THD *thd,
|
|||
|
||||
static bool debug_sync_set_action(THD *thd, st_debug_sync_action *action)
|
||||
{
|
||||
if(!thd)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
st_debug_sync_control *ds_control= thd->debug_sync_control;
|
||||
bool is_dsp_now= FALSE;
|
||||
DBUG_ENTER("debug_sync_set_action");
|
||||
|
|
@ -1455,7 +1450,7 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action)
|
|||
sig_wait, sig_glob, error));});
|
||||
if (error == ETIMEDOUT || error == ETIME)
|
||||
{
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_DEBUG_SYNC_TIMEOUT, ER(ER_DEBUG_SYNC_TIMEOUT));
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ bool init_errmessage(void)
|
|||
&errmsgs, ER_ERROR_LAST - ER_ERROR_FIRST + 1) &&
|
||||
!errmsgs)
|
||||
{
|
||||
free(errmsgs);
|
||||
my_free(errmsgs);
|
||||
|
||||
if (org_errmsgs)
|
||||
{
|
||||
|
|
@ -99,7 +99,7 @@ bool init_errmessage(void)
|
|||
}
|
||||
}
|
||||
else
|
||||
free(org_errmsgs); // Free old language
|
||||
my_free(org_errmsgs); // Free old language
|
||||
|
||||
/* Register messages for use with my_error(). */
|
||||
if (my_error_register(get_server_errmsgs, ER_ERROR_FIRST, ER_ERROR_LAST))
|
||||
|
|
|
|||
|
|
@ -608,7 +608,7 @@ Event_timed::load_from_row(THD *thd, TABLE *table)
|
|||
table, &creation_ctx))
|
||||
{
|
||||
push_warning_printf(thd,
|
||||
MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_EVENT_INVALID_CREATION_CTX,
|
||||
ER(ER_EVENT_INVALID_CREATION_CTX),
|
||||
(const char *) dbname.str,
|
||||
|
|
|
|||
|
|
@ -687,7 +687,7 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data,
|
|||
if (create_if_not)
|
||||
{
|
||||
*event_already_exists= true;
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
|
||||
ER_EVENT_ALREADY_EXISTS, ER(ER_EVENT_ALREADY_EXISTS),
|
||||
parse_data->name.str);
|
||||
ret= 0;
|
||||
|
|
@ -912,7 +912,7 @@ Event_db_repository::drop_event(THD *thd, LEX_STRING db, LEX_STRING name,
|
|||
goto end;
|
||||
}
|
||||
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
|
||||
ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST),
|
||||
"Event", name.str);
|
||||
ret= 0;
|
||||
|
|
@ -958,7 +958,7 @@ Event_db_repository::find_named_event(LEX_STRING db, LEX_STRING name,
|
|||
if (db.length > table->field[ET_FIELD_DB]->field_length ||
|
||||
name.length > table->field[ET_FIELD_NAME]->field_length ||
|
||||
table->s->keys == 0 ||
|
||||
table->key_info[0].key_parts != 2 ||
|
||||
table->key_info[0].user_defined_key_parts != 2 ||
|
||||
table->key_info[0].key_part[0].fieldnr != ET_FIELD_DB+1 ||
|
||||
table->key_info[0].key_part[1].fieldnr != ET_FIELD_NAME+1)
|
||||
DBUG_RETURN(TRUE);
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ Event_parse_data::check_if_in_the_past(THD *thd, my_time_t ltime_utc)
|
|||
{
|
||||
switch (thd->lex->sql_command) {
|
||||
case SQLCOM_CREATE_EVENT:
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
|
||||
ER_EVENT_CANNOT_CREATE_IN_THE_PAST,
|
||||
ER(ER_EVENT_CANNOT_CREATE_IN_THE_PAST));
|
||||
break;
|
||||
|
|
@ -143,7 +143,7 @@ Event_parse_data::check_if_in_the_past(THD *thd, my_time_t ltime_utc)
|
|||
{
|
||||
status= Event_parse_data::DISABLED;
|
||||
status_changed= true;
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
|
||||
ER_EVENT_EXEC_TIME_IN_THE_PAST,
|
||||
ER(ER_EVENT_EXEC_TIME_IN_THE_PAST));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,9 +75,9 @@ struct scheduler_param {
|
|||
void
|
||||
Event_worker_thread::print_warnings(THD *thd, Event_job_data *et)
|
||||
{
|
||||
MYSQL_ERROR *err;
|
||||
const Sql_condition *err;
|
||||
DBUG_ENTER("evex_print_warnings");
|
||||
if (thd->warning_info->is_empty())
|
||||
if (thd->get_stmt_da()->is_warning_info_empty())
|
||||
DBUG_VOID_RETURN;
|
||||
|
||||
char msg_buf[10 * STRING_BUFFER_USUAL_SIZE];
|
||||
|
|
@ -93,7 +93,8 @@ Event_worker_thread::print_warnings(THD *thd, Event_job_data *et)
|
|||
prefix.append(et->name.str, et->name.length, system_charset_info);
|
||||
prefix.append("] ", 2);
|
||||
|
||||
List_iterator_fast<MYSQL_ERROR> it(thd->warning_info->warn_list());
|
||||
Diagnostics_area::Sql_condition_iterator it=
|
||||
thd->get_stmt_da()->sql_conditions();
|
||||
while ((err= it++))
|
||||
{
|
||||
String err_msg(msg_buf, sizeof(msg_buf), system_charset_info);
|
||||
|
|
|
|||
206
sql/field.cc
206
sql/field.cc
|
|
@ -1076,7 +1076,7 @@ static void push_numerical_conversion_warning(THD* thd, const char* str,
|
|||
|
||||
String tmp(buf, sizeof(buf), cs);
|
||||
tmp.copy(str, length, cs);
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
error, ER(error), typestr, tmp.c_ptr(),
|
||||
field_name, row_num);
|
||||
}
|
||||
|
|
@ -1190,17 +1190,18 @@ int Field_num::check_int(CHARSET_INFO *cs, const char *str, int length,
|
|||
if (str == int_end || error == MY_ERRNO_EDOM)
|
||||
{
|
||||
ErrConvString err(str, length, cs);
|
||||
push_warning_printf(get_thd(), MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(get_thd(), Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
|
||||
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
|
||||
"integer", err.ptr(), field_name,
|
||||
(ulong) get_thd()->warning_info->current_row_for_warning());
|
||||
(ulong) table->in_use->get_stmt_da()->
|
||||
current_row_for_warning());
|
||||
return 1;
|
||||
}
|
||||
/* Test if we have garbage at the end of the given string. */
|
||||
if (test_if_important_data(cs, int_end, str + length))
|
||||
{
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -1269,7 +1270,7 @@ bool Field_num::get_int(CHARSET_INFO *cs, const char *from, uint len,
|
|||
return 0;
|
||||
|
||||
out_of_range:
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -1289,12 +1290,12 @@ int Field::warn_if_overflow(int op_result)
|
|||
{
|
||||
if (op_result == E_DEC_OVERFLOW)
|
||||
{
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
return 1;
|
||||
}
|
||||
if (op_result == E_DEC_TRUNCATED)
|
||||
{
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_NOTE, WARN_DATA_TRUNCATED, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_NOTE, WARN_DATA_TRUNCATED, 1);
|
||||
/* We return 0 here as this is not a critical issue */
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -1618,7 +1619,7 @@ longlong Field::convert_decimal2longlong(const my_decimal *val,
|
|||
{
|
||||
if (val->sign())
|
||||
{
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
i= 0;
|
||||
*err= 1;
|
||||
}
|
||||
|
|
@ -1926,7 +1927,7 @@ void Field_decimal::overflow(bool negative)
|
|||
uint len=field_length;
|
||||
uchar *to=ptr, filler= '9';
|
||||
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
if (negative)
|
||||
{
|
||||
if (!unsigned_flag)
|
||||
|
|
@ -2034,7 +2035,7 @@ int Field_decimal::store(const char *from_arg, uint len, CHARSET_INFO *cs)
|
|||
from++;
|
||||
if (from == end)
|
||||
{
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
is_cuted_fields_incr=1;
|
||||
}
|
||||
else if (*from == '+' || *from == '-') // Found some sign ?
|
||||
|
|
@ -2110,7 +2111,7 @@ int Field_decimal::store(const char *from_arg, uint len, CHARSET_INFO *cs)
|
|||
for (;from != end && my_isspace(&my_charset_bin, *from); from++) ;
|
||||
if (from != end) // If still something left, warn
|
||||
{
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
is_cuted_fields_incr=1;
|
||||
}
|
||||
}
|
||||
|
|
@ -2288,7 +2289,7 @@ int Field_decimal::store(const char *from_arg, uint len, CHARSET_INFO *cs)
|
|||
if (tmp_char != '0') // Losing a non zero digit ?
|
||||
{
|
||||
if (!is_cuted_fields_incr)
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN,
|
||||
WARN_DATA_TRUNCATED, 1);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2311,7 +2312,7 @@ int Field_decimal::store(const char *from_arg, uint len, CHARSET_INFO *cs)
|
|||
This is a note, not a warning, as we don't want to abort
|
||||
when we cut decimals in strict mode
|
||||
*/
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_NOTE, WARN_DATA_TRUNCATED, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_NOTE, WARN_DATA_TRUNCATED, 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2661,7 +2662,7 @@ bool Field_new_decimal::store_value(const my_decimal *decimal_value)
|
|||
if (unsigned_flag && decimal_value->sign())
|
||||
{
|
||||
DBUG_PRINT("info", ("unsigned overflow"));
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
decimal_value= &decimal_zero;
|
||||
}
|
||||
|
|
@ -2705,32 +2706,32 @@ int Field_new_decimal::store(const char *from, uint length,
|
|||
thd->abort_on_warning)
|
||||
{
|
||||
ErrConvString errmsg(from, length, &my_charset_bin);
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
|
||||
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
|
||||
"decimal", errmsg.ptr(), field_name,
|
||||
(ulong) thd->warning_info->current_row_for_warning());
|
||||
|
||||
static_cast<ulong>(thd->get_stmt_da()->
|
||||
current_row_for_warning()));
|
||||
DBUG_RETURN(err);
|
||||
}
|
||||
|
||||
switch (err) {
|
||||
case E_DEC_TRUNCATED:
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_NOTE, WARN_DATA_TRUNCATED, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
break;
|
||||
case E_DEC_OVERFLOW:
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_value_on_overflow(&decimal_value, decimal_value.sign());
|
||||
break;
|
||||
case E_DEC_BAD_NUM:
|
||||
{
|
||||
ErrConvString errmsg(from, length, &my_charset_bin);
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
|
||||
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
|
||||
"decimal", errmsg.ptr(), field_name,
|
||||
(ulong) thd->warning_info->
|
||||
current_row_for_warning());
|
||||
static_cast<ulong>(thd->get_stmt_da()->
|
||||
current_row_for_warning()));
|
||||
my_decimal_set_zero(&decimal_value);
|
||||
break;
|
||||
}
|
||||
|
|
@ -3037,13 +3038,13 @@ int Field_tiny::store(double nr)
|
|||
if (nr < 0.0)
|
||||
{
|
||||
*ptr=0;
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
}
|
||||
else if (nr > 255.0)
|
||||
{
|
||||
*ptr= (uchar) 255;
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
}
|
||||
else
|
||||
|
|
@ -3054,13 +3055,13 @@ int Field_tiny::store(double nr)
|
|||
if (nr < -128.0)
|
||||
{
|
||||
*ptr= (uchar) -128;
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
}
|
||||
else if (nr > 127.0)
|
||||
{
|
||||
*ptr=127;
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
}
|
||||
else
|
||||
|
|
@ -3080,13 +3081,13 @@ int Field_tiny::store(longlong nr, bool unsigned_val)
|
|||
if (nr < 0 && !unsigned_val)
|
||||
{
|
||||
*ptr= 0;
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
}
|
||||
else if ((ulonglong) nr > (ulonglong) 255)
|
||||
{
|
||||
*ptr= (char) 255;
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
}
|
||||
else
|
||||
|
|
@ -3099,13 +3100,13 @@ int Field_tiny::store(longlong nr, bool unsigned_val)
|
|||
if (nr < -128)
|
||||
{
|
||||
*ptr= (char) -128;
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
}
|
||||
else if (nr > 127)
|
||||
{
|
||||
*ptr=127;
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
}
|
||||
else
|
||||
|
|
@ -3216,13 +3217,13 @@ int Field_short::store(double nr)
|
|||
if (nr < 0)
|
||||
{
|
||||
res=0;
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
}
|
||||
else if (nr > (double) UINT_MAX16)
|
||||
{
|
||||
res=(int16) UINT_MAX16;
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
}
|
||||
else
|
||||
|
|
@ -3233,13 +3234,13 @@ int Field_short::store(double nr)
|
|||
if (nr < (double) INT_MIN16)
|
||||
{
|
||||
res=INT_MIN16;
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
}
|
||||
else if (nr > (double) INT_MAX16)
|
||||
{
|
||||
res=INT_MAX16;
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
}
|
||||
else
|
||||
|
|
@ -3261,13 +3262,13 @@ int Field_short::store(longlong nr, bool unsigned_val)
|
|||
if (nr < 0L && !unsigned_val)
|
||||
{
|
||||
res=0;
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
}
|
||||
else if ((ulonglong) nr > (ulonglong) UINT_MAX16)
|
||||
{
|
||||
res=(int16) UINT_MAX16;
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
}
|
||||
else
|
||||
|
|
@ -3281,13 +3282,13 @@ int Field_short::store(longlong nr, bool unsigned_val)
|
|||
if (nr < INT_MIN16)
|
||||
{
|
||||
res=INT_MIN16;
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
}
|
||||
else if (nr > (longlong) INT_MAX16)
|
||||
{
|
||||
res=INT_MAX16;
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
}
|
||||
else
|
||||
|
|
@ -3404,14 +3405,14 @@ int Field_medium::store(double nr)
|
|||
if (nr < 0)
|
||||
{
|
||||
int3store(ptr,0);
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
}
|
||||
else if (nr >= (double) (long) (1L << 24))
|
||||
{
|
||||
uint32 tmp=(uint32) (1L << 24)-1L;
|
||||
int3store(ptr,tmp);
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
}
|
||||
else
|
||||
|
|
@ -3423,14 +3424,14 @@ int Field_medium::store(double nr)
|
|||
{
|
||||
long tmp=(long) INT_MIN24;
|
||||
int3store(ptr,tmp);
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
}
|
||||
else if (nr > (double) INT_MAX24)
|
||||
{
|
||||
long tmp=(long) INT_MAX24;
|
||||
int3store(ptr,tmp);
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
}
|
||||
else
|
||||
|
|
@ -3450,14 +3451,14 @@ int Field_medium::store(longlong nr, bool unsigned_val)
|
|||
if (nr < 0 && !unsigned_val)
|
||||
{
|
||||
int3store(ptr,0);
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
}
|
||||
else if ((ulonglong) nr >= (ulonglong) (long) (1L << 24))
|
||||
{
|
||||
long tmp= (long) (1L << 24)-1L;
|
||||
int3store(ptr,tmp);
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
}
|
||||
else
|
||||
|
|
@ -3472,14 +3473,14 @@ int Field_medium::store(longlong nr, bool unsigned_val)
|
|||
{
|
||||
long tmp= (long) INT_MIN24;
|
||||
int3store(ptr,tmp);
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
}
|
||||
else if (nr > (longlong) INT_MAX24)
|
||||
{
|
||||
long tmp=(long) INT_MAX24;
|
||||
int3store(ptr,tmp);
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
}
|
||||
else
|
||||
|
|
@ -3601,7 +3602,7 @@ int Field_long::store(double nr)
|
|||
else if (nr > (double) UINT_MAX32)
|
||||
{
|
||||
res= UINT_MAX32;
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
}
|
||||
else
|
||||
|
|
@ -3623,7 +3624,7 @@ int Field_long::store(double nr)
|
|||
res=(int32) (longlong) nr;
|
||||
}
|
||||
if (error)
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
|
||||
int4store(ptr,res);
|
||||
return error;
|
||||
|
|
@ -3669,7 +3670,7 @@ int Field_long::store(longlong nr, bool unsigned_val)
|
|||
res=(int32) nr;
|
||||
}
|
||||
if (error)
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
|
||||
int4store(ptr,res);
|
||||
return error;
|
||||
|
|
@ -3768,7 +3769,7 @@ int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs)
|
|||
tmp= cs->cset->strntoull10rnd(cs,from,len,unsigned_flag,&end,&error);
|
||||
if (error == MY_ERRNO_ERANGE)
|
||||
{
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
}
|
||||
else if (get_thd()->count_cuted_fields &&
|
||||
|
|
@ -3790,7 +3791,7 @@ int Field_longlong::store(double nr)
|
|||
res= double_to_longlong(nr, unsigned_flag, &error);
|
||||
|
||||
if (error)
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
|
||||
int8store(ptr,res);
|
||||
return error;
|
||||
|
|
@ -3811,7 +3812,7 @@ int Field_longlong::store(longlong nr, bool unsigned_val)
|
|||
if (unsigned_flag != unsigned_val)
|
||||
{
|
||||
nr= unsigned_flag ? (ulonglong) 0 : (ulonglong) LONGLONG_MAX;
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -3925,7 +3926,7 @@ int Field_float::store(const char *from,uint len,CHARSET_INFO *cs)
|
|||
if (error || (!len || ((uint) (end-from) != len &&
|
||||
get_thd()->count_cuted_fields)))
|
||||
{
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN,
|
||||
(error ? ER_WARN_DATA_OUT_OF_RANGE : WARN_DATA_TRUNCATED), 1);
|
||||
error= error ? 1 : 2;
|
||||
}
|
||||
|
|
@ -3942,7 +3943,7 @@ int Field_float::store(double nr)
|
|||
unsigned_flag, FLT_MAX);
|
||||
if (error)
|
||||
{
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
if (error < 0) // Wrong double value
|
||||
{
|
||||
error= 1;
|
||||
|
|
@ -4113,7 +4114,7 @@ int Field_double::store(const char *from,uint len,CHARSET_INFO *cs)
|
|||
if (error || (!len || ((uint) (end-from) != len &&
|
||||
get_thd()->count_cuted_fields)))
|
||||
{
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN,
|
||||
(error ? ER_WARN_DATA_OUT_OF_RANGE : WARN_DATA_TRUNCATED), 1);
|
||||
error= error ? 1 : 2;
|
||||
}
|
||||
|
|
@ -4130,7 +4131,7 @@ int Field_double::store(double nr)
|
|||
unsigned_flag, DBL_MAX);
|
||||
if (error)
|
||||
{
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
if (error < 0) // Wrong double value
|
||||
{
|
||||
error= 1;
|
||||
|
|
@ -4295,7 +4296,7 @@ longlong Field_double::val_int(void)
|
|||
if (error)
|
||||
{
|
||||
ErrConvDouble err(j);
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_TRUNCATED_WRONG_VALUE,
|
||||
ER(ER_TRUNCATED_WRONG_VALUE), "INTEGER",
|
||||
err.ptr());
|
||||
|
|
@ -4492,7 +4493,7 @@ int Field_timestamp::store_TIME_with_warning(THD *thd, MYSQL_TIME *l_time,
|
|||
if (was_cut || !have_smth_to_conv)
|
||||
{
|
||||
error= 1;
|
||||
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED,
|
||||
set_datetime_warning(Sql_condition::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED,
|
||||
str, MYSQL_TIMESTAMP_DATETIME, 1);
|
||||
}
|
||||
/* Only convert a correct date (not a zero date) */
|
||||
|
|
@ -4504,7 +4505,7 @@ int Field_timestamp::store_TIME_with_warning(THD *thd, MYSQL_TIME *l_time,
|
|||
conversion_error= ER_WARN_DATA_OUT_OF_RANGE;
|
||||
if (conversion_error)
|
||||
{
|
||||
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, conversion_error,
|
||||
set_datetime_warning(Sql_condition::WARN_LEVEL_WARN, conversion_error,
|
||||
str, MYSQL_TIMESTAMP_DATETIME, !error);
|
||||
error= 1;
|
||||
}
|
||||
|
|
@ -4968,7 +4969,7 @@ int Field_temporal::store_TIME_with_warning(MYSQL_TIME *ltime,
|
|||
const ErrConv *str,
|
||||
int was_cut, int have_smth_to_conv)
|
||||
{
|
||||
MYSQL_ERROR::enum_warning_level trunc_level= MYSQL_ERROR::WARN_LEVEL_WARN;
|
||||
Sql_condition::enum_warning_level trunc_level= Sql_condition::WARN_LEVEL_WARN;
|
||||
int ret= 2;
|
||||
|
||||
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
|
||||
|
|
@ -4988,7 +4989,7 @@ int Field_temporal::store_TIME_with_warning(MYSQL_TIME *ltime,
|
|||
mysql_type_to_time_type(type()) == MYSQL_TIMESTAMP_DATE &&
|
||||
(ltime->hour || ltime->minute || ltime->second || ltime->second_part))
|
||||
{
|
||||
trunc_level= MYSQL_ERROR::WARN_LEVEL_NOTE;
|
||||
trunc_level= Sql_condition::WARN_LEVEL_NOTE;
|
||||
was_cut|= MYSQL_TIME_WARN_TRUNCATED;
|
||||
ret= 3;
|
||||
}
|
||||
|
|
@ -4997,7 +4998,7 @@ int Field_temporal::store_TIME_with_warning(MYSQL_TIME *ltime,
|
|||
(ltime->year || ltime->month))
|
||||
{
|
||||
ltime->year= ltime->month= ltime->day= 0;
|
||||
trunc_level= MYSQL_ERROR::WARN_LEVEL_NOTE;
|
||||
trunc_level= Sql_condition::WARN_LEVEL_NOTE;
|
||||
was_cut|= MYSQL_TIME_WARN_TRUNCATED;
|
||||
ret= 3;
|
||||
}
|
||||
|
|
@ -5016,7 +5017,7 @@ int Field_temporal::store_TIME_with_warning(MYSQL_TIME *ltime,
|
|||
set_datetime_warning(trunc_level, WARN_DATA_TRUNCATED,
|
||||
str, mysql_type_to_time_type(type()), 1);
|
||||
if (was_cut & MYSQL_TIME_WARN_OUT_OF_RANGE)
|
||||
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE,
|
||||
set_datetime_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE,
|
||||
str, mysql_type_to_time_type(type()), 1);
|
||||
|
||||
store_TIME(ltime);
|
||||
|
|
@ -5237,10 +5238,10 @@ bool Field_time::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
|
|||
THD *thd= get_thd();
|
||||
if (!(fuzzydate & (TIME_FUZZY_DATE|TIME_TIME_ONLY)))
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_DATA_OUT_OF_RANGE,
|
||||
ER(ER_WARN_DATA_OUT_OF_RANGE), field_name,
|
||||
thd->warning_info->current_row_for_warning());
|
||||
thd->get_stmt_da()->current_row_for_warning());
|
||||
return 1;
|
||||
}
|
||||
long tmp=(long) sint3korr(ptr);
|
||||
|
|
@ -5421,7 +5422,7 @@ int Field_year::store(const char *from, uint len,CHARSET_INFO *cs)
|
|||
error == MY_ERRNO_ERANGE)
|
||||
{
|
||||
*ptr=0;
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
return 1;
|
||||
}
|
||||
if (get_thd()->count_cuted_fields &&
|
||||
|
|
@ -5464,7 +5465,7 @@ int Field_year::store(longlong nr, bool unsigned_val)
|
|||
if (nr < 0 || (nr >= 100 && nr <= 1900) || nr > 2155)
|
||||
{
|
||||
*ptr= 0;
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
return 1;
|
||||
}
|
||||
if (nr != 0 || field_length != 4) // 0000 -> 0; 00 -> 2000
|
||||
|
|
@ -5485,7 +5486,7 @@ int Field_year::store_time_dec(MYSQL_TIME *ltime, uint dec)
|
|||
if (Field_year::store(ltime->year, 0))
|
||||
return 1;
|
||||
|
||||
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED,
|
||||
set_datetime_warning(Sql_condition::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED,
|
||||
&str, ltime->time_type, 1);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -6046,11 +6047,11 @@ check_string_copy_error(Field_str *field,
|
|||
convert_to_printable(tmp, sizeof(tmp), pos, (end - pos), cs, 6);
|
||||
|
||||
push_warning_printf(thd,
|
||||
MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
|
||||
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
|
||||
"string", tmp, field->field_name,
|
||||
thd->warning_info->current_row_for_warning());
|
||||
thd->get_stmt_da()->current_row_for_warning());
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -6085,14 +6086,14 @@ Field_longstr::report_if_important_data(const char *pstr, const char *end,
|
|||
if (test_if_important_data(field_charset, pstr, end))
|
||||
{
|
||||
if (thd->abort_on_warning)
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_DATA_TOO_LONG, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_DATA_TOO_LONG, 1);
|
||||
else
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
return 2;
|
||||
}
|
||||
else if (count_spaces)
|
||||
{ /* If we lost only spaces then produce a NOTE, not a WARNING */
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_NOTE, WARN_DATA_TRUNCATED, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_NOTE, WARN_DATA_TRUNCATED, 1);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
|
@ -6158,9 +6159,9 @@ int Field_str::store(double nr)
|
|||
if (error)
|
||||
{
|
||||
if (get_thd()->abort_on_warning)
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_DATA_TOO_LONG, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_DATA_TOO_LONG, 1);
|
||||
else
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
}
|
||||
return store(buff, length, &my_charset_numeric);
|
||||
}
|
||||
|
|
@ -6223,7 +6224,7 @@ double Field_string::val_real(void)
|
|||
(char*) ptr + field_length))))
|
||||
{
|
||||
ErrConvString err((char*) ptr, field_length, cs);
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_TRUNCATED_WRONG_VALUE,
|
||||
ER(ER_TRUNCATED_WRONG_VALUE), "DOUBLE",
|
||||
err.ptr());
|
||||
|
|
@ -6247,7 +6248,7 @@ longlong Field_string::val_int(void)
|
|||
(char*) ptr + field_length))))
|
||||
{
|
||||
ErrConvString err((char*) ptr, field_length, cs);
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_TRUNCATED_WRONG_VALUE,
|
||||
ER(ER_TRUNCATED_WRONG_VALUE),
|
||||
"INTEGER", err.ptr());
|
||||
|
|
@ -6283,7 +6284,7 @@ my_decimal *Field_string::val_decimal(my_decimal *decimal_value)
|
|||
if (!get_thd()->no_errors && err)
|
||||
{
|
||||
ErrConvString errmsg((char*) ptr, field_length, charset());
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_TRUNCATED_WRONG_VALUE,
|
||||
ER(ER_TRUNCATED_WRONG_VALUE),
|
||||
"DECIMAL", errmsg.ptr());
|
||||
|
|
@ -7695,13 +7696,13 @@ int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs)
|
|||
if (err || end != from+length || tmp > typelib->count)
|
||||
{
|
||||
tmp=0;
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
}
|
||||
if (!get_thd()->count_cuted_fields)
|
||||
err= 0;
|
||||
}
|
||||
else
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
}
|
||||
store_type((ulonglong) tmp);
|
||||
return err;
|
||||
|
|
@ -7720,7 +7721,7 @@ int Field_enum::store(longlong nr, bool unsigned_val)
|
|||
int error= 0;
|
||||
if ((ulonglong) nr > typelib->count || nr == 0)
|
||||
{
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
if (nr != 0 || get_thd()->count_cuted_fields)
|
||||
{
|
||||
nr= 0;
|
||||
|
|
@ -7874,11 +7875,11 @@ int Field_set::store(const char *from,uint length,CHARSET_INFO *cs)
|
|||
tmp > (ulonglong) (((longlong) 1 << typelib->count) - (longlong) 1))
|
||||
{
|
||||
tmp=0;
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
}
|
||||
}
|
||||
else if (got_warning)
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
store_type(tmp);
|
||||
return err;
|
||||
}
|
||||
|
|
@ -7898,7 +7899,7 @@ int Field_set::store(longlong nr, bool unsigned_val)
|
|||
if ((ulonglong) nr > max_nr)
|
||||
{
|
||||
nr&= max_nr;
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
error=1;
|
||||
}
|
||||
store_type((ulonglong) nr);
|
||||
|
|
@ -8252,9 +8253,9 @@ int Field_bit::store(const char *from, uint length, CHARSET_INFO *cs)
|
|||
set_rec_bits((1 << bit_len) - 1, bit_ptr, bit_ofs, bit_len);
|
||||
memset(ptr, 0xff, bytes_in_rec);
|
||||
if (get_thd()->really_abort_on_warning())
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_DATA_TOO_LONG, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_DATA_TOO_LONG, 1);
|
||||
else
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
return 1;
|
||||
}
|
||||
/* delta is >= -1 here */
|
||||
|
|
@ -8689,9 +8690,9 @@ int Field_bit_as_char::store(const char *from, uint length, CHARSET_INFO *cs)
|
|||
if (bits)
|
||||
*ptr&= ((1 << bits) - 1); /* set first uchar */
|
||||
if (get_thd()->really_abort_on_warning())
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_DATA_TOO_LONG, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_DATA_TOO_LONG, 1);
|
||||
else
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
return 1;
|
||||
}
|
||||
bzero(ptr, delta);
|
||||
|
|
@ -9092,7 +9093,7 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
|
|||
/*
|
||||
Otherwise a default of '' is just a warning.
|
||||
*/
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_BLOB_CANT_HAVE_DEFAULT,
|
||||
ER(ER_BLOB_CANT_HAVE_DEFAULT),
|
||||
fld_name);
|
||||
|
|
@ -9610,7 +9611,7 @@ Create_field::Create_field(Field *old_field,Field *orig_field)
|
|||
{
|
||||
char buff[sizeof("YEAR()") + MY_INT64_NUM_DECIMAL_DIGITS + 1];
|
||||
my_snprintf(buff, sizeof(buff), "YEAR(%lu)", length);
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_NOTE,
|
||||
ER_WARN_DEPRECATED_SYNTAX,
|
||||
ER(ER_WARN_DEPRECATED_SYNTAX),
|
||||
buff, "YEAR(4)");
|
||||
|
|
@ -9738,11 +9739,11 @@ uint32 Field_blob::max_display_length()
|
|||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
Produce warning or note about data saved into field.
|
||||
* Produce warning or note about data saved into field.
|
||||
|
||||
@param level - level of message (Note/Warning/Error)
|
||||
@param code - error code of message to be produced
|
||||
@param cuted_increment - whenever we should increase cut fields count or not
|
||||
@param cut_increment - whenever we should increase cut fields count
|
||||
|
||||
@note
|
||||
This function won't produce warning and increase cut fields counter
|
||||
|
|
@ -9750,11 +9751,16 @@ uint32 Field_blob::max_display_length()
|
|||
|
||||
if count_cuted_fields == CHECK_FIELD_IGNORE then we ignore notes.
|
||||
This allows us to avoid notes in optimisation, like convert_constant_item().
|
||||
|
||||
@retval
|
||||
1 if count_cuted_fields == CHECK_FIELD_IGNORE and error level is not NOTE
|
||||
@retval
|
||||
0 otherwise
|
||||
*/
|
||||
|
||||
void
|
||||
Field::set_warning(MYSQL_ERROR::enum_warning_level level, uint code,
|
||||
int cuted_increment)
|
||||
bool
|
||||
Field::set_warning(Sql_condition::enum_warning_level level, uint code,
|
||||
int cut_increment) const
|
||||
{
|
||||
/*
|
||||
If this field was created only for type conversion purposes it
|
||||
|
|
@ -9763,10 +9769,12 @@ Field::set_warning(MYSQL_ERROR::enum_warning_level level, uint code,
|
|||
THD *thd= table ? table->in_use : current_thd;
|
||||
if (thd->count_cuted_fields)
|
||||
{
|
||||
thd->cuted_fields+= cuted_increment;
|
||||
thd->cuted_fields+= cut_increment;
|
||||
push_warning_printf(thd, level, code, ER(code), field_name,
|
||||
thd->warning_info->current_row_for_warning());
|
||||
thd->get_stmt_da()->current_row_for_warning());
|
||||
return 0;
|
||||
}
|
||||
return level >= Sql_condition::WARN_LEVEL_WARN;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -9788,12 +9796,12 @@ Field::set_warning(MYSQL_ERROR::enum_warning_level level, uint code,
|
|||
|
||||
*/
|
||||
|
||||
void Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level,
|
||||
void Field::set_datetime_warning(Sql_condition::enum_warning_level level,
|
||||
uint code, const ErrConv *str,
|
||||
timestamp_type ts_type, int cuted_increment)
|
||||
{
|
||||
THD *thd= get_thd();
|
||||
if (thd->really_abort_on_warning() && level >= MYSQL_ERROR::WARN_LEVEL_WARN)
|
||||
if (thd->really_abort_on_warning() && level >= Sql_condition::WARN_LEVEL_WARN)
|
||||
make_truncated_value_warning(thd, level, str, ts_type, field_name);
|
||||
else
|
||||
set_warning(level, code, cuted_increment);
|
||||
|
|
|
|||
48
sql/field.h
48
sql/field.h
|
|
@ -668,9 +668,9 @@ public:
|
|||
virtual uint repertoire(void) const { return MY_REPERTOIRE_UNICODE30; }
|
||||
virtual void set_derivation(enum Derivation derivation_arg) { }
|
||||
virtual int set_time() { return 1; }
|
||||
void set_warning(MYSQL_ERROR::enum_warning_level, unsigned int code,
|
||||
int cuted_increment);
|
||||
void set_datetime_warning(MYSQL_ERROR::enum_warning_level, uint code,
|
||||
bool set_warning(Sql_condition::enum_warning_level, unsigned int code,
|
||||
int cuted_increment) const;
|
||||
void set_datetime_warning(Sql_condition::enum_warning_level, uint code,
|
||||
const ErrConv *str, timestamp_type ts_type,
|
||||
int cuted_increment);
|
||||
inline bool check_overflow(int op_result)
|
||||
|
|
@ -715,6 +715,30 @@ public:
|
|||
return GEOM_GEOMETRY;
|
||||
}
|
||||
|
||||
ha_storage_media field_storage_type() const
|
||||
{
|
||||
return (ha_storage_media)
|
||||
((flags >> FIELD_FLAGS_STORAGE_MEDIA) & 3);
|
||||
}
|
||||
|
||||
void set_storage_type(ha_storage_media storage_type_arg)
|
||||
{
|
||||
DBUG_ASSERT(field_storage_type() == HA_SM_DEFAULT);
|
||||
flags |= (storage_type_arg << FIELD_FLAGS_STORAGE_MEDIA);
|
||||
}
|
||||
|
||||
column_format_type column_format() const
|
||||
{
|
||||
return (column_format_type)
|
||||
((flags >> FIELD_FLAGS_COLUMN_FORMAT) & 3);
|
||||
}
|
||||
|
||||
void set_column_format(column_format_type column_format_arg)
|
||||
{
|
||||
DBUG_ASSERT(column_format() == COLUMN_FORMAT_TYPE_DEFAULT);
|
||||
flags |= (column_format_arg << FIELD_FLAGS_COLUMN_FORMAT);
|
||||
}
|
||||
|
||||
key_map get_possible_keys();
|
||||
|
||||
/* Hash value */
|
||||
|
|
@ -2405,6 +2429,7 @@ public:
|
|||
|
||||
uint8 row,col,sc_length,interval_id; // For rea_create_table
|
||||
uint offset,pack_flag;
|
||||
bool create_if_not_exists; // Used in ALTER TABLE IF NOT EXISTS
|
||||
|
||||
/*
|
||||
This is additinal data provided for any computed(virtual) field.
|
||||
|
|
@ -2419,7 +2444,8 @@ public:
|
|||
*/
|
||||
bool stored_in_db;
|
||||
|
||||
Create_field() :after(0), option_list(NULL), option_struct(NULL)
|
||||
Create_field() :after(0), option_list(NULL), option_struct(NULL),
|
||||
create_if_not_exists(FALSE)
|
||||
{}
|
||||
Create_field(Field *field, Field *orig_field);
|
||||
/* Used to make a clone of this object for ALTER/CREATE TABLE */
|
||||
|
|
@ -2443,10 +2469,24 @@ public:
|
|||
{
|
||||
return (flags & (BINCMP_FLAG | BINARY_FLAG)) != 0;
|
||||
}
|
||||
|
||||
ha_storage_media field_storage_type() const
|
||||
{
|
||||
return (ha_storage_media)
|
||||
((flags >> FIELD_FLAGS_STORAGE_MEDIA) & 3);
|
||||
}
|
||||
|
||||
column_format_type column_format() const
|
||||
{
|
||||
return (column_format_type)
|
||||
((flags >> FIELD_FLAGS_COLUMN_FORMAT) & 3);
|
||||
}
|
||||
|
||||
uint virtual_col_expr_maxlen()
|
||||
{
|
||||
return 255 - FRM_VCOL_HEADER_SIZE(interval != NULL);
|
||||
}
|
||||
|
||||
private:
|
||||
const String empty_set_string;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ set_field_to_null(Field *field)
|
|||
field->reset();
|
||||
switch (field->table->in_use->count_cuted_fields) {
|
||||
case CHECK_FIELD_WARN:
|
||||
field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
field->set_warning(Sql_condition::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
/* fall through */
|
||||
case CHECK_FIELD_IGNORE:
|
||||
return 0;
|
||||
|
|
@ -202,7 +202,7 @@ set_field_to_null_with_conversions(Field *field, bool no_conversions)
|
|||
}
|
||||
switch (field->table->in_use->count_cuted_fields) {
|
||||
case CHECK_FIELD_WARN:
|
||||
field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_BAD_NULL_ERROR, 1);
|
||||
field->set_warning(Sql_condition::WARN_LEVEL_WARN, ER_BAD_NULL_ERROR, 1);
|
||||
/* fall through */
|
||||
case CHECK_FIELD_IGNORE:
|
||||
return 0;
|
||||
|
|
@ -272,7 +272,7 @@ static void do_copy_nullable_row_to_notnull(Copy_field *copy)
|
|||
if (*copy->null_row ||
|
||||
(copy->from_null_ptr && (*copy->from_null_ptr & copy->from_bit)))
|
||||
{
|
||||
copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
|
||||
WARN_DATA_TRUNCATED, 1);
|
||||
copy->to_field->reset();
|
||||
}
|
||||
|
|
@ -288,7 +288,7 @@ static void do_copy_not_null(Copy_field *copy)
|
|||
{
|
||||
if (*copy->from_null_ptr & copy->from_bit)
|
||||
{
|
||||
copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
|
||||
WARN_DATA_TRUNCATED, 1);
|
||||
copy->to_field->reset();
|
||||
}
|
||||
|
|
@ -440,7 +440,7 @@ static void do_cut_string(Copy_field *copy)
|
|||
(char*) copy->from_ptr + copy->from_length,
|
||||
MY_SEQ_SPACES) < copy->from_length - copy->to_length)
|
||||
{
|
||||
copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
|
||||
WARN_DATA_TRUNCATED, 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -471,7 +471,7 @@ static void do_cut_string_complex(Copy_field *copy)
|
|||
(char*) from_end,
|
||||
MY_SEQ_SPACES) < (copy->from_length - copy_length))
|
||||
{
|
||||
copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
|
||||
WARN_DATA_TRUNCATED, 1);
|
||||
}
|
||||
|
||||
|
|
@ -510,7 +510,7 @@ static void do_varstring1(Copy_field *copy)
|
|||
length=copy->to_length - 1;
|
||||
if (copy->from_field->table->in_use->count_cuted_fields &&
|
||||
copy->to_field)
|
||||
copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
|
||||
WARN_DATA_TRUNCATED, 1);
|
||||
}
|
||||
*(uchar*) copy->to_ptr= (uchar) length;
|
||||
|
|
@ -531,7 +531,7 @@ static void do_varstring1_mb(Copy_field *copy)
|
|||
if (length < from_length)
|
||||
{
|
||||
if (current_thd->count_cuted_fields)
|
||||
copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
|
||||
WARN_DATA_TRUNCATED, 1);
|
||||
}
|
||||
*copy->to_ptr= (uchar) length;
|
||||
|
|
@ -547,7 +547,7 @@ static void do_varstring2(Copy_field *copy)
|
|||
length=copy->to_length-HA_KEY_BLOB_LENGTH;
|
||||
if (copy->from_field->table->in_use->count_cuted_fields &&
|
||||
copy->to_field)
|
||||
copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
|
||||
WARN_DATA_TRUNCATED, 1);
|
||||
}
|
||||
int2store(copy->to_ptr,length);
|
||||
|
|
@ -569,7 +569,7 @@ static void do_varstring2_mb(Copy_field *copy)
|
|||
if (length < from_length)
|
||||
{
|
||||
if (current_thd->count_cuted_fields)
|
||||
copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
|
||||
WARN_DATA_TRUNCATED, 1);
|
||||
}
|
||||
int2store(copy->to_ptr, length);
|
||||
|
|
|
|||
|
|
@ -391,7 +391,8 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
|
|||
MYF(0),
|
||||
ER_THD(thd, ER_FILSORT_ABORT),
|
||||
kill_errno ? ER(kill_errno) :
|
||||
thd->killed == ABORT_QUERY ? "" : thd->stmt_da->message());
|
||||
thd->killed == ABORT_QUERY ? "" :
|
||||
thd->get_stmt_da()->message());
|
||||
|
||||
if (global_system_variables.log_warnings > 1)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -379,11 +379,11 @@ static int ndb_to_mysql_error(const NdbError *ndberr)
|
|||
- Used by replication to see if the error was temporary
|
||||
*/
|
||||
if (ndberr->status == NdbError::TemporaryError)
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_GET_TEMPORARY_ERRMSG, ER(ER_GET_TEMPORARY_ERRMSG),
|
||||
ndberr->code, ndberr->message, "NDB");
|
||||
else
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_GET_ERRMSG, ER(ER_GET_ERRMSG),
|
||||
ndberr->code, ndberr->message, "NDB");
|
||||
return error;
|
||||
|
|
@ -650,7 +650,7 @@ static void set_ndb_err(THD *thd, const NdbError &err)
|
|||
{
|
||||
char buf[FN_REFLEN];
|
||||
ndb_error_string(thd_ndb->m_error_code, buf, sizeof(buf));
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_GET_ERRMSG, ER(ER_GET_ERRMSG),
|
||||
thd_ndb->m_error_code, buf, "NDB");
|
||||
}
|
||||
|
|
@ -3206,7 +3206,7 @@ int ha_ndbcluster::update_row(const uchar *old_data, uchar *new_data)
|
|||
undo_res= write_row((uchar *)old_data);
|
||||
if (undo_res)
|
||||
push_warning(current_thd,
|
||||
MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
Sql_condition::WARN_LEVEL_WARN,
|
||||
undo_res,
|
||||
"NDB failed undoing delete at primary key update");
|
||||
m_primary_key_update= FALSE;
|
||||
|
|
@ -5416,7 +5416,7 @@ int ha_ndbcluster::create(const char *name,
|
|||
{
|
||||
if (create_info->storage_media == HA_SM_MEMORY)
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_ILLEGAL_HA_CREATE_OPTION,
|
||||
ER(ER_ILLEGAL_HA_CREATE_OPTION),
|
||||
ndbcluster_hton_name,
|
||||
|
|
@ -5471,7 +5471,7 @@ int ha_ndbcluster::create(const char *name,
|
|||
case ROW_TYPE_FIXED:
|
||||
if (field_type_forces_var_part(field->type()))
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_ILLEGAL_HA_CREATE_OPTION,
|
||||
ER(ER_ILLEGAL_HA_CREATE_OPTION),
|
||||
ndbcluster_hton_name,
|
||||
|
|
@ -5802,7 +5802,7 @@ int ha_ndbcluster::create_index(const char *name, KEY *key_info,
|
|||
case UNIQUE_INDEX:
|
||||
if (check_index_fields_not_null(key_info))
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_NULL_COLUMN_IN_INDEX,
|
||||
"Ndb does not support unique index on NULL valued attributes, index access with NULL value will become full table scan");
|
||||
}
|
||||
|
|
@ -5811,7 +5811,7 @@ int ha_ndbcluster::create_index(const char *name, KEY *key_info,
|
|||
case ORDERED_INDEX:
|
||||
if (key_info->algorithm == HA_KEY_ALG_HASH)
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_ILLEGAL_HA_CREATE_OPTION,
|
||||
ER(ER_ILLEGAL_HA_CREATE_OPTION),
|
||||
ndbcluster_hton_name,
|
||||
|
|
@ -7284,7 +7284,7 @@ int ndbcluster_find_files(handlerton *hton, THD *thd,
|
|||
file_name->str));
|
||||
if (ndb_create_table_from_engine(thd, db, file_name->str))
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_TABLE_EXISTS_ERROR,
|
||||
"Discover of table %s.%s failed",
|
||||
db, file_name->str);
|
||||
|
|
@ -7310,7 +7310,7 @@ int ndbcluster_find_files(handlerton *hton, THD *thd,
|
|||
file_name->length);
|
||||
DBUG_ASSERT(record);
|
||||
my_hash_delete(&ndb_tables, record);
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_TABLE_EXISTS_ERROR,
|
||||
"Local table %s.%s shadows ndb table",
|
||||
db, file_name->str);
|
||||
|
|
@ -9827,11 +9827,11 @@ char* ha_ndbcluster::get_tablespace_name(THD *thd, char* name, uint name_len)
|
|||
}
|
||||
err:
|
||||
if (ndberr.status == NdbError::TemporaryError)
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_GET_TEMPORARY_ERRMSG, ER(ER_GET_TEMPORARY_ERRMSG),
|
||||
ndberr.code, ndberr.message, "NDB");
|
||||
else
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_GET_ERRMSG, ER(ER_GET_ERRMSG),
|
||||
ndberr.code, ndberr.message, "NDB");
|
||||
return 0;
|
||||
|
|
@ -9957,7 +9957,7 @@ int ha_ndbcluster::get_default_no_partitions(HA_CREATE_INFO *create_info)
|
|||
if (adjusted_frag_count(no_fragments, no_nodes, reported_frags))
|
||||
{
|
||||
push_warning(current_thd,
|
||||
MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
|
||||
Sql_condition::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
|
||||
"Ndb might have problems storing the max amount of rows specified");
|
||||
}
|
||||
return (int)reported_frags;
|
||||
|
|
@ -10146,7 +10146,7 @@ uint ha_ndbcluster::set_up_partition_info(partition_info *part_info,
|
|||
{
|
||||
if (!current_thd->variables.new_mode)
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_ILLEGAL_HA_CREATE_OPTION,
|
||||
ER(ER_ILLEGAL_HA_CREATE_OPTION),
|
||||
ndbcluster_hton_name,
|
||||
|
|
|
|||
|
|
@ -290,13 +290,13 @@ static void run_query(THD *thd, char *buf, char *end,
|
|||
Thd_ndb *thd_ndb= get_thd_ndb(thd);
|
||||
for (i= 0; no_print_error[i]; i++)
|
||||
if ((thd_ndb->m_error_code == no_print_error[i]) ||
|
||||
(thd->stmt_da->sql_errno() == (unsigned) no_print_error[i]))
|
||||
(thd->get_stmt_da()->sql_errno() == (unsigned) no_print_error[i]))
|
||||
break;
|
||||
if (!no_print_error[i])
|
||||
sql_print_error("NDB: %s: error %s %d(ndb: %d) %d %d",
|
||||
buf,
|
||||
thd->stmt_da->message(),
|
||||
thd->stmt_da->sql_errno(),
|
||||
thd->get_stmt_da()->message(),
|
||||
thd->get_stmt_da()->sql_errno(),
|
||||
thd_ndb->m_error_code,
|
||||
(int) thd->is_error(), thd->is_slave_error);
|
||||
}
|
||||
|
|
@ -310,7 +310,7 @@ static void run_query(THD *thd, char *buf, char *end,
|
|||
is called from ndbcluster_reset_logs(), which is called from
|
||||
mysql_flush().
|
||||
*/
|
||||
thd->stmt_da->reset_diagnostics_area();
|
||||
thd->get_stmt_da()->reset_diagnostics_area();
|
||||
|
||||
thd->variables.option_bits= save_thd_options;
|
||||
thd->set_query(save_thd_query, save_thd_query_length);
|
||||
|
|
@ -984,8 +984,8 @@ static void print_could_not_discover_error(THD *thd,
|
|||
"my_errno: %d",
|
||||
schema->db, schema->name, schema->query,
|
||||
schema->node_id, my_errno);
|
||||
List_iterator_fast<MYSQL_ERROR> it(thd->warning_info->warn_list());
|
||||
MYSQL_ERROR *err;
|
||||
List_iterator_fast<Sql_condition> it(thd->warning_info->warn_list());
|
||||
Sql_condition *err;
|
||||
while ((err= it++))
|
||||
sql_print_warning("NDB Binlog: (%d)%s", err->get_sql_errno(),
|
||||
err->get_message_text());
|
||||
|
|
@ -1230,7 +1230,7 @@ ndbcluster_update_slock(THD *thd,
|
|||
char buf[1024];
|
||||
my_snprintf(buf, sizeof(buf), "Could not release lock on '%s.%s'",
|
||||
db, table_name);
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_GET_ERRMSG, ER(ER_GET_ERRMSG),
|
||||
ndb_error->code, ndb_error->message, buf);
|
||||
}
|
||||
|
|
@ -1559,7 +1559,7 @@ err:
|
|||
}
|
||||
end:
|
||||
if (ndb_error)
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_GET_ERRMSG, ER(ER_GET_ERRMSG),
|
||||
ndb_error->code,
|
||||
ndb_error->message,
|
||||
|
|
@ -2349,8 +2349,8 @@ static int open_ndb_binlog_index(THD *thd, TABLE **ndb_binlog_index)
|
|||
sql_print_error("NDB Binlog: Opening ndb_binlog_index: killed");
|
||||
else
|
||||
sql_print_error("NDB Binlog: Opening ndb_binlog_index: %d, '%s'",
|
||||
thd->stmt_da->sql_errno(),
|
||||
thd->stmt_da->message());
|
||||
thd->get_stmt_da()->sql_errno(),
|
||||
thd->get_stmt_da()->message());
|
||||
thd->proc_info= save_proc_info;
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -2406,9 +2406,9 @@ int ndb_add_ndb_binlog_index(THD *thd, void *_row)
|
|||
}
|
||||
|
||||
add_ndb_binlog_index_err:
|
||||
thd->stmt_da->can_overwrite_status= TRUE;
|
||||
thd->get_stmt_da()->set_overwrite_status(true);
|
||||
thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
|
||||
thd->stmt_da->can_overwrite_status= FALSE;
|
||||
thd->get_stmt_da()->set_overwrite_status(false);
|
||||
close_thread_tables(thd);
|
||||
thd->mdl_context.release_transactional_locks();
|
||||
ndb_binlog_index= 0;
|
||||
|
|
@ -2730,7 +2730,7 @@ ndbcluster_create_event(Ndb *ndb, const NDBTAB *ndbtab,
|
|||
"with BLOB attribute and no PK is not supported",
|
||||
share->key);
|
||||
if (push_warning)
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_ILLEGAL_HA_CREATE_OPTION,
|
||||
ER(ER_ILLEGAL_HA_CREATE_OPTION),
|
||||
ndbcluster_hton_name,
|
||||
|
|
@ -2774,7 +2774,7 @@ ndbcluster_create_event(Ndb *ndb, const NDBTAB *ndbtab,
|
|||
failed, print a warning
|
||||
*/
|
||||
if (push_warning > 1)
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_GET_ERRMSG, ER(ER_GET_ERRMSG),
|
||||
dict->getNdbError().code,
|
||||
dict->getNdbError().message, "NDB");
|
||||
|
|
@ -2802,7 +2802,7 @@ ndbcluster_create_event(Ndb *ndb, const NDBTAB *ndbtab,
|
|||
dict->dropEvent(my_event.getName()))
|
||||
{
|
||||
if (push_warning > 1)
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_GET_ERRMSG, ER(ER_GET_ERRMSG),
|
||||
dict->getNdbError().code,
|
||||
dict->getNdbError().message, "NDB");
|
||||
|
|
@ -2821,7 +2821,7 @@ ndbcluster_create_event(Ndb *ndb, const NDBTAB *ndbtab,
|
|||
if (dict->createEvent(my_event))
|
||||
{
|
||||
if (push_warning > 1)
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_GET_ERRMSG, ER(ER_GET_ERRMSG),
|
||||
dict->getNdbError().code,
|
||||
dict->getNdbError().message, "NDB");
|
||||
|
|
@ -2834,7 +2834,7 @@ ndbcluster_create_event(Ndb *ndb, const NDBTAB *ndbtab,
|
|||
DBUG_RETURN(-1);
|
||||
}
|
||||
#ifdef NDB_BINLOG_EXTRA_WARNINGS
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_GET_ERRMSG, ER(ER_GET_ERRMSG),
|
||||
0, "NDB Binlog: Removed trailing event",
|
||||
"NDB");
|
||||
|
|
@ -2945,7 +2945,7 @@ ndbcluster_create_event_ops(NDB_SHARE *share, const NDBTAB *ndbtab,
|
|||
{
|
||||
sql_print_error("NDB Binlog: Creating NdbEventOperation failed for"
|
||||
" %s",event_name);
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_GET_ERRMSG, ER(ER_GET_ERRMSG),
|
||||
ndb->getNdbError().code,
|
||||
ndb->getNdbError().message,
|
||||
|
|
@ -2994,7 +2994,7 @@ ndbcluster_create_event_ops(NDB_SHARE *share, const NDBTAB *ndbtab,
|
|||
sql_print_error("NDB Binlog: Creating NdbEventOperation"
|
||||
" blob field %u handles failed (code=%d) for %s",
|
||||
j, op->getNdbError().code, event_name);
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_GET_ERRMSG, ER(ER_GET_ERRMSG),
|
||||
op->getNdbError().code,
|
||||
op->getNdbError().message,
|
||||
|
|
@ -3033,7 +3033,7 @@ ndbcluster_create_event_ops(NDB_SHARE *share, const NDBTAB *ndbtab,
|
|||
retries= 0;
|
||||
if (retries == 0)
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_GET_ERRMSG, ER(ER_GET_ERRMSG),
|
||||
op->getNdbError().code, op->getNdbError().message,
|
||||
"NDB");
|
||||
|
|
@ -3101,7 +3101,7 @@ ndbcluster_handle_drop_table(Ndb *ndb, const char *event_name,
|
|||
if (dict->getNdbError().code != 4710)
|
||||
{
|
||||
/* drop event failed for some reason, issue a warning */
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_GET_ERRMSG, ER(ER_GET_ERRMSG),
|
||||
dict->getNdbError().code,
|
||||
dict->getNdbError().message, "NDB");
|
||||
|
|
@ -4277,9 +4277,9 @@ err:
|
|||
sql_print_information("Stopping Cluster Binlog");
|
||||
DBUG_PRINT("info",("Shutting down cluster binlog thread"));
|
||||
thd->proc_info= "Shutting down";
|
||||
thd->stmt_da->can_overwrite_status= TRUE;
|
||||
thd->get_stmt_da()->set_overwrite_status(true);
|
||||
thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
|
||||
thd->stmt_da->can_overwrite_status= FALSE;
|
||||
thd->get_stmt_da()->set_overwrite_status(false);
|
||||
close_thread_tables(thd);
|
||||
thd->mdl_context.release_transactional_locks();
|
||||
mysql_mutex_lock(&injector_mutex);
|
||||
|
|
|
|||
|
|
@ -1375,7 +1375,7 @@ ha_ndbcluster_cond::generate_scan_filter(NdbScanOperation *op)
|
|||
{
|
||||
// err.message has static storage
|
||||
DBUG_PRINT("info", ("%s", err.message));
|
||||
push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
err.code, err.message);
|
||||
ret=0;
|
||||
}
|
||||
|
|
|
|||
1691
sql/ha_partition.cc
1691
sql/ha_partition.cc
File diff suppressed because it is too large
Load diff
|
|
@ -47,6 +47,92 @@ enum partition_keywords
|
|||
/* offset to the engines array */
|
||||
#define PAR_ENGINES_OFFSET 12
|
||||
|
||||
/** Struct used for partition_name_hash */
|
||||
typedef struct st_part_name_def
|
||||
{
|
||||
uchar *partition_name;
|
||||
uint length;
|
||||
uint32 part_id;
|
||||
my_bool is_subpart;
|
||||
} PART_NAME_DEF;
|
||||
|
||||
/** class where to save partitions Handler_share's */
|
||||
class Parts_share_refs
|
||||
{
|
||||
public:
|
||||
uint num_parts; /**< Size of ha_share array */
|
||||
Handler_share **ha_shares; /**< Storage for each part */
|
||||
Parts_share_refs()
|
||||
{
|
||||
num_parts= 0;
|
||||
ha_shares= NULL;
|
||||
}
|
||||
~Parts_share_refs()
|
||||
{
|
||||
uint i;
|
||||
for (i= 0; i < num_parts; i++)
|
||||
if (ha_shares[i])
|
||||
delete ha_shares[i];
|
||||
if (ha_shares)
|
||||
delete [] ha_shares;
|
||||
}
|
||||
bool init(uint arg_num_parts)
|
||||
{
|
||||
DBUG_ASSERT(!num_parts && !ha_shares);
|
||||
num_parts= arg_num_parts;
|
||||
/* Allocate an array of Handler_share pointers */
|
||||
ha_shares= new Handler_share *[num_parts];
|
||||
if (!ha_shares)
|
||||
{
|
||||
num_parts= 0;
|
||||
return true;
|
||||
}
|
||||
memset(ha_shares, 0, sizeof(Handler_share*) * num_parts);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Partition specific Handler_share.
|
||||
*/
|
||||
class Partition_share : public Handler_share
|
||||
{
|
||||
public:
|
||||
bool auto_inc_initialized;
|
||||
mysql_mutex_t auto_inc_mutex; /**< protecting auto_inc val */
|
||||
ulonglong next_auto_inc_val; /**< first non reserved value */
|
||||
/**
|
||||
Hash of partition names. Initialized in the first ha_partition::open()
|
||||
for the table_share. After that it is read-only, i.e. no locking required.
|
||||
*/
|
||||
bool partition_name_hash_initialized;
|
||||
HASH partition_name_hash;
|
||||
/** Storage for each partitions Handler_share */
|
||||
Parts_share_refs *partitions_share_refs;
|
||||
Partition_share() {}
|
||||
~Partition_share()
|
||||
{
|
||||
DBUG_ENTER("Partition_share::~Partition_share");
|
||||
mysql_mutex_destroy(&auto_inc_mutex);
|
||||
if (partition_name_hash_initialized)
|
||||
my_hash_free(&partition_name_hash);
|
||||
if (partitions_share_refs)
|
||||
delete partitions_share_refs;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
bool init(uint num_parts);
|
||||
void lock_auto_inc()
|
||||
{
|
||||
mysql_mutex_lock(&auto_inc_mutex);
|
||||
}
|
||||
void unlock_auto_inc()
|
||||
{
|
||||
mysql_mutex_unlock(&auto_inc_mutex);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class ha_partition :public handler
|
||||
{
|
||||
private:
|
||||
|
|
@ -176,16 +262,25 @@ private:
|
|||
ha_rows m_bulk_inserted_rows;
|
||||
/** used for prediction of start_bulk_insert rows */
|
||||
enum_monotonicity_info m_part_func_monotonicity_info;
|
||||
/** keep track of locked partitions */
|
||||
MY_BITMAP m_locked_partitions;
|
||||
/** Stores shared auto_increment etc. */
|
||||
Partition_share *part_share;
|
||||
/** Temporary storage for new partitions Handler_shares during ALTER */
|
||||
List<Parts_share_refs> m_new_partitions_share_refs;
|
||||
/** Sorted array of partition ids in descending order of number of rows. */
|
||||
uint32 *m_part_ids_sorted_by_num_of_records;
|
||||
/* Compare function for my_qsort2, for reversed order. */
|
||||
static int compare_number_of_records(ha_partition *me,
|
||||
const uint32 *a,
|
||||
const uint32 *b);
|
||||
/** keep track of partitions to call ha_reset */
|
||||
MY_BITMAP m_partitions_to_reset;
|
||||
/** partitions that returned HA_ERR_KEY_NOT_FOUND. */
|
||||
MY_BITMAP m_key_not_found_partitions;
|
||||
bool m_key_not_found;
|
||||
public:
|
||||
Partition_share *get_part_share() { return part_share; }
|
||||
handler *clone(const char *name, MEM_ROOT *mem_root);
|
||||
virtual void set_part_info(partition_info *part_info)
|
||||
{
|
||||
|
|
@ -268,11 +363,10 @@ private:
|
|||
handler *file, const char *part_name,
|
||||
partition_element *p_elem);
|
||||
/*
|
||||
delete_table, rename_table and create uses very similar logic which
|
||||
delete_table and rename_table uses very similar logic which
|
||||
is packed into this routine.
|
||||
*/
|
||||
uint del_ren_cre_table(const char *from, const char *to,
|
||||
TABLE *table_arg, HA_CREATE_INFO *create_info);
|
||||
uint del_ren_table(const char *from, const char *to);
|
||||
/*
|
||||
One method to create the table_name.par file containing the names of the
|
||||
underlying partitions, their engine and the number of partitions.
|
||||
|
|
@ -289,9 +383,15 @@ private:
|
|||
int set_up_table_before_create(TABLE *table_arg,
|
||||
const char *partition_name_with_path,
|
||||
HA_CREATE_INFO *info,
|
||||
uint part_id,
|
||||
partition_element *p_elem);
|
||||
partition_element *find_partition_element(uint part_id);
|
||||
bool insert_partition_name_in_hash(const char *name, uint part_id,
|
||||
bool is_subpart);
|
||||
bool populate_partition_name_hash();
|
||||
Partition_share *get_share();
|
||||
bool set_ha_share_ref(Handler_share **ha_share);
|
||||
bool init_partition_bitmaps();
|
||||
void free_partition_bitmaps();
|
||||
|
||||
public:
|
||||
|
||||
|
|
@ -397,7 +497,8 @@ public:
|
|||
virtual bool is_fatal_error(int error, uint flags)
|
||||
{
|
||||
if (!handler::is_fatal_error(error, flags) ||
|
||||
error == HA_ERR_NO_PARTITION_FOUND)
|
||||
error == HA_ERR_NO_PARTITION_FOUND ||
|
||||
error == HA_ERR_NOT_IN_LOCK_PARTITIONS)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -957,16 +1058,15 @@ private:
|
|||
/* lock already taken */
|
||||
if (auto_increment_safe_stmt_log_lock)
|
||||
return;
|
||||
DBUG_ASSERT(table_share->ha_part_data && !auto_increment_lock);
|
||||
DBUG_ASSERT(!auto_increment_lock);
|
||||
if(table_share->tmp_table == NO_TMP_TABLE)
|
||||
{
|
||||
auto_increment_lock= TRUE;
|
||||
mysql_mutex_lock(&table_share->ha_part_data->LOCK_auto_inc);
|
||||
part_share->lock_auto_inc();
|
||||
}
|
||||
}
|
||||
virtual void unlock_auto_increment()
|
||||
{
|
||||
DBUG_ASSERT(table_share->ha_part_data);
|
||||
/*
|
||||
If auto_increment_safe_stmt_log_lock is true, we have to keep the lock.
|
||||
It will be set to false and thus unlocked at the end of the statement by
|
||||
|
|
@ -974,7 +1074,7 @@ private:
|
|||
*/
|
||||
if(auto_increment_lock && !auto_increment_safe_stmt_log_lock)
|
||||
{
|
||||
mysql_mutex_unlock(&table_share->ha_part_data->LOCK_auto_inc);
|
||||
part_share->unlock_auto_inc();
|
||||
auto_increment_lock= FALSE;
|
||||
}
|
||||
}
|
||||
|
|
@ -983,10 +1083,10 @@ private:
|
|||
ulonglong nr= (((Field_num*) field)->unsigned_flag ||
|
||||
field->val_int() > 0) ? field->val_int() : 0;
|
||||
lock_auto_increment();
|
||||
DBUG_ASSERT(table_share->ha_part_data->auto_inc_initialized == TRUE);
|
||||
DBUG_ASSERT(part_share->auto_inc_initialized);
|
||||
/* must check when the mutex is taken */
|
||||
if (nr >= table_share->ha_part_data->next_auto_inc_val)
|
||||
table_share->ha_part_data->next_auto_inc_val= nr + 1;
|
||||
if (nr >= part_share->next_auto_inc_val)
|
||||
part_share->next_auto_inc_val= nr + 1;
|
||||
unlock_auto_increment();
|
||||
}
|
||||
|
||||
|
|
@ -1052,20 +1152,25 @@ public:
|
|||
|
||||
/*
|
||||
-------------------------------------------------------------------------
|
||||
MODULE on-line ALTER TABLE
|
||||
-------------------------------------------------------------------------
|
||||
MODULE in-place ALTER TABLE
|
||||
-------------------------------------------------------------------------
|
||||
These methods are in the handler interface. (used by innodb-plugin)
|
||||
They are used for on-line/fast alter table add/drop index:
|
||||
-------------------------------------------------------------------------
|
||||
They are used for in-place alter table:
|
||||
-------------------------------------------------------------------------
|
||||
*/
|
||||
virtual int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys,
|
||||
handler_add_index **add);
|
||||
virtual int final_add_index(handler_add_index *add, bool commit);
|
||||
virtual int prepare_drop_index(TABLE *table_arg, uint *key_num,
|
||||
uint num_of_keys);
|
||||
virtual int final_drop_index(TABLE *table_arg);
|
||||
virtual enum_alter_inplace_result
|
||||
check_if_supported_inplace_alter(TABLE *altered_table,
|
||||
Alter_inplace_info *ha_alter_info);
|
||||
virtual bool prepare_inplace_alter_table(TABLE *altered_table,
|
||||
Alter_inplace_info *ha_alter_info);
|
||||
virtual bool inplace_alter_table(TABLE *altered_table,
|
||||
Alter_inplace_info *ha_alter_info);
|
||||
virtual bool commit_inplace_alter_table(TABLE *altered_table,
|
||||
Alter_inplace_info *ha_alter_info,
|
||||
bool commit);
|
||||
virtual void notify_table_changed();
|
||||
|
||||
/*
|
||||
/*
|
||||
-------------------------------------------------------------------------
|
||||
MODULE tablespace support
|
||||
-------------------------------------------------------------------------
|
||||
|
|
|
|||
357
sql/handler.cc
357
sql/handler.cc
|
|
@ -61,7 +61,7 @@ static handlerton *installed_htons[128];
|
|||
#define BITMAP_STACKBUF_SIZE (128/8)
|
||||
|
||||
KEY_CREATE_INFO default_key_create_info=
|
||||
{ HA_KEY_ALG_UNDEF, 0, {NullS, 0}, {NullS, 0}, 0 };
|
||||
{ HA_KEY_ALG_UNDEF, 0, {NullS, 0}, {NullS, 0}, true };
|
||||
|
||||
/* number of entries in handlertons[] */
|
||||
ulong total_ha= 0;
|
||||
|
|
@ -98,6 +98,7 @@ uint known_extensions_id= 0;
|
|||
static int commit_one_phase_2(THD *thd, bool all, THD_TRANS *trans,
|
||||
bool is_real_trans);
|
||||
|
||||
|
||||
static plugin_ref ha_default_plugin(THD *thd)
|
||||
{
|
||||
if (thd->variables.table_plugin)
|
||||
|
|
@ -1095,7 +1096,7 @@ int ha_prepare(THD *thd)
|
|||
}
|
||||
else
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
|
||||
ha_resolve_storage_engine_name(ht));
|
||||
}
|
||||
|
|
@ -1203,7 +1204,7 @@ int ha_commit_trans(THD *thd, bool all)
|
|||
|
||||
/* Just a random warning to test warnings pushed during autocommit. */
|
||||
DBUG_EXECUTE_IF("warn_during_ha_commit_trans",
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARNING_NOT_COMPLETE_ROLLBACK,
|
||||
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK)););
|
||||
|
||||
|
|
@ -1523,7 +1524,7 @@ int ha_rollback_trans(THD *thd, bool all)
|
|||
trans->no_2pc=0;
|
||||
if (is_real_trans && thd->transaction_rollback_request &&
|
||||
thd->transaction.xid_state.xa_state != XA_NOTR)
|
||||
thd->transaction.xid_state.rm_error= thd->stmt_da->sql_errno();
|
||||
thd->transaction.xid_state.rm_error= thd->get_stmt_da()->sql_errno();
|
||||
}
|
||||
/* Always cleanup. Even if nht==0. There may be savepoints. */
|
||||
if (is_real_trans)
|
||||
|
|
@ -1546,7 +1547,7 @@ int ha_rollback_trans(THD *thd, bool all)
|
|||
*/
|
||||
if (is_real_trans && thd->transaction.all.modified_non_trans_table &&
|
||||
!thd->slave_thread && thd->killed < KILL_CONNECTION)
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARNING_NOT_COMPLETE_ROLLBACK,
|
||||
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
|
||||
(void) RUN_HOOK(transaction, after_rollback, (thd, FALSE));
|
||||
|
|
@ -2039,7 +2040,7 @@ int ha_start_consistent_snapshot(THD *thd)
|
|||
exist:
|
||||
*/
|
||||
if (warn)
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
|
||||
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
|
||||
"This MySQL server does not support any "
|
||||
"consistent-read capable storage engine");
|
||||
return 0;
|
||||
|
|
@ -2135,9 +2136,9 @@ public:
|
|||
virtual bool handle_condition(THD *thd,
|
||||
uint sql_errno,
|
||||
const char* sqlstate,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
Sql_condition::enum_warning_level level,
|
||||
const char* msg,
|
||||
MYSQL_ERROR ** cond_hdl);
|
||||
Sql_condition ** cond_hdl);
|
||||
char buff[MYSQL_ERRMSG_SIZE];
|
||||
};
|
||||
|
||||
|
|
@ -2147,9 +2148,9 @@ Ha_delete_table_error_handler::
|
|||
handle_condition(THD *,
|
||||
uint,
|
||||
const char*,
|
||||
MYSQL_ERROR::enum_warning_level,
|
||||
Sql_condition::enum_warning_level,
|
||||
const char* msg,
|
||||
MYSQL_ERROR ** cond_hdl)
|
||||
Sql_condition ** cond_hdl)
|
||||
{
|
||||
*cond_hdl= NULL;
|
||||
/* Grab the error message */
|
||||
|
|
@ -2213,7 +2214,7 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path,
|
|||
XXX: should we convert *all* errors to warnings here?
|
||||
What if the error is fatal?
|
||||
*/
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, error,
|
||||
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, error,
|
||||
ha_delete_table_error_handler.buff);
|
||||
}
|
||||
delete file;
|
||||
|
|
@ -2236,8 +2237,10 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path,
|
|||
handler *handler::clone(const char *name, MEM_ROOT *mem_root)
|
||||
{
|
||||
handler *new_handler= get_new_handler(table->s, mem_root, ht);
|
||||
if (! new_handler)
|
||||
if (!new_handler)
|
||||
return NULL;
|
||||
if (new_handler->set_ha_share_ref(ha_share))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
Allocate handler->ref here because otherwise ha_open will allocate it
|
||||
|
|
@ -2247,7 +2250,7 @@ handler *handler::clone(const char *name, MEM_ROOT *mem_root)
|
|||
|
||||
if (!(new_handler->ref= (uchar*) alloc_root(mem_root,
|
||||
ALIGN_SIZE(ref_length)*2)))
|
||||
return NULL;
|
||||
goto err;
|
||||
|
||||
/*
|
||||
TODO: Implement a more efficient way to have more than one index open for
|
||||
|
|
@ -2258,9 +2261,13 @@ handler *handler::clone(const char *name, MEM_ROOT *mem_root)
|
|||
*/
|
||||
if (new_handler->ha_open(table, name, table->db_stat,
|
||||
HA_OPEN_IGNORE_IF_LOCKED))
|
||||
return NULL;
|
||||
goto err;
|
||||
|
||||
return new_handler;
|
||||
|
||||
err:
|
||||
delete new_handler;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2342,6 +2349,8 @@ int handler::ha_open(TABLE *table_arg, const char *name, int mode,
|
|||
|
||||
table= table_arg;
|
||||
DBUG_ASSERT(table->s == table_share);
|
||||
DBUG_ASSERT(m_lock_type == F_UNLCK);
|
||||
DBUG_PRINT("info", ("old m_lock_type: %d F_UNLCK %d", m_lock_type, F_UNLCK));
|
||||
DBUG_ASSERT(alloc_root_inited(&table->mem_root));
|
||||
|
||||
if ((error=open(name,mode,test_if_locked)))
|
||||
|
|
@ -2363,8 +2372,16 @@ int handler::ha_open(TABLE *table_arg, const char *name, int mode,
|
|||
DBUG_ASSERT(m_psi == NULL);
|
||||
DBUG_ASSERT(table_share != NULL);
|
||||
#ifdef HAVE_PSI_TABLE_INTERFACE
|
||||
PSI_table_share *share_psi= ha_table_share_psi(table_share);
|
||||
m_psi= PSI_TABLE_CALL(open_table)(share_psi, this);
|
||||
/*
|
||||
Do not call this for partitions handlers, since it may take too much
|
||||
resources.
|
||||
So only use the m_psi on table level, not for individual partitions.
|
||||
*/
|
||||
if (!(test_if_locked & HA_OPEN_NO_PSI_CALL))
|
||||
{
|
||||
PSI_table_share *share_psi= ha_table_share_psi(table_share);
|
||||
m_psi= PSI_TABLE_CALL(open_table)(share_psi, this);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (table->s->db_options_in_use & HA_OPTION_READ_ONLY_DATA)
|
||||
|
|
@ -2400,13 +2417,20 @@ int handler::ha_close(void)
|
|||
PSI_TABLE_CALL(close_table)(m_psi);
|
||||
m_psi= NULL; /* instrumentation handle, invalid after close_table() */
|
||||
#endif
|
||||
|
||||
// TODO: set table= NULL to mark the handler as closed?
|
||||
DBUG_ASSERT(m_psi == NULL);
|
||||
DBUG_ASSERT(m_lock_type == F_UNLCK);
|
||||
DBUG_ASSERT(inited == NONE);
|
||||
DBUG_RETURN(close());
|
||||
}
|
||||
|
||||
int handler::ha_rnd_next(uchar *buf)
|
||||
{
|
||||
int result;
|
||||
DBUG_ENTER("handler::ha_rnd_next");
|
||||
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
|
||||
m_lock_type != F_UNLCK);
|
||||
DBUG_ASSERT(inited == RND);
|
||||
|
||||
MYSQL_TABLE_IO_WAIT(m_psi, PSI_TABLE_FETCH_ROW, MAX_KEY, 0,
|
||||
{ result= rnd_next(buf); })
|
||||
|
|
@ -2421,12 +2445,17 @@ int handler::ha_rnd_next(uchar *buf)
|
|||
increment_statistics(&SSV::ha_read_rnd_next_count);
|
||||
|
||||
table->status=result ? STATUS_NOT_FOUND: 0;
|
||||
return result;
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
|
||||
int handler::ha_rnd_pos(uchar *buf, uchar *pos)
|
||||
{
|
||||
int result;
|
||||
DBUG_ENTER("handler::ha_rnd_pos");
|
||||
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
|
||||
m_lock_type != F_UNLCK);
|
||||
/* TODO: Find out how to solve ha_rnd_pos when finding duplicate update. */
|
||||
/* DBUG_ASSERT(inited == RND); */
|
||||
|
||||
MYSQL_TABLE_IO_WAIT(m_psi, PSI_TABLE_FETCH_ROW, MAX_KEY, 0,
|
||||
{ result= rnd_pos(buf, pos); })
|
||||
|
|
@ -2434,7 +2463,7 @@ int handler::ha_rnd_pos(uchar *buf, uchar *pos)
|
|||
if (!result)
|
||||
update_rows_read();
|
||||
table->status=result ? STATUS_NOT_FOUND: 0;
|
||||
return result;
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
|
||||
int handler::ha_index_read_map(uchar *buf, const uchar *key,
|
||||
|
|
@ -2442,6 +2471,9 @@ int handler::ha_index_read_map(uchar *buf, const uchar *key,
|
|||
enum ha_rkey_function find_flag)
|
||||
{
|
||||
int result;
|
||||
DBUG_ENTER("handler::ha_index_read_map");
|
||||
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
|
||||
m_lock_type != F_UNLCK);
|
||||
DBUG_ASSERT(inited==INDEX);
|
||||
|
||||
MYSQL_TABLE_IO_WAIT(m_psi, PSI_TABLE_FETCH_ROW, active_index, 0,
|
||||
|
|
@ -2450,7 +2482,7 @@ int handler::ha_index_read_map(uchar *buf, const uchar *key,
|
|||
if (!result)
|
||||
update_index_statistics();
|
||||
table->status=result ? STATUS_NOT_FOUND: 0;
|
||||
return result;
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -2465,6 +2497,8 @@ int handler::ha_index_read_idx_map(uchar *buf, uint index, const uchar *key,
|
|||
{
|
||||
int result;
|
||||
DBUG_ASSERT(inited==NONE);
|
||||
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
|
||||
m_lock_type != F_UNLCK);
|
||||
DBUG_ASSERT(end_range == NULL);
|
||||
MYSQL_TABLE_IO_WAIT(m_psi, PSI_TABLE_FETCH_ROW, index, 0,
|
||||
{ result= index_read_idx_map(buf, index, key, keypart_map, find_flag); })
|
||||
|
|
@ -2481,6 +2515,9 @@ int handler::ha_index_read_idx_map(uchar *buf, uint index, const uchar *key,
|
|||
int handler::ha_index_next(uchar * buf)
|
||||
{
|
||||
int result;
|
||||
DBUG_ENTER("handler::ha_index_next");
|
||||
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
|
||||
m_lock_type != F_UNLCK);
|
||||
DBUG_ASSERT(inited==INDEX);
|
||||
|
||||
MYSQL_TABLE_IO_WAIT(m_psi, PSI_TABLE_FETCH_ROW, active_index, 0,
|
||||
|
|
@ -2489,12 +2526,15 @@ int handler::ha_index_next(uchar * buf)
|
|||
if (!result)
|
||||
update_index_statistics();
|
||||
table->status=result ? STATUS_NOT_FOUND: 0;
|
||||
return result;
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
|
||||
int handler::ha_index_prev(uchar * buf)
|
||||
{
|
||||
int result;
|
||||
DBUG_ENTER("handler::ha_index_prev");
|
||||
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
|
||||
m_lock_type != F_UNLCK);
|
||||
DBUG_ASSERT(inited==INDEX);
|
||||
|
||||
MYSQL_TABLE_IO_WAIT(m_psi, PSI_TABLE_FETCH_ROW, active_index, 0,
|
||||
|
|
@ -2503,12 +2543,14 @@ int handler::ha_index_prev(uchar * buf)
|
|||
if (!result)
|
||||
update_index_statistics();
|
||||
table->status=result ? STATUS_NOT_FOUND: 0;
|
||||
return result;
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
|
||||
int handler::ha_index_first(uchar * buf)
|
||||
{
|
||||
int result;
|
||||
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
|
||||
m_lock_type != F_UNLCK);
|
||||
DBUG_ASSERT(inited==INDEX);
|
||||
|
||||
MYSQL_TABLE_IO_WAIT(m_psi, PSI_TABLE_FETCH_ROW, active_index, 0,
|
||||
|
|
@ -2523,6 +2565,8 @@ int handler::ha_index_first(uchar * buf)
|
|||
int handler::ha_index_last(uchar * buf)
|
||||
{
|
||||
int result;
|
||||
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
|
||||
m_lock_type != F_UNLCK);
|
||||
DBUG_ASSERT(inited==INDEX);
|
||||
|
||||
MYSQL_TABLE_IO_WAIT(m_psi, PSI_TABLE_FETCH_ROW, active_index, 0,
|
||||
|
|
@ -2537,6 +2581,8 @@ int handler::ha_index_last(uchar * buf)
|
|||
int handler::ha_index_next_same(uchar *buf, const uchar *key, uint keylen)
|
||||
{
|
||||
int result;
|
||||
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
|
||||
m_lock_type != F_UNLCK);
|
||||
DBUG_ASSERT(inited==INDEX);
|
||||
|
||||
MYSQL_TABLE_IO_WAIT(m_psi, PSI_TABLE_FETCH_ROW, active_index, 0,
|
||||
|
|
@ -3059,6 +3105,9 @@ void handler::get_auto_increment(ulonglong offset, ulonglong increment,
|
|||
void handler::ha_release_auto_increment()
|
||||
{
|
||||
DBUG_ENTER("ha_release_auto_increment");
|
||||
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
|
||||
m_lock_type != F_UNLCK ||
|
||||
(!next_insert_id && !insert_id_for_cur_row));
|
||||
release_auto_increment();
|
||||
insert_id_for_cur_row= 0;
|
||||
auto_inc_interval_for_cur_row.replace(0, 0, 0);
|
||||
|
|
@ -3190,7 +3239,9 @@ void handler::print_error(int error, myf errflag)
|
|||
uint key_nr=get_dup_key(error);
|
||||
if ((int) key_nr >= 0)
|
||||
{
|
||||
print_keydup_error(table, &table->key_info[key_nr], errflag);
|
||||
print_keydup_error(table,
|
||||
key_nr == MAX_KEY ? NULL : &table->key_info[key_nr],
|
||||
errflag);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
}
|
||||
|
|
@ -3202,9 +3253,12 @@ void handler::print_error(int error, myf errflag)
|
|||
char rec_buf[MAX_KEY_LENGTH];
|
||||
String rec(rec_buf, sizeof(rec_buf), system_charset_info);
|
||||
/* Table is opened and defined at this point */
|
||||
key_unpack(&rec, table, 0 /* just print the subset of fields that are
|
||||
part of the first index, printing the whole
|
||||
row from there is not easy */);
|
||||
|
||||
/*
|
||||
Just print the subset of fields that are part of the first index,
|
||||
printing the whole row from there is not easy.
|
||||
*/
|
||||
key_unpack(&rec, table, &table->key_info[0]);
|
||||
|
||||
char child_table_name[NAME_LEN + 1];
|
||||
char child_key_name[NAME_LEN + 1];
|
||||
|
|
@ -3339,7 +3393,7 @@ void handler::print_error(int error, myf errflag)
|
|||
case HA_ERR_AUTOINC_ERANGE:
|
||||
textno= error;
|
||||
my_error(textno, errflag, table->next_number_field->field_name,
|
||||
table->in_use->warning_info->current_row_for_warning());
|
||||
table->in_use->get_stmt_da()->current_row_for_warning());
|
||||
DBUG_VOID_RETURN;
|
||||
break;
|
||||
case HA_ERR_TOO_MANY_CONCURRENT_TRXS:
|
||||
|
|
@ -3348,6 +3402,9 @@ void handler::print_error(int error, myf errflag)
|
|||
case HA_ERR_INDEX_COL_TOO_LONG:
|
||||
textno= ER_INDEX_COLUMN_TOO_LONG;
|
||||
break;
|
||||
case HA_ERR_NOT_IN_LOCK_PARTITIONS:
|
||||
textno=ER_ROW_DOES_NOT_MATCH_GIVEN_PARTITION_SET;
|
||||
break;
|
||||
case HA_ERR_INDEX_CORRUPT:
|
||||
textno= ER_INDEX_CORRUPT;
|
||||
break;
|
||||
|
|
@ -3567,6 +3624,8 @@ err:
|
|||
*/
|
||||
uint handler::get_dup_key(int error)
|
||||
{
|
||||
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
|
||||
m_lock_type != F_UNLCK);
|
||||
DBUG_ENTER("handler::get_dup_key");
|
||||
table->file->errkey = (uint) -1;
|
||||
if (error == HA_ERR_FOUND_DUPP_KEY || error == HA_ERR_FOREIGN_DUPLICATE_KEY ||
|
||||
|
|
@ -3672,6 +3731,8 @@ void handler::drop_table(const char *name)
|
|||
int handler::ha_check(THD *thd, HA_CHECK_OPT *check_opt)
|
||||
{
|
||||
int error;
|
||||
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
|
||||
m_lock_type != F_UNLCK);
|
||||
|
||||
if ((table->s->mysql_version >= MYSQL_VERSION_ID) &&
|
||||
(check_opt->sql_flags & TT_FOR_UPGRADE))
|
||||
|
|
@ -3758,6 +3819,8 @@ int
|
|||
handler::ha_bulk_update_row(const uchar *old_data, uchar *new_data,
|
||||
uint *dup_key_found)
|
||||
{
|
||||
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
|
||||
m_lock_type == F_WRLCK);
|
||||
mark_trx_read_write();
|
||||
|
||||
return bulk_update_row(old_data, new_data, dup_key_found);
|
||||
|
|
@ -3773,6 +3836,8 @@ handler::ha_bulk_update_row(const uchar *old_data, uchar *new_data,
|
|||
int
|
||||
handler::ha_delete_all_rows()
|
||||
{
|
||||
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
|
||||
m_lock_type == F_WRLCK);
|
||||
mark_trx_read_write();
|
||||
|
||||
return delete_all_rows();
|
||||
|
|
@ -3788,6 +3853,8 @@ handler::ha_delete_all_rows()
|
|||
int
|
||||
handler::ha_truncate()
|
||||
{
|
||||
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
|
||||
m_lock_type == F_WRLCK);
|
||||
mark_trx_read_write();
|
||||
|
||||
return truncate();
|
||||
|
|
@ -3803,6 +3870,8 @@ handler::ha_truncate()
|
|||
int
|
||||
handler::ha_reset_auto_increment(ulonglong value)
|
||||
{
|
||||
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
|
||||
m_lock_type == F_WRLCK);
|
||||
mark_trx_read_write();
|
||||
|
||||
return reset_auto_increment(value);
|
||||
|
|
@ -3818,6 +3887,8 @@ handler::ha_reset_auto_increment(ulonglong value)
|
|||
int
|
||||
handler::ha_optimize(THD* thd, HA_CHECK_OPT* check_opt)
|
||||
{
|
||||
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
|
||||
m_lock_type == F_WRLCK);
|
||||
mark_trx_read_write();
|
||||
|
||||
return optimize(thd, check_opt);
|
||||
|
|
@ -3833,6 +3904,8 @@ handler::ha_optimize(THD* thd, HA_CHECK_OPT* check_opt)
|
|||
int
|
||||
handler::ha_analyze(THD* thd, HA_CHECK_OPT* check_opt)
|
||||
{
|
||||
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
|
||||
m_lock_type != F_UNLCK);
|
||||
mark_trx_read_write();
|
||||
|
||||
return analyze(thd, check_opt);
|
||||
|
|
@ -3848,6 +3921,8 @@ handler::ha_analyze(THD* thd, HA_CHECK_OPT* check_opt)
|
|||
bool
|
||||
handler::ha_check_and_repair(THD *thd)
|
||||
{
|
||||
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
|
||||
m_lock_type == F_UNLCK);
|
||||
mark_trx_read_write();
|
||||
|
||||
return check_and_repair(thd);
|
||||
|
|
@ -3863,6 +3938,8 @@ handler::ha_check_and_repair(THD *thd)
|
|||
int
|
||||
handler::ha_disable_indexes(uint mode)
|
||||
{
|
||||
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
|
||||
m_lock_type != F_UNLCK);
|
||||
mark_trx_read_write();
|
||||
|
||||
return disable_indexes(mode);
|
||||
|
|
@ -3878,6 +3955,8 @@ handler::ha_disable_indexes(uint mode)
|
|||
int
|
||||
handler::ha_enable_indexes(uint mode)
|
||||
{
|
||||
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
|
||||
m_lock_type != F_UNLCK);
|
||||
mark_trx_read_write();
|
||||
|
||||
return enable_indexes(mode);
|
||||
|
|
@ -3893,26 +3972,116 @@ handler::ha_enable_indexes(uint mode)
|
|||
int
|
||||
handler::ha_discard_or_import_tablespace(my_bool discard)
|
||||
{
|
||||
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
|
||||
m_lock_type == F_WRLCK);
|
||||
mark_trx_read_write();
|
||||
|
||||
return discard_or_import_tablespace(discard);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Prepare for alter: public interface.
|
||||
|
||||
Called to prepare an *online* ALTER.
|
||||
|
||||
@sa handler::prepare_for_alter()
|
||||
*/
|
||||
|
||||
void
|
||||
handler::ha_prepare_for_alter()
|
||||
bool handler::ha_prepare_inplace_alter_table(TABLE *altered_table,
|
||||
Alter_inplace_info *ha_alter_info)
|
||||
{
|
||||
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
|
||||
m_lock_type != F_UNLCK);
|
||||
mark_trx_read_write();
|
||||
|
||||
prepare_for_alter();
|
||||
return prepare_inplace_alter_table(altered_table, ha_alter_info);
|
||||
}
|
||||
|
||||
|
||||
bool handler::ha_commit_inplace_alter_table(TABLE *altered_table,
|
||||
Alter_inplace_info *ha_alter_info,
|
||||
bool commit)
|
||||
{
|
||||
/*
|
||||
At this point we should have an exclusive metadata lock on the table.
|
||||
The exception is if we're about to roll back changes (commit= false).
|
||||
In this case, we might be rolling back after a failed lock upgrade,
|
||||
so we could be holding the same lock level as for inplace_alter_table().
|
||||
*/
|
||||
DBUG_ASSERT(ha_thd()->mdl_context.is_lock_owner(MDL_key::TABLE,
|
||||
table->s->db.str,
|
||||
table->s->table_name.str,
|
||||
MDL_EXCLUSIVE) ||
|
||||
!commit);
|
||||
|
||||
return commit_inplace_alter_table(altered_table, ha_alter_info, commit);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Default implementation to support in-place alter table
|
||||
and old online add/drop index API
|
||||
*/
|
||||
|
||||
enum_alter_inplace_result
|
||||
handler::check_if_supported_inplace_alter(TABLE *altered_table,
|
||||
Alter_inplace_info *ha_alter_info)
|
||||
{
|
||||
DBUG_ENTER("check_if_supported_alter");
|
||||
|
||||
HA_CREATE_INFO *create_info= ha_alter_info->create_info;
|
||||
|
||||
Alter_inplace_info::HA_ALTER_FLAGS inplace_offline_operations=
|
||||
Alter_inplace_info::ALTER_COLUMN_EQUAL_PACK_LENGTH |
|
||||
Alter_inplace_info::ALTER_COLUMN_NAME |
|
||||
Alter_inplace_info::ALTER_COLUMN_DEFAULT |
|
||||
Alter_inplace_info::CHANGE_CREATE_OPTION |
|
||||
Alter_inplace_info::ALTER_RENAME;
|
||||
|
||||
/* Is there at least one operation that requires copy algorithm? */
|
||||
if (ha_alter_info->handler_flags & ~inplace_offline_operations)
|
||||
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
|
||||
|
||||
/*
|
||||
ALTER TABLE tbl_name CONVERT TO CHARACTER SET .. and
|
||||
ALTER TABLE table_name DEFAULT CHARSET = .. most likely
|
||||
change column charsets and so not supported in-place through
|
||||
old API.
|
||||
|
||||
Changing of PACK_KEYS, MAX_ROWS and ROW_FORMAT options were
|
||||
not supported as in-place operations in old API either.
|
||||
*/
|
||||
if (create_info->used_fields & (HA_CREATE_USED_CHARSET |
|
||||
HA_CREATE_USED_DEFAULT_CHARSET |
|
||||
HA_CREATE_USED_PACK_KEYS |
|
||||
HA_CREATE_USED_MAX_ROWS) ||
|
||||
(table->s->row_type != create_info->row_type))
|
||||
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
|
||||
|
||||
uint table_changes= (ha_alter_info->handler_flags &
|
||||
Alter_inplace_info::ALTER_COLUMN_EQUAL_PACK_LENGTH) ?
|
||||
IS_EQUAL_PACK_LENGTH : IS_EQUAL_YES;
|
||||
if (table->file->check_if_incompatible_data(create_info, table_changes)
|
||||
== COMPATIBLE_DATA_YES)
|
||||
DBUG_RETURN(HA_ALTER_INPLACE_EXCLUSIVE_LOCK);
|
||||
|
||||
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Default implementation to support in-place alter table
|
||||
and old online add/drop index API
|
||||
*/
|
||||
|
||||
void handler::notify_table_changed()
|
||||
{
|
||||
ha_create_handler_files(table->s->path.str, NULL, CHF_INDEX_FLAG, NULL);
|
||||
}
|
||||
|
||||
|
||||
void Alter_inplace_info::report_unsupported_error(const char *not_supported,
|
||||
const char *try_instead)
|
||||
{
|
||||
if (unsupported_reason == NULL)
|
||||
my_error(ER_ALTER_OPERATION_NOT_SUPPORTED, MYF(0),
|
||||
not_supported, try_instead);
|
||||
else
|
||||
my_error(ER_ALTER_OPERATION_NOT_SUPPORTED_REASON, MYF(0),
|
||||
not_supported, unsupported_reason, try_instead);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -3925,6 +4094,7 @@ handler::ha_prepare_for_alter()
|
|||
int
|
||||
handler::ha_rename_table(const char *from, const char *to)
|
||||
{
|
||||
DBUG_ASSERT(m_lock_type == F_UNLCK);
|
||||
mark_trx_read_write();
|
||||
|
||||
return rename_table(from, to);
|
||||
|
|
@ -3958,6 +4128,7 @@ handler::ha_delete_table(const char *name)
|
|||
void
|
||||
handler::ha_drop_table(const char *name)
|
||||
{
|
||||
DBUG_ASSERT(m_lock_type == F_UNLCK);
|
||||
mark_trx_read_write();
|
||||
|
||||
return drop_table(name);
|
||||
|
|
@ -3973,6 +4144,7 @@ handler::ha_drop_table(const char *name)
|
|||
int
|
||||
handler::ha_create(const char *name, TABLE *form, HA_CREATE_INFO *info)
|
||||
{
|
||||
DBUG_ASSERT(m_lock_type == F_UNLCK);
|
||||
mark_trx_read_write();
|
||||
|
||||
return create(name, form, info);
|
||||
|
|
@ -3989,6 +4161,13 @@ int
|
|||
handler::ha_create_handler_files(const char *name, const char *old_name,
|
||||
int action_flag, HA_CREATE_INFO *info)
|
||||
{
|
||||
/*
|
||||
Normally this is done when unlocked, but in fast_alter_partition_table,
|
||||
it is done on an already locked handler when preparing to alter/rename
|
||||
partitions.
|
||||
*/
|
||||
DBUG_ASSERT(m_lock_type == F_UNLCK ||
|
||||
(!old_name && strcmp(name, table_share->path.str)));
|
||||
mark_trx_read_write();
|
||||
|
||||
return create_handler_files(name, old_name, action_flag, info);
|
||||
|
|
@ -4008,7 +4187,13 @@ handler::ha_change_partitions(HA_CREATE_INFO *create_info,
|
|||
ulonglong * const deleted,
|
||||
const uchar *pack_frm_data,
|
||||
size_t pack_frm_len)
|
||||
{
|
||||
{ /*
|
||||
Must have at least RDLCK or be a TMP table. Read lock is needed to read
|
||||
from current partitions and write lock will be taken on new partitions.
|
||||
*/
|
||||
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
|
||||
m_lock_type != F_UNLCK);
|
||||
|
||||
mark_trx_read_write();
|
||||
|
||||
return change_partitions(create_info, path, copied, deleted,
|
||||
|
|
@ -4025,6 +4210,8 @@ handler::ha_change_partitions(HA_CREATE_INFO *create_info,
|
|||
int
|
||||
handler::ha_drop_partitions(const char *path)
|
||||
{
|
||||
DBUG_ASSERT(!table->db_stat);
|
||||
|
||||
mark_trx_read_write();
|
||||
|
||||
return drop_partitions(path);
|
||||
|
|
@ -4040,6 +4227,8 @@ handler::ha_drop_partitions(const char *path)
|
|||
int
|
||||
handler::ha_rename_partitions(const char *path)
|
||||
{
|
||||
DBUG_ASSERT(!table->db_stat);
|
||||
|
||||
mark_trx_read_write();
|
||||
|
||||
return rename_partitions(path);
|
||||
|
|
@ -5345,6 +5534,12 @@ int handler::ha_external_lock(THD *thd, int lock_type)
|
|||
taken a table lock), ha_release_auto_increment() was too.
|
||||
*/
|
||||
DBUG_ASSERT(next_insert_id == 0);
|
||||
/* Consecutive calls for lock without unlocking in between is not allowed */
|
||||
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
|
||||
((lock_type != F_UNLCK && m_lock_type == F_UNLCK) ||
|
||||
lock_type == F_UNLCK));
|
||||
/* SQL HANDLER call locks/unlock while scanning (RND/INDEX). */
|
||||
DBUG_ASSERT(inited == NONE || table->open_by_handler);
|
||||
|
||||
if (MYSQL_HANDLER_RDLOCK_START_ENABLED() ||
|
||||
MYSQL_HANDLER_WRLOCK_START_ENABLED() ||
|
||||
|
|
@ -5377,7 +5572,14 @@ int handler::ha_external_lock(THD *thd, int lock_type)
|
|||
{ error= external_lock(thd, lock_type); })
|
||||
|
||||
if (error == 0)
|
||||
{
|
||||
/*
|
||||
The lock type is needed by MRR when creating a clone of this handler
|
||||
object and for assert checking.
|
||||
*/
|
||||
m_lock_type= lock_type;
|
||||
cached_table_flags= table_flags();
|
||||
}
|
||||
|
||||
if (MYSQL_HANDLER_RDLOCK_DONE_ENABLED() ||
|
||||
MYSQL_HANDLER_WRLOCK_DONE_ENABLED() ||
|
||||
|
|
@ -5430,6 +5632,8 @@ int handler::ha_write_row(uchar *buf)
|
|||
{
|
||||
int error;
|
||||
Log_func *log_func= Write_rows_log_event::binlog_row_logging_function;
|
||||
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
|
||||
m_lock_type == F_WRLCK);
|
||||
DBUG_ENTER("handler::ha_write_row");
|
||||
DEBUG_SYNC_C("ha_write_row_start");
|
||||
|
||||
|
|
@ -5456,6 +5660,8 @@ int handler::ha_update_row(const uchar *old_data, uchar *new_data)
|
|||
{
|
||||
int error;
|
||||
Log_func *log_func= Update_rows_log_event::binlog_row_logging_function;
|
||||
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
|
||||
m_lock_type == F_WRLCK);
|
||||
|
||||
/*
|
||||
Some storage engines require that the new record is in record[0]
|
||||
|
|
@ -5483,6 +5689,8 @@ int handler::ha_delete_row(const uchar *buf)
|
|||
{
|
||||
int error;
|
||||
Log_func *log_func= Delete_rows_log_event::binlog_row_logging_function;
|
||||
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
|
||||
m_lock_type == F_WRLCK);
|
||||
|
||||
MYSQL_DELETE_ROW_START(table_share->db.str, table_share->table_name.str);
|
||||
mark_trx_read_write();
|
||||
|
|
@ -5513,6 +5721,77 @@ void handler::use_hidden_primary_key()
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
Get an initialized ha_share.
|
||||
|
||||
@return Initialized ha_share
|
||||
@retval NULL ha_share is not yet initialized.
|
||||
@retval != NULL previous initialized ha_share.
|
||||
|
||||
@note
|
||||
If not a temp table, then LOCK_ha_data must be held.
|
||||
*/
|
||||
|
||||
Handler_share *handler::get_ha_share_ptr()
|
||||
{
|
||||
DBUG_ENTER("handler::get_ha_share_ptr");
|
||||
DBUG_ASSERT(ha_share && table_share);
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
if (table_share->tmp_table == NO_TMP_TABLE)
|
||||
mysql_mutex_assert_owner(&table_share->LOCK_ha_data);
|
||||
#endif
|
||||
|
||||
DBUG_RETURN(*ha_share);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Set ha_share to be used by all instances of the same table/partition.
|
||||
|
||||
@param ha_share Handler_share to be shared.
|
||||
|
||||
@note
|
||||
If not a temp table, then LOCK_ha_data must be held.
|
||||
*/
|
||||
|
||||
void handler::set_ha_share_ptr(Handler_share *arg_ha_share)
|
||||
{
|
||||
DBUG_ENTER("handler::set_ha_share_ptr");
|
||||
DBUG_ASSERT(ha_share);
|
||||
#ifndef DBUG_OFF
|
||||
if (table_share->tmp_table == NO_TMP_TABLE)
|
||||
mysql_mutex_assert_owner(&table_share->LOCK_ha_data);
|
||||
#endif
|
||||
|
||||
*ha_share= arg_ha_share;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Take a lock for protecting shared handler data.
|
||||
*/
|
||||
|
||||
void handler::lock_shared_ha_data()
|
||||
{
|
||||
DBUG_ASSERT(table_share);
|
||||
if (table_share->tmp_table == NO_TMP_TABLE)
|
||||
mysql_mutex_lock(&table_share->LOCK_ha_data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Release lock for protecting ha_share.
|
||||
*/
|
||||
|
||||
void handler::unlock_shared_ha_data()
|
||||
{
|
||||
DBUG_ASSERT(table_share);
|
||||
if (table_share->tmp_table == NO_TMP_TABLE)
|
||||
mysql_mutex_unlock(&table_share->LOCK_ha_data);
|
||||
}
|
||||
|
||||
/** @brief
|
||||
Dummy function which accept information about log files which is not need
|
||||
by handlers
|
||||
|
|
|
|||
487
sql/handler.h
487
sql/handler.h
|
|
@ -404,6 +404,13 @@ enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED,
|
|||
/** Unused. Reserved for future versions. */
|
||||
ROW_TYPE_PAGE };
|
||||
|
||||
/* Specifies data storage format for individual columns */
|
||||
enum column_format_type {
|
||||
COLUMN_FORMAT_TYPE_DEFAULT= 0, /* Not specified (use engine default) */
|
||||
COLUMN_FORMAT_TYPE_FIXED= 1, /* FIXED format */
|
||||
COLUMN_FORMAT_TYPE_DYNAMIC= 2 /* DYNAMIC format */
|
||||
};
|
||||
|
||||
enum enum_binlog_func {
|
||||
BFN_RESET_LOGS= 1,
|
||||
BFN_RESET_SLAVE= 2,
|
||||
|
|
@ -1243,6 +1250,7 @@ inline LEX_STRING *hton_name(const handlerton *hton)
|
|||
#define HTON_ALTER_NOT_SUPPORTED (1 << 1) //Engine does not support alter
|
||||
#define HTON_CAN_RECREATE (1 << 2) //Delete all is used for truncate
|
||||
#define HTON_HIDDEN (1 << 3) //Engine does not appear in lists
|
||||
#define HTON_FLUSH_AFTER_RENAME (1 << 4)
|
||||
#define HTON_NOT_USER_SELECTABLE (1 << 5)
|
||||
#define HTON_TEMPORARY_NOT_SUPPORTED (1 << 6) //Having temporary tables not supported
|
||||
#define HTON_SUPPORT_LOG_TABLES (1 << 7) //Engine supports log tables
|
||||
|
|
@ -1304,6 +1312,22 @@ struct THD_TRANS
|
|||
void reset() { no_2pc= FALSE; modified_non_trans_table= FALSE; }
|
||||
bool is_empty() const { return ha_list == NULL; }
|
||||
THD_TRANS() {} /* Remove gcc warning */
|
||||
|
||||
unsigned int m_unsafe_rollback_flags;
|
||||
/*
|
||||
Define the type of statemens which cannot be rolled back safely.
|
||||
Each type occupies one bit in m_unsafe_rollback_flags.
|
||||
*/
|
||||
static unsigned int const MODIFIED_NON_TRANS_TABLE= 0x01;
|
||||
static unsigned int const CREATED_TEMP_TABLE= 0x02;
|
||||
static unsigned int const DROPPED_TEMP_TABLE= 0x04;
|
||||
|
||||
void mark_created_temp_table()
|
||||
{
|
||||
DBUG_PRINT("debug", ("mark_created_temp_table"));
|
||||
m_unsafe_rollback_flags|= CREATED_TEMP_TABLE;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -1427,7 +1451,6 @@ struct st_table_log_memory_entry;
|
|||
class partition_info;
|
||||
|
||||
struct st_partition_iter;
|
||||
#define NOT_A_PARTITION_ID ((uint32)-1)
|
||||
|
||||
enum ha_choice { HA_CHOICE_UNDEF, HA_CHOICE_NO, HA_CHOICE_YES };
|
||||
|
||||
|
|
@ -1438,6 +1461,7 @@ enum enum_stats_auto_recalc { HA_STATS_AUTO_RECALC_DEFAULT= 0,
|
|||
typedef struct st_ha_create_information
|
||||
{
|
||||
CHARSET_INFO *table_charset, *default_table_charset;
|
||||
LEX_CUSTRING tabledef_version;
|
||||
LEX_STRING connect_string;
|
||||
const char *password, *tablespace;
|
||||
LEX_STRING comment;
|
||||
|
|
@ -1445,7 +1469,7 @@ typedef struct st_ha_create_information
|
|||
const char *alias;
|
||||
ulonglong max_rows,min_rows;
|
||||
ulonglong auto_increment_value;
|
||||
ulong table_options;
|
||||
ulong table_options; ///< HA_OPTION_ values
|
||||
ulong avg_row_length;
|
||||
ulong used_fields;
|
||||
ulong key_block_size;
|
||||
|
|
@ -1469,18 +1493,21 @@ typedef struct st_ha_create_information
|
|||
uint merge_insert_method;
|
||||
uint extra_size; /* length of extra data segment */
|
||||
enum ha_choice transactional;
|
||||
bool frm_only; ///< 1 if no ha_create_table()
|
||||
bool varchar; ///< 1 if table has a VARCHAR
|
||||
enum ha_storage_media storage_media; ///< DEFAULT, DISK or MEMORY
|
||||
enum ha_choice page_checksum; ///< If we have page_checksums
|
||||
engine_option_value *option_list; ///< list of table create options
|
||||
|
||||
/* the following three are only for ALTER TABLE, check_if_incompatible_data() */
|
||||
ha_table_option_struct *option_struct; ///< structure with parsed table options
|
||||
ha_field_option_struct **fields_option_struct; ///< array of field option structures
|
||||
ha_index_option_struct **indexes_option_struct; ///< array of index option structures
|
||||
|
||||
bool tmp_table() { return options & HA_LEX_CREATE_TMP_TABLE; }
|
||||
} HA_CREATE_INFO;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
In-place alter handler context.
|
||||
|
||||
|
|
@ -2182,34 +2209,61 @@ uint calculate_key_len(TABLE *, uint, const uchar *, key_part_map);
|
|||
#define make_prev_keypart_map(N) (((key_part_map)1 << (N)) - 1)
|
||||
|
||||
|
||||
/**
|
||||
Index creation context.
|
||||
Created by handler::add_index() and destroyed by handler::final_add_index().
|
||||
And finally freed at the end of the statement.
|
||||
(Sql_alloc does not free in delete).
|
||||
*/
|
||||
|
||||
class handler_add_index : public Sql_alloc
|
||||
/** Base class to be used by handlers different shares */
|
||||
class Handler_share
|
||||
{
|
||||
public:
|
||||
/* Table where the indexes are added */
|
||||
TABLE* const table;
|
||||
/* Indexes being created */
|
||||
KEY* const key_info;
|
||||
/* Size of key_info[] */
|
||||
const uint num_of_keys;
|
||||
handler_add_index(TABLE *table_arg, KEY *key_info_arg, uint num_of_keys_arg)
|
||||
: table (table_arg), key_info (key_info_arg), num_of_keys (num_of_keys_arg)
|
||||
{}
|
||||
virtual ~handler_add_index() {}
|
||||
Handler_share() {}
|
||||
virtual ~Handler_share() {}
|
||||
};
|
||||
|
||||
class Query_cache;
|
||||
struct Query_cache_block_table;
|
||||
|
||||
/**
|
||||
The handler class is the interface for dynamically loadable
|
||||
storage engines. Do not add ifdefs and take care when adding or
|
||||
changing virtual functions to avoid vtable confusion
|
||||
|
||||
Functions in this class accept and return table columns data. Two data
|
||||
representation formats are used:
|
||||
1. TableRecordFormat - Used to pass [partial] table records to/from
|
||||
storage engine
|
||||
|
||||
2. KeyTupleFormat - used to pass index search tuples (aka "keys") to
|
||||
storage engine. See opt_range.cc for description of this format.
|
||||
|
||||
TableRecordFormat
|
||||
=================
|
||||
[Warning: this description is work in progress and may be incomplete]
|
||||
The table record is stored in a fixed-size buffer:
|
||||
|
||||
record: null_bytes, column1_data, column2_data, ...
|
||||
|
||||
The offsets of the parts of the buffer are also fixed: every column has
|
||||
an offset to its column{i}_data, and if it is nullable it also has its own
|
||||
bit in null_bytes.
|
||||
|
||||
The record buffer only includes data about columns that are marked in the
|
||||
relevant column set (table->read_set and/or table->write_set, depending on
|
||||
the situation).
|
||||
<not-sure>It could be that it is required that null bits of non-present
|
||||
columns are set to 1</not-sure>
|
||||
|
||||
VARIOUS EXCEPTIONS AND SPECIAL CASES
|
||||
|
||||
If the table has no nullable columns, then null_bytes is still
|
||||
present, its length is one byte <not-sure> which must be set to 0xFF
|
||||
at all times. </not-sure>
|
||||
|
||||
If the table has columns of type BIT, then certain bits from those columns
|
||||
may be stored in null_bytes as well. Grep around for Field_bit for
|
||||
details.
|
||||
|
||||
For blob columns (see Field_blob), the record buffer stores length of the
|
||||
data, following by memory pointer to the blob data. The pointer is owned
|
||||
by the storage engine and is valid until the next operation.
|
||||
|
||||
If a blob column has NULL value, then its length and blob data pointer
|
||||
must be set to 0.
|
||||
*/
|
||||
|
||||
class handler :public Sql_alloc
|
||||
|
|
@ -2262,7 +2316,6 @@ public:
|
|||
uint ref_length;
|
||||
FT_INFO *ft_handler;
|
||||
enum {NONE=0, INDEX, RND} inited;
|
||||
bool locked;
|
||||
bool implicit_emptied; /* Can be !=0 only if HEAP */
|
||||
bool mark_trx_done;
|
||||
const COND *pushed_cond;
|
||||
|
|
@ -2323,6 +2376,21 @@ public:
|
|||
virtual void unbind_psi();
|
||||
virtual void rebind_psi();
|
||||
|
||||
private:
|
||||
/**
|
||||
The lock type set by when calling::ha_external_lock(). This is
|
||||
propagated down to the storage engine. The reason for also storing
|
||||
it here, is that when doing MRR we need to create/clone a second handler
|
||||
object. This cloned handler object needs to know about the lock_type used.
|
||||
*/
|
||||
int m_lock_type;
|
||||
/**
|
||||
Pointer where to store/retrieve the Handler_share pointer.
|
||||
For non partitioned handlers this is &TABLE_SHARE::ha_share.
|
||||
*/
|
||||
Handler_share **ha_share;
|
||||
|
||||
public:
|
||||
handler(handlerton *ht_arg, TABLE_SHARE *share_arg)
|
||||
:table_share(share_arg), table(0),
|
||||
estimation_rows_to_insert(0), ht(ht_arg),
|
||||
|
|
@ -2330,18 +2398,21 @@ public:
|
|||
in_range_check_pushed_down(FALSE),
|
||||
ref_length(sizeof(my_off_t)),
|
||||
ft_handler(0), inited(NONE),
|
||||
locked(FALSE), implicit_emptied(0), mark_trx_done(FALSE),
|
||||
implicit_emptied(0), mark_trx_done(FALSE),
|
||||
pushed_cond(0), next_insert_id(0), insert_id_for_cur_row(0),
|
||||
pushed_idx_cond(NULL),
|
||||
pushed_idx_cond_keyno(MAX_KEY),
|
||||
auto_inc_intervals_count(0),
|
||||
m_psi(NULL)
|
||||
m_psi(NULL), m_lock_type(F_UNLCK), ha_share(NULL)
|
||||
{
|
||||
DBUG_PRINT("info",
|
||||
("handler created F_UNLCK %d F_RDLCK %d F_WRLCK %d",
|
||||
F_UNLCK, F_RDLCK, F_WRLCK));
|
||||
reset_statistics();
|
||||
}
|
||||
virtual ~handler(void)
|
||||
{
|
||||
DBUG_ASSERT(locked == FALSE);
|
||||
DBUG_ASSERT(m_lock_type == F_UNLCK);
|
||||
DBUG_ASSERT(inited == NONE);
|
||||
}
|
||||
virtual handler *clone(const char *name, MEM_ROOT *mem_root);
|
||||
|
|
@ -2456,7 +2527,6 @@ public:
|
|||
int ha_disable_indexes(uint mode);
|
||||
int ha_enable_indexes(uint mode);
|
||||
int ha_discard_or_import_tablespace(my_bool discard);
|
||||
void ha_prepare_for_alter();
|
||||
int ha_rename_table(const char *from, const char *to);
|
||||
int ha_delete_table(const char *name);
|
||||
void ha_drop_table(const char *name);
|
||||
|
|
@ -2756,6 +2826,7 @@ private:
|
|||
*/
|
||||
virtual int rnd_pos_by_record(uchar *record)
|
||||
{
|
||||
DBUG_ASSERT(table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION);
|
||||
position(record);
|
||||
return rnd_pos(record, ref);
|
||||
}
|
||||
|
|
@ -2871,10 +2942,15 @@ public:
|
|||
{ return FALSE; }
|
||||
virtual char* get_foreign_key_create_info()
|
||||
{ return(NULL);} /* gets foreign key create string from InnoDB */
|
||||
virtual char* get_tablespace_name(THD *thd, char *name, uint name_len)
|
||||
{ return(NULL);} /* gets tablespace name from handler */
|
||||
/** used in ALTER TABLE; 1 if changing storage engine is allowed */
|
||||
virtual bool can_switch_engines() { return 1; }
|
||||
/**
|
||||
Used in ALTER TABLE to check if changing storage engine is allowed.
|
||||
|
||||
@note Called without holding thr_lock.c lock.
|
||||
|
||||
@retval true Changing storage engine is allowed.
|
||||
@retval false Changing storage engine not allowed.
|
||||
*/
|
||||
virtual bool can_switch_engines() { return true; }
|
||||
virtual int can_continue_handler_scan() { return 0; }
|
||||
/**
|
||||
Get the list of foreign keys in this table.
|
||||
|
|
@ -2936,42 +3012,6 @@ public:
|
|||
|
||||
virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0;
|
||||
|
||||
/**
|
||||
First phase of in-place add index.
|
||||
Handlers are supposed to create new indexes here but not make them
|
||||
visible.
|
||||
|
||||
@param table_arg Table to add index to
|
||||
@param key_info Information about new indexes
|
||||
@param num_of_key Number of new indexes
|
||||
@param add[out] Context of handler specific information needed
|
||||
for final_add_index().
|
||||
|
||||
@note This function can be called with less than exclusive metadata
|
||||
lock depending on which flags are listed in alter_table_flags.
|
||||
*/
|
||||
virtual int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys,
|
||||
handler_add_index **add)
|
||||
{ return (HA_ERR_WRONG_COMMAND); }
|
||||
|
||||
/**
|
||||
Second and last phase of in-place add index.
|
||||
Commit or rollback pending new indexes.
|
||||
|
||||
@param add Context of handler specific information from add_index().
|
||||
@param commit If true, commit. If false, rollback index changes.
|
||||
|
||||
@note This function is called with exclusive metadata lock.
|
||||
*/
|
||||
virtual int final_add_index(handler_add_index *add, bool commit)
|
||||
{ return (HA_ERR_WRONG_COMMAND); }
|
||||
|
||||
virtual int prepare_drop_index(TABLE *table_arg, uint *key_num,
|
||||
uint num_of_keys)
|
||||
{ return (HA_ERR_WRONG_COMMAND); }
|
||||
virtual int final_drop_index(TABLE *table_arg)
|
||||
{ return (HA_ERR_WRONG_COMMAND); }
|
||||
|
||||
uint max_record_length() const
|
||||
{ return MY_MIN(HA_MAX_REC_LENGTH, max_supported_record_length()); }
|
||||
uint max_keys() const
|
||||
|
|
@ -3179,10 +3219,266 @@ public:
|
|||
pushed_idx_cond_keyno= MAX_KEY;
|
||||
in_range_check_pushed_down= false;
|
||||
}
|
||||
/**
|
||||
Part of old, deprecated in-place ALTER API.
|
||||
*/
|
||||
virtual bool check_if_incompatible_data(HA_CREATE_INFO *create_info,
|
||||
uint table_changes)
|
||||
{ return COMPATIBLE_DATA_NO; }
|
||||
|
||||
/* On-line/in-place ALTER TABLE interface. */
|
||||
|
||||
/*
|
||||
Here is an outline of on-line/in-place ALTER TABLE execution through
|
||||
this interface.
|
||||
|
||||
Phase 1 : Initialization
|
||||
========================
|
||||
During this phase we determine which algorithm should be used
|
||||
for execution of ALTER TABLE and what level concurrency it will
|
||||
require.
|
||||
|
||||
*) This phase starts by opening the table and preparing description
|
||||
of the new version of the table.
|
||||
*) Then we check if it is impossible even in theory to carry out
|
||||
this ALTER TABLE using the in-place algorithm. For example, because
|
||||
we need to change storage engine or the user has explicitly requested
|
||||
usage of the "copy" algorithm.
|
||||
*) If in-place ALTER TABLE is theoretically possible, we continue
|
||||
by compiling differences between old and new versions of the table
|
||||
in the form of HA_ALTER_FLAGS bitmap. We also build a few
|
||||
auxiliary structures describing requested changes and store
|
||||
all these data in the Alter_inplace_info object.
|
||||
*) Then the handler::check_if_supported_inplace_alter() method is called
|
||||
in order to find if the storage engine can carry out changes requested
|
||||
by this ALTER TABLE using the in-place algorithm. To determine this,
|
||||
the engine can rely on data in HA_ALTER_FLAGS/Alter_inplace_info
|
||||
passed to it as well as on its own checks. If the in-place algorithm
|
||||
can be used for this ALTER TABLE, the level of required concurrency for
|
||||
its execution is also returned.
|
||||
If any errors occur during the handler call, ALTER TABLE is aborted
|
||||
and no further handler functions are called.
|
||||
*) Locking requirements of the in-place algorithm are compared to any
|
||||
concurrency requirements specified by user. If there is a conflict
|
||||
between them, we either switch to the copy algorithm or emit an error.
|
||||
|
||||
Phase 2 : Execution
|
||||
===================
|
||||
|
||||
In this phase the operations are executed.
|
||||
|
||||
*) As the first step, we acquire a lock corresponding to the concurrency
|
||||
level which was returned by handler::check_if_supported_inplace_alter()
|
||||
and requested by the user. This lock is held for most of the
|
||||
duration of in-place ALTER (if HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE
|
||||
or HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE were returned we acquire an
|
||||
exclusive lock for duration of the next step only).
|
||||
*) After that we call handler::ha_prepare_inplace_alter_table() to give the
|
||||
storage engine a chance to update its internal structures with a higher
|
||||
lock level than the one that will be used for the main step of algorithm.
|
||||
After that we downgrade the lock if it is necessary.
|
||||
*) After that, the main step of this phase and algorithm is executed.
|
||||
We call the handler::ha_inplace_alter_table() method, which carries out the
|
||||
changes requested by ALTER TABLE but does not makes them visible to other
|
||||
connections yet.
|
||||
*) We ensure that no other connection uses the table by upgrading our
|
||||
lock on it to exclusive.
|
||||
*) a) If the previous step succeeds, handler::ha_commit_inplace_alter_table() is
|
||||
called to allow the storage engine to do any final updates to its structures,
|
||||
to make all earlier changes durable and visible to other connections.
|
||||
b) If we have failed to upgrade lock or any errors have occured during the
|
||||
handler functions calls (including commit), we call
|
||||
handler::ha_commit_inplace_alter_table()
|
||||
to rollback all changes which were done during previous steps.
|
||||
|
||||
Phase 3 : Final
|
||||
===============
|
||||
|
||||
In this phase we:
|
||||
|
||||
*) Update SQL-layer data-dictionary by installing .FRM file for the new version
|
||||
of the table.
|
||||
*) Inform the storage engine about this change by calling the
|
||||
handler::ha_notify_table_changed() method.
|
||||
*) Destroy the Alter_inplace_info and handler_ctx objects.
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
Check if a storage engine supports a particular alter table in-place
|
||||
|
||||
@param altered_table TABLE object for new version of table.
|
||||
@param ha_alter_info Structure describing changes to be done
|
||||
by ALTER TABLE and holding data used
|
||||
during in-place alter.
|
||||
|
||||
@retval HA_ALTER_ERROR Unexpected error.
|
||||
@retval HA_ALTER_INPLACE_NOT_SUPPORTED Not supported, must use copy.
|
||||
@retval HA_ALTER_INPLACE_EXCLUSIVE_LOCK Supported, but requires X lock.
|
||||
@retval HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE
|
||||
Supported, but requires SNW lock
|
||||
during main phase. Prepare phase
|
||||
requires X lock.
|
||||
@retval HA_ALTER_INPLACE_SHARED_LOCK Supported, but requires SNW lock.
|
||||
@retval HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE
|
||||
Supported, concurrent reads/writes
|
||||
allowed. However, prepare phase
|
||||
requires X lock.
|
||||
@retval HA_ALTER_INPLACE_NO_LOCK Supported, concurrent
|
||||
reads/writes allowed.
|
||||
|
||||
@note The default implementation uses the old in-place ALTER API
|
||||
to determine if the storage engine supports in-place ALTER or not.
|
||||
|
||||
@note Called without holding thr_lock.c lock.
|
||||
*/
|
||||
virtual enum_alter_inplace_result
|
||||
check_if_supported_inplace_alter(TABLE *altered_table,
|
||||
Alter_inplace_info *ha_alter_info);
|
||||
|
||||
|
||||
/**
|
||||
Public functions wrapping the actual handler call.
|
||||
@see prepare_inplace_alter_table()
|
||||
*/
|
||||
bool ha_prepare_inplace_alter_table(TABLE *altered_table,
|
||||
Alter_inplace_info *ha_alter_info);
|
||||
|
||||
|
||||
/**
|
||||
Public function wrapping the actual handler call.
|
||||
@see inplace_alter_table()
|
||||
*/
|
||||
bool ha_inplace_alter_table(TABLE *altered_table,
|
||||
Alter_inplace_info *ha_alter_info)
|
||||
{
|
||||
return inplace_alter_table(altered_table, ha_alter_info);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Public function wrapping the actual handler call.
|
||||
Allows us to enforce asserts regardless of handler implementation.
|
||||
@see commit_inplace_alter_table()
|
||||
*/
|
||||
bool ha_commit_inplace_alter_table(TABLE *altered_table,
|
||||
Alter_inplace_info *ha_alter_info,
|
||||
bool commit);
|
||||
|
||||
|
||||
/**
|
||||
Public function wrapping the actual handler call.
|
||||
@see notify_table_changed()
|
||||
*/
|
||||
void ha_notify_table_changed()
|
||||
{
|
||||
notify_table_changed();
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
/**
|
||||
Allows the storage engine to update internal structures with concurrent
|
||||
writes blocked. If check_if_supported_inplace_alter() returns
|
||||
HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE or
|
||||
HA_ALTER_INPLACE_SHARED_AFTER_PREPARE, this function is called with
|
||||
exclusive lock otherwise the same level of locking as for
|
||||
inplace_alter_table() will be used.
|
||||
|
||||
@note Storage engines are responsible for reporting any errors by
|
||||
calling my_error()/print_error()
|
||||
|
||||
@note If this function reports error, commit_inplace_alter_table()
|
||||
will be called with commit= false.
|
||||
|
||||
@note For partitioning, failing to prepare one partition, means that
|
||||
commit_inplace_alter_table() will be called to roll back changes for
|
||||
all partitions. This means that commit_inplace_alter_table() might be
|
||||
called without prepare_inplace_alter_table() having been called first
|
||||
for a given partition.
|
||||
|
||||
@param altered_table TABLE object for new version of table.
|
||||
@param ha_alter_info Structure describing changes to be done
|
||||
by ALTER TABLE and holding data used
|
||||
during in-place alter.
|
||||
|
||||
@retval true Error
|
||||
@retval false Success
|
||||
*/
|
||||
virtual bool prepare_inplace_alter_table(TABLE *altered_table,
|
||||
Alter_inplace_info *ha_alter_info)
|
||||
{ return false; }
|
||||
|
||||
|
||||
/**
|
||||
Alter the table structure in-place with operations specified using HA_ALTER_FLAGS
|
||||
and Alter_inplace_info. The level of concurrency allowed during this
|
||||
operation depends on the return value from check_if_supported_inplace_alter().
|
||||
|
||||
@note Storage engines are responsible for reporting any errors by
|
||||
calling my_error()/print_error()
|
||||
|
||||
@note If this function reports error, commit_inplace_alter_table()
|
||||
will be called with commit= false.
|
||||
|
||||
@param altered_table TABLE object for new version of table.
|
||||
@param ha_alter_info Structure describing changes to be done
|
||||
by ALTER TABLE and holding data used
|
||||
during in-place alter.
|
||||
|
||||
@retval true Error
|
||||
@retval false Success
|
||||
*/
|
||||
virtual bool inplace_alter_table(TABLE *altered_table,
|
||||
Alter_inplace_info *ha_alter_info)
|
||||
{ return false; }
|
||||
|
||||
|
||||
/**
|
||||
Commit or rollback the changes made during prepare_inplace_alter_table()
|
||||
and inplace_alter_table() inside the storage engine.
|
||||
Note that in case of rollback the allowed level of concurrency during
|
||||
this operation will be the same as for inplace_alter_table() and thus
|
||||
might be higher than during prepare_inplace_alter_table(). (For example,
|
||||
concurrent writes were blocked during prepare, but might not be during
|
||||
rollback).
|
||||
|
||||
@note Storage engines are responsible for reporting any errors by
|
||||
calling my_error()/print_error()
|
||||
|
||||
@note If this function with commit= true reports error, it will be called
|
||||
again with commit= false.
|
||||
|
||||
@note In case of partitioning, this function might be called for rollback
|
||||
without prepare_inplace_alter_table() having been called first.
|
||||
@see prepare_inplace_alter_table().
|
||||
|
||||
@param altered_table TABLE object for new version of table.
|
||||
@param ha_alter_info Structure describing changes to be done
|
||||
by ALTER TABLE and holding data used
|
||||
during in-place alter.
|
||||
@param commit True => Commit, False => Rollback.
|
||||
|
||||
@retval true Error
|
||||
@retval false Success
|
||||
*/
|
||||
virtual bool commit_inplace_alter_table(TABLE *altered_table,
|
||||
Alter_inplace_info *ha_alter_info,
|
||||
bool commit)
|
||||
{ return false; }
|
||||
|
||||
|
||||
/**
|
||||
Notify the storage engine that the table structure (.FRM) has been updated.
|
||||
|
||||
@note No errors are allowed during notify_table_changed().
|
||||
*/
|
||||
virtual void notify_table_changed();
|
||||
|
||||
public:
|
||||
/* End of On-line/in-place ALTER TABLE interface. */
|
||||
|
||||
|
||||
/**
|
||||
use_hidden_primary_key() is called in case of an update/delete when
|
||||
(table_flags() and HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) is defined
|
||||
|
|
@ -3226,32 +3522,6 @@ protected:
|
|||
*/
|
||||
PSI_table_share *ha_table_share_psi(const TABLE_SHARE *share) const;
|
||||
|
||||
inline void psi_open()
|
||||
{
|
||||
DBUG_ASSERT(m_psi == NULL);
|
||||
DBUG_ASSERT(table_share != NULL);
|
||||
#ifdef HAVE_PSI_INTERFACE
|
||||
if (PSI_server)
|
||||
{
|
||||
PSI_table_share *share_psi= ha_table_share_psi(table_share);
|
||||
if (share_psi)
|
||||
m_psi= PSI_server->open_table(share_psi, this);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void psi_close()
|
||||
{
|
||||
#ifdef HAVE_PSI_INTERFACE
|
||||
if (PSI_server && m_psi)
|
||||
{
|
||||
PSI_server->close_table(m_psi);
|
||||
m_psi= NULL; /* instrumentation handle, invalid after close_table() */
|
||||
}
|
||||
#endif
|
||||
DBUG_ASSERT(m_psi == NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
Default rename_table() and delete_table() rename/delete files with a
|
||||
given name and extensions from bas_ext().
|
||||
|
|
@ -3301,6 +3571,14 @@ private:
|
|||
return HA_ERR_WRONG_COMMAND;
|
||||
}
|
||||
|
||||
/**
|
||||
Update a single row.
|
||||
|
||||
Note: If HA_ERR_FOUND_DUPP_KEY is returned, the handler must read
|
||||
all columns of the row so MySQL can create an error message. If
|
||||
the columns required for the error message are not read, the error
|
||||
message will contain garbage.
|
||||
*/
|
||||
virtual int update_row(const uchar *old_data __attribute__((unused)),
|
||||
uchar *new_data __attribute__((unused)))
|
||||
{
|
||||
|
|
@ -3364,9 +3642,12 @@ private:
|
|||
}
|
||||
virtual void start_bulk_insert(ha_rows rows, uint flags) {}
|
||||
virtual int end_bulk_insert() { return 0; }
|
||||
protected:
|
||||
virtual int index_read(uchar * buf, const uchar * key, uint key_len,
|
||||
enum ha_rkey_function find_flag)
|
||||
{ return HA_ERR_WRONG_COMMAND; }
|
||||
friend class ha_partition;
|
||||
public:
|
||||
/**
|
||||
This method is similar to update_row, however the handler doesn't need
|
||||
to execute the updates at this point in time. The handler can be certain
|
||||
|
|
@ -3451,7 +3732,16 @@ private:
|
|||
{ return HA_ERR_WRONG_COMMAND; }
|
||||
virtual int rename_partitions(const char *path)
|
||||
{ return HA_ERR_WRONG_COMMAND; }
|
||||
friend class ha_partition;
|
||||
virtual bool set_ha_share_ref(Handler_share **arg_ha_share)
|
||||
{
|
||||
DBUG_ASSERT(!ha_share);
|
||||
DBUG_ASSERT(arg_ha_share);
|
||||
if (ha_share || !arg_ha_share)
|
||||
return true;
|
||||
ha_share= arg_ha_share;
|
||||
return false;
|
||||
}
|
||||
int get_lock_type() const { return m_lock_type; }
|
||||
public:
|
||||
/* XXX to be removed, see ha_partition::partition_ht() */
|
||||
virtual handlerton *partition_ht() const
|
||||
|
|
@ -3460,6 +3750,11 @@ public:
|
|||
inline int ha_update_tmp_row(const uchar * old_data, uchar * new_data);
|
||||
|
||||
friend enum icp_result handler_index_cond_check(void* h_arg);
|
||||
protected:
|
||||
Handler_share *get_ha_share_ptr();
|
||||
void set_ha_share_ptr(Handler_share *arg_ha_share);
|
||||
void lock_shared_ha_data();
|
||||
void unlock_shared_ha_data();
|
||||
};
|
||||
|
||||
#include "multi_range_read.h"
|
||||
|
|
@ -3541,6 +3836,8 @@ int ha_discover(THD* thd, const char* dbname, const char* name,
|
|||
int ha_find_files(THD *thd,const char *db,const char *path,
|
||||
const char *wild, bool dir, List<LEX_STRING>* files);
|
||||
int ha_table_exists_in_engine(THD* thd, const char* db, const char* name);
|
||||
bool ha_check_if_supported_system_table(handlerton *hton, const char* db,
|
||||
const char* table_name);
|
||||
|
||||
/* key cache */
|
||||
extern "C" int ha_init_key_cache(const char *name, KEY_CACHE *key_cache, void *);
|
||||
|
|
|
|||
40
sql/item.cc
40
sql/item.cc
|
|
@ -341,7 +341,7 @@ my_decimal *Item::val_decimal_from_string(my_decimal *decimal_value)
|
|||
decimal_value) & E_DEC_BAD_NUM)
|
||||
{
|
||||
ErrConvString err(res);
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_TRUNCATED_WRONG_VALUE,
|
||||
ER(ER_TRUNCATED_WRONG_VALUE), "DECIMAL",
|
||||
err.ptr());
|
||||
|
|
@ -980,11 +980,11 @@ void Item::set_name(const char *str, uint length, CHARSET_INFO *cs)
|
|||
MY_MIN(sizeof(buff)-1, length + (int) (str-str_start)));
|
||||
|
||||
if (length == 0)
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_NAME_BECOMES_EMPTY, ER(ER_NAME_BECOMES_EMPTY),
|
||||
buff);
|
||||
else
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_REMOVED_SPACES, ER(ER_REMOVED_SPACES),
|
||||
buff);
|
||||
}
|
||||
|
|
@ -1126,12 +1126,27 @@ Item *Item_static_float_func::safe_charset_converter(CHARSET_INFO *tocs)
|
|||
|
||||
|
||||
Item *Item_string::safe_charset_converter(CHARSET_INFO *tocs)
|
||||
{
|
||||
return charset_converter(tocs, true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Convert a string item into the requested character set.
|
||||
|
||||
@param tocs Character set to to convert the string to.
|
||||
@param lossless Whether data loss is acceptable.
|
||||
|
||||
@return A new item representing the converted string.
|
||||
*/
|
||||
Item *Item_string::charset_converter(CHARSET_INFO *tocs, bool lossless)
|
||||
{
|
||||
Item_string *conv;
|
||||
uint conv_errors;
|
||||
char *ptr;
|
||||
String tmp, cstr, *ostr= val_str(&tmp);
|
||||
cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors);
|
||||
conv_errors= lossless && conv_errors;
|
||||
if (conv_errors || !(conv= new Item_string(cstr.ptr(), cstr.length(),
|
||||
cstr.charset(),
|
||||
collation.derivation)))
|
||||
|
|
@ -1152,7 +1167,6 @@ Item *Item_string::safe_charset_converter(CHARSET_INFO *tocs)
|
|||
return conv;
|
||||
}
|
||||
|
||||
|
||||
Item *Item_param::safe_charset_converter(CHARSET_INFO *tocs)
|
||||
{
|
||||
if (const_item())
|
||||
|
|
@ -2966,7 +2980,7 @@ double_from_string_with_check(CHARSET_INFO *cs, const char *cptr,
|
|||
We can use err.ptr() here as ErrConvString is guranteed to put an
|
||||
end \0 here.
|
||||
*/
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_TRUNCATED_WRONG_VALUE,
|
||||
ER(ER_TRUNCATED_WRONG_VALUE), "DOUBLE",
|
||||
err.ptr());
|
||||
|
|
@ -3003,7 +3017,7 @@ longlong_from_string_with_check(CHARSET_INFO *cs, const char *cptr,
|
|||
(end != end_of_num && !check_if_only_end_space(cs, end_of_num, end))))
|
||||
{
|
||||
ErrConvString err(cptr, end - cptr, cs);
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_TRUNCATED_WRONG_VALUE,
|
||||
ER(ER_TRUNCATED_WRONG_VALUE), "INTEGER",
|
||||
err.ptr());
|
||||
|
|
@ -3216,7 +3230,7 @@ void Item_param::set_time(MYSQL_TIME *tm, timestamp_type time_type,
|
|||
value.time.second_part > TIME_MAX_SECOND_PART)
|
||||
{
|
||||
ErrConvTime str(&value.time);
|
||||
make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
&str, time_type, 0);
|
||||
set_zero_time(&value.time, MYSQL_TIMESTAMP_ERROR);
|
||||
}
|
||||
|
|
@ -4293,7 +4307,7 @@ static bool mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current,
|
|||
return TRUE;
|
||||
if (thd->lex->describe & DESCRIBE_EXTENDED)
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
|
||||
ER_WARN_FIELD_RESOLVED, ER(ER_WARN_FIELD_RESOLVED),
|
||||
db_name, (db_name[0] ? "." : ""),
|
||||
table_name, (table_name [0] ? "." : ""),
|
||||
|
|
@ -4541,7 +4555,7 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select)
|
|||
!((*group_by_ref)->eq(*select_ref, 0)))
|
||||
{
|
||||
ambiguous_fields= TRUE;
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
|
||||
ER(ER_NON_UNIQ_ERROR), ref->full_name(),
|
||||
current_thd->where);
|
||||
|
||||
|
|
@ -5523,7 +5537,7 @@ String *Item::check_well_formed_result(String *str, bool send_error)
|
|||
{
|
||||
str->length(wlen);
|
||||
}
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_INVALID_CHARACTER_STRING,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_INVALID_CHARACTER_STRING,
|
||||
ER(ER_INVALID_CHARACTER_STRING), cs->csname, hexbuf);
|
||||
}
|
||||
return str;
|
||||
|
|
@ -6203,7 +6217,7 @@ int Item_hex_string::save_in_field(Field *field, bool no_conversions)
|
|||
|
||||
warn:
|
||||
if (!field->store((longlong) nr, TRUE))
|
||||
field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE,
|
||||
field->set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE,
|
||||
1);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -8134,7 +8148,7 @@ int Item_default_value::save_in_field(Field *field_arg, bool no_conversions)
|
|||
{
|
||||
TABLE_LIST *view= cached_table->top_table();
|
||||
push_warning_printf(field_arg->table->in_use,
|
||||
MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_NO_DEFAULT_FOR_VIEW_FIELD,
|
||||
ER(ER_NO_DEFAULT_FOR_VIEW_FIELD),
|
||||
view->view_db.str,
|
||||
|
|
@ -8143,7 +8157,7 @@ int Item_default_value::save_in_field(Field *field_arg, bool no_conversions)
|
|||
else
|
||||
{
|
||||
push_warning_printf(field_arg->table->in_use,
|
||||
MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_NO_DEFAULT_FOR_FIELD,
|
||||
ER(ER_NO_DEFAULT_FOR_FIELD),
|
||||
field_arg->field_name);
|
||||
|
|
|
|||
13
sql/item.h
13
sql/item.h
|
|
@ -1365,7 +1365,7 @@ public:
|
|||
virtual void bring_value() {}
|
||||
|
||||
Field *tmp_table_field_from_field_type(TABLE *table, bool fixed_length);
|
||||
virtual Item_field *filed_for_view_update() { return 0; }
|
||||
virtual Item_field *field_for_view_update() { return 0; }
|
||||
|
||||
virtual Item *neg_transformer(THD *thd) { return NULL; }
|
||||
virtual Item *update_value_transformer(uchar *select_arg) { return this; }
|
||||
|
|
@ -2079,7 +2079,7 @@ public:
|
|||
bool set_no_const_sub(uchar *arg);
|
||||
Item *replace_equal_field(uchar *arg);
|
||||
inline uint32 max_disp_length() { return field->max_display_length(); }
|
||||
Item_field *filed_for_view_update() { return this; }
|
||||
Item_field *field_for_view_update() { return this; }
|
||||
Item *safe_charset_converter(CHARSET_INFO *tocs);
|
||||
int fix_outer_field(THD *thd, Field **field, Item **reference);
|
||||
virtual Item *update_value_transformer(uchar *select_arg);
|
||||
|
|
@ -2570,6 +2570,7 @@ public:
|
|||
str_value.length(), collation.collation);
|
||||
}
|
||||
Item *safe_charset_converter(CHARSET_INFO *tocs);
|
||||
Item *charset_converter(CHARSET_INFO *tocs, bool lossless);
|
||||
inline void append(char *str, uint length)
|
||||
{
|
||||
str_value.append(str, length);
|
||||
|
|
@ -2914,8 +2915,8 @@ public:
|
|||
}
|
||||
virtual void print(String *str, enum_query_type query_type);
|
||||
void cleanup();
|
||||
Item_field *filed_for_view_update()
|
||||
{ return (*ref)->filed_for_view_update(); }
|
||||
Item_field *field_for_view_update()
|
||||
{ return (*ref)->field_for_view_update(); }
|
||||
virtual Ref_Type ref_type() { return REF; }
|
||||
|
||||
// Row emulation: forwarding of ROW-related calls to ref
|
||||
|
|
@ -3121,8 +3122,8 @@ public:
|
|||
}
|
||||
bool enumerate_field_refs_processor(uchar *arg)
|
||||
{ return orig_item->enumerate_field_refs_processor(arg); }
|
||||
Item_field *filed_for_view_update()
|
||||
{ return orig_item->filed_for_view_update(); }
|
||||
Item_field *field_for_view_update()
|
||||
{ return orig_item->field_for_view_update(); }
|
||||
|
||||
/* Row emulation: forwarding of ROW-related calls to orig_item */
|
||||
uint cols()
|
||||
|
|
|
|||
|
|
@ -746,7 +746,7 @@ bool get_mysql_time_from_str(THD *thd, String *str, timestamp_type warn_type,
|
|||
}
|
||||
|
||||
if (error > 0)
|
||||
make_truncated_value_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
make_truncated_value_warning(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
&err, warn_type, warn_name);
|
||||
|
||||
return value;
|
||||
|
|
|
|||
|
|
@ -2053,19 +2053,6 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
class Create_func_row_count : public Create_func_arg0
|
||||
{
|
||||
public:
|
||||
virtual Item *create_builder(THD *thd);
|
||||
|
||||
static Create_func_row_count s_singleton;
|
||||
|
||||
protected:
|
||||
Create_func_row_count() {}
|
||||
virtual ~Create_func_row_count() {}
|
||||
};
|
||||
|
||||
|
||||
class Create_func_rpad : public Create_func_arg3
|
||||
{
|
||||
public:
|
||||
|
|
@ -4795,18 +4782,6 @@ Create_func_round::create_native(THD *thd, LEX_STRING name,
|
|||
}
|
||||
|
||||
|
||||
Create_func_row_count Create_func_row_count::s_singleton;
|
||||
|
||||
Item*
|
||||
Create_func_row_count::create_builder(THD *thd)
|
||||
{
|
||||
DBUG_ENTER("Create_func_row_count::create");
|
||||
thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION);
|
||||
thd->lex->safe_to_cache_query= 0;
|
||||
DBUG_RETURN(new (thd->mem_root) Item_func_row_count());
|
||||
}
|
||||
|
||||
|
||||
Create_func_rpad Create_func_rpad::s_singleton;
|
||||
|
||||
Item*
|
||||
|
|
@ -5475,7 +5450,6 @@ static Native_func_registry func_array[] =
|
|||
{ { C_STRING_WITH_LEN("RELEASE_LOCK") }, BUILDER(Create_func_release_lock)},
|
||||
{ { C_STRING_WITH_LEN("REVERSE") }, BUILDER(Create_func_reverse)},
|
||||
{ { C_STRING_WITH_LEN("ROUND") }, BUILDER(Create_func_round)},
|
||||
{ { C_STRING_WITH_LEN("ROW_COUNT") }, BUILDER(Create_func_row_count)},
|
||||
{ { C_STRING_WITH_LEN("RPAD") }, BUILDER(Create_func_rpad)},
|
||||
{ { C_STRING_WITH_LEN("RTRIM") }, BUILDER(Create_func_rtrim)},
|
||||
{ { C_STRING_WITH_LEN("SEC_TO_TIME") }, BUILDER(Create_func_sec_to_time)},
|
||||
|
|
|
|||
|
|
@ -695,7 +695,7 @@ void Item_func::signal_divide_by_null()
|
|||
{
|
||||
THD *thd= current_thd;
|
||||
if (thd->variables.sql_mode & MODE_ERROR_FOR_DIVISION_BY_ZERO)
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_DIVISION_BY_ZERO,
|
||||
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, ER_DIVISION_BY_ZERO,
|
||||
ER(ER_DIVISION_BY_ZERO));
|
||||
null_value= 1;
|
||||
}
|
||||
|
|
@ -1030,7 +1030,7 @@ longlong Item_func_signed::val_int_from_str(int *error)
|
|||
char err_buff[128];
|
||||
String err_tmp(err_buff,(uint32) sizeof(err_buff), system_charset_info);
|
||||
err_tmp.copy(start, length, system_charset_info);
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_TRUNCATED_WRONG_VALUE,
|
||||
ER(ER_TRUNCATED_WRONG_VALUE), "INTEGER",
|
||||
err_tmp.c_ptr());
|
||||
|
|
@ -1067,7 +1067,7 @@ longlong Item_func_signed::val_int()
|
|||
return value;
|
||||
|
||||
err:
|
||||
push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_UNKNOWN_ERROR,
|
||||
push_warning(current_thd, Sql_condition::WARN_LEVEL_NOTE, ER_UNKNOWN_ERROR,
|
||||
"Cast to signed converted positive out-of-range integer to "
|
||||
"it's negative complement");
|
||||
return value;
|
||||
|
|
@ -1123,7 +1123,7 @@ longlong Item_func_unsigned::val_int()
|
|||
return value;
|
||||
|
||||
err:
|
||||
push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_UNKNOWN_ERROR,
|
||||
push_warning(current_thd, Sql_condition::WARN_LEVEL_NOTE, ER_UNKNOWN_ERROR,
|
||||
"Cast to unsigned converted negative integer to it's "
|
||||
"positive complement");
|
||||
return value;
|
||||
|
|
@ -1191,7 +1191,7 @@ my_decimal *Item_decimal_typecast::val_decimal(my_decimal *dec)
|
|||
return dec;
|
||||
|
||||
err:
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_DATA_OUT_OF_RANGE,
|
||||
ER(ER_WARN_DATA_OUT_OF_RANGE),
|
||||
name, 1L);
|
||||
|
|
@ -1233,7 +1233,7 @@ double Item_double_typecast::val_real()
|
|||
if ((error= truncate_double(&tmp, max_length, decimals, 0, DBL_MAX)))
|
||||
{
|
||||
push_warning_printf(current_thd,
|
||||
MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_DATA_OUT_OF_RANGE,
|
||||
ER(ER_WARN_DATA_OUT_OF_RANGE),
|
||||
name, 1);
|
||||
|
|
@ -3891,7 +3891,7 @@ longlong Item_master_pos_wait::val_int()
|
|||
connection_name= thd->variables.default_master_connection;
|
||||
|
||||
if (!(mi= master_info_index->get_master_info(&connection_name,
|
||||
MYSQL_ERROR::WARN_LEVEL_WARN)))
|
||||
Sql_condition::WARN_LEVEL_WARN)))
|
||||
goto err;
|
||||
if ((event_count = mi->rli.wait_for_pos(thd, log_name, pos, timeout)) == -2)
|
||||
{
|
||||
|
|
@ -4229,7 +4229,7 @@ longlong Item_func_benchmark::val_int()
|
|||
{
|
||||
char buff[22];
|
||||
llstr(((longlong) loop_count), buff);
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WRONG_VALUE_FOR_TYPE, ER(ER_WRONG_VALUE_FOR_TYPE),
|
||||
"count", buff, "benchmark");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -500,7 +500,7 @@ String *Item_func_spatial_collection::val_str(String *str)
|
|||
}
|
||||
if (str->length() > current_thd->variables.max_allowed_packet)
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_ALLOWED_PACKET_OVERFLOWED,
|
||||
ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
|
||||
func_name(), current_thd->variables.max_allowed_packet);
|
||||
|
|
|
|||
|
|
@ -282,9 +282,9 @@ String *Item_func_sha2::val_str_ascii(String *str)
|
|||
default:
|
||||
if (!args[1]->const_item())
|
||||
push_warning_printf(current_thd,
|
||||
MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_WRONG_PARAMETERS_TO_NATIVE_FCT,
|
||||
ER(ER_WRONG_PARAMETERS_TO_NATIVE_FCT), "sha2");
|
||||
Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WRONG_PARAMETERS_TO_NATIVE_FCT,
|
||||
ER(ER_WRONG_PARAMETERS_TO_NATIVE_FCT), "sha2");
|
||||
null_value= TRUE;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -306,7 +306,7 @@ String *Item_func_sha2::val_str_ascii(String *str)
|
|||
|
||||
#else
|
||||
push_warning_printf(current_thd,
|
||||
MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_FEATURE_DISABLED,
|
||||
ER(ER_FEATURE_DISABLED),
|
||||
"sha2", "--with-ssl");
|
||||
|
|
@ -344,7 +344,7 @@ void Item_func_sha2::fix_length_and_dec()
|
|||
#endif
|
||||
default:
|
||||
push_warning_printf(current_thd,
|
||||
MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WRONG_PARAMETERS_TO_NATIVE_FCT,
|
||||
ER(ER_WRONG_PARAMETERS_TO_NATIVE_FCT), "sha2");
|
||||
}
|
||||
|
|
@ -363,7 +363,7 @@ void Item_func_sha2::fix_length_and_dec()
|
|||
DERIVATION_COERCIBLE);
|
||||
#else
|
||||
push_warning_printf(current_thd,
|
||||
MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_FEATURE_DISABLED,
|
||||
ER(ER_FEATURE_DISABLED),
|
||||
"sha2", "--with-ssl");
|
||||
|
|
@ -489,7 +489,7 @@ String *Item_func_concat::val_str(String *str)
|
|||
if (res->length()+res2->length() >
|
||||
current_thd->variables.max_allowed_packet)
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_ALLOWED_PACKET_OVERFLOWED,
|
||||
ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), func_name(),
|
||||
current_thd->variables.max_allowed_packet);
|
||||
|
|
@ -695,11 +695,11 @@ String *Item_func_des_encrypt::val_str(String *str)
|
|||
return &tmp_value;
|
||||
|
||||
error:
|
||||
push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd,Sql_condition::WARN_LEVEL_WARN,
|
||||
code, ER(code),
|
||||
"des_encrypt");
|
||||
#else
|
||||
push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd,Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_FEATURE_DISABLED, ER(ER_FEATURE_DISABLED),
|
||||
"des_encrypt", "--with-ssl");
|
||||
#endif /* defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) */
|
||||
|
|
@ -773,12 +773,12 @@ String *Item_func_des_decrypt::val_str(String *str)
|
|||
return &tmp_value;
|
||||
|
||||
error:
|
||||
push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd,Sql_condition::WARN_LEVEL_WARN,
|
||||
code, ER(code),
|
||||
"des_decrypt");
|
||||
wrong_key:
|
||||
#else
|
||||
push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd,Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_FEATURE_DISABLED, ER(ER_FEATURE_DISABLED),
|
||||
"des_decrypt", "--with-ssl");
|
||||
#endif /* defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) */
|
||||
|
|
@ -829,7 +829,7 @@ String *Item_func_concat_ws::val_str(String *str)
|
|||
if (res->length() + sep_str->length() + res2->length() >
|
||||
current_thd->variables.max_allowed_packet)
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_ALLOWED_PACKET_OVERFLOWED,
|
||||
ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), func_name(),
|
||||
current_thd->variables.max_allowed_packet);
|
||||
|
|
@ -1088,7 +1088,7 @@ redo:
|
|||
if (res->length()-from_length + to_length >
|
||||
current_thd->variables.max_allowed_packet)
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_ALLOWED_PACKET_OVERFLOWED,
|
||||
ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
|
||||
func_name(),
|
||||
|
|
@ -1117,7 +1117,7 @@ skip:
|
|||
if (res->length()-from_length + to_length >
|
||||
current_thd->variables.max_allowed_packet)
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_ALLOWED_PACKET_OVERFLOWED,
|
||||
ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), func_name(),
|
||||
current_thd->variables.max_allowed_packet);
|
||||
|
|
@ -1204,7 +1204,7 @@ String *Item_func_insert::val_str(String *str)
|
|||
if ((ulonglong) (res->length() - length + res2->length()) >
|
||||
(ulonglong) current_thd->variables.max_allowed_packet)
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_ALLOWED_PACKET_OVERFLOWED,
|
||||
ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
|
||||
func_name(), current_thd->variables.max_allowed_packet);
|
||||
|
|
@ -2230,7 +2230,7 @@ MY_LOCALE *Item_func_format::get_locale(Item *item)
|
|||
if (!locale_name ||
|
||||
!(lc= my_locale_by_name(locale_name->c_ptr_safe())))
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_UNKNOWN_LOCALE,
|
||||
ER(ER_UNKNOWN_LOCALE),
|
||||
locale_name ? locale_name->c_ptr_safe() : "NULL");
|
||||
|
|
@ -2675,7 +2675,7 @@ String *Item_func_repeat::val_str(String *str)
|
|||
// Safe length check
|
||||
if (length > current_thd->variables.max_allowed_packet / (uint) count)
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_ALLOWED_PACKET_OVERFLOWED,
|
||||
ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
|
||||
func_name(), current_thd->variables.max_allowed_packet);
|
||||
|
|
@ -2768,7 +2768,7 @@ String *Item_func_rpad::val_str(String *str)
|
|||
byte_count= count * collation.collation->mbmaxlen;
|
||||
if ((ulonglong) byte_count > current_thd->variables.max_allowed_packet)
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_ALLOWED_PACKET_OVERFLOWED,
|
||||
ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
|
||||
func_name(), current_thd->variables.max_allowed_packet);
|
||||
|
|
@ -2876,7 +2876,7 @@ String *Item_func_lpad::val_str(String *str)
|
|||
|
||||
if ((ulonglong) byte_count > current_thd->variables.max_allowed_packet)
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_ALLOWED_PACKET_OVERFLOWED,
|
||||
ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
|
||||
func_name(), current_thd->variables.max_allowed_packet);
|
||||
|
|
@ -3254,7 +3254,7 @@ String *Item_load_file::val_str(String *str)
|
|||
}
|
||||
if (stat_info.st_size > (long) current_thd->variables.max_allowed_packet)
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_ALLOWED_PACKET_OVERFLOWED,
|
||||
ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
|
||||
func_name(), current_thd->variables.max_allowed_packet);
|
||||
|
|
@ -3345,7 +3345,7 @@ String* Item_func_export_set::val_str(String* str)
|
|||
|
||||
if (unlikely(max_total_length > max_allowed_packet))
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_ALLOWED_PACKET_OVERFLOWED,
|
||||
ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
|
||||
func_name(), max_allowed_packet);
|
||||
|
|
@ -3593,7 +3593,7 @@ longlong Item_func_uncompressed_length::val_int()
|
|||
*/
|
||||
if (res->length() <= 4)
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_ZLIB_Z_DATA_ERROR,
|
||||
ER(ER_ZLIB_Z_DATA_ERROR));
|
||||
null_value= 1;
|
||||
|
|
@ -3670,7 +3670,7 @@ String *Item_func_compress::val_str(String *str)
|
|||
res->length())) != Z_OK)
|
||||
{
|
||||
code= err==Z_MEM_ERROR ? ER_ZLIB_Z_MEM_ERROR : ER_ZLIB_Z_BUF_ERROR;
|
||||
push_warning(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN,code,ER(code));
|
||||
push_warning(current_thd,Sql_condition::WARN_LEVEL_WARN,code,ER(code));
|
||||
null_value= 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -3708,7 +3708,7 @@ String *Item_func_uncompress::val_str(String *str)
|
|||
/* If length is less than 4 bytes, data is corrupt */
|
||||
if (res->length() <= 4)
|
||||
{
|
||||
push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd,Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_ZLIB_Z_DATA_ERROR,
|
||||
ER(ER_ZLIB_Z_DATA_ERROR));
|
||||
goto err;
|
||||
|
|
@ -3718,7 +3718,7 @@ String *Item_func_uncompress::val_str(String *str)
|
|||
new_size= uint4korr(res->ptr()) & 0x3FFFFFFF;
|
||||
if (new_size > current_thd->variables.max_allowed_packet)
|
||||
{
|
||||
push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd,Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_TOO_BIG_FOR_UNCOMPRESS,
|
||||
ER(ER_TOO_BIG_FOR_UNCOMPRESS),
|
||||
static_cast<int>(current_thd->variables.
|
||||
|
|
@ -3737,7 +3737,7 @@ String *Item_func_uncompress::val_str(String *str)
|
|||
|
||||
code= ((err == Z_BUF_ERROR) ? ER_ZLIB_Z_BUF_ERROR :
|
||||
((err == Z_MEM_ERROR) ? ER_ZLIB_Z_MEM_ERROR : ER_ZLIB_Z_DATA_ERROR));
|
||||
push_warning(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN,code,ER(code));
|
||||
push_warning(current_thd,Sql_condition::WARN_LEVEL_WARN,code,ER(code));
|
||||
|
||||
err:
|
||||
null_value= 1;
|
||||
|
|
@ -4423,7 +4423,7 @@ longlong Item_dyncol_get::val_int()
|
|||
{
|
||||
char buff[30];
|
||||
sprintf(buff, "%lg", val.x.double_value);
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_DATA_OVERFLOW,
|
||||
ER(ER_DATA_OVERFLOW),
|
||||
buff,
|
||||
|
|
@ -4443,7 +4443,7 @@ longlong Item_dyncol_get::val_int()
|
|||
char buff[80];
|
||||
strmake(buff, val.x.string.value.str, MY_MIN(sizeof(buff)-1,
|
||||
val.x.string.value.length));
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_BAD_DATA,
|
||||
ER(ER_BAD_DATA),
|
||||
buff,
|
||||
|
|
@ -4507,7 +4507,7 @@ double Item_dyncol_get::val_real()
|
|||
char buff[80];
|
||||
strmake(buff, val.x.string.value.str, MY_MIN(sizeof(buff)-1,
|
||||
val.x.string.value.length));
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_BAD_DATA,
|
||||
ER(ER_BAD_DATA),
|
||||
buff, "DOUBLE");
|
||||
|
|
@ -4565,7 +4565,7 @@ my_decimal *Item_dyncol_get::val_decimal(my_decimal *decimal_value)
|
|||
val.x.string.value.length));
|
||||
if (rc != E_DEC_OK)
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_BAD_DATA,
|
||||
ER(ER_BAD_DATA),
|
||||
buff, "DECIMAL");
|
||||
|
|
|
|||
|
|
@ -897,7 +897,7 @@ public:
|
|||
Item_field *filed_for_view_update()
|
||||
{
|
||||
/* this function is transparent for view updating */
|
||||
return args[0]->filed_for_view_update();
|
||||
return args[0]->field_for_view_update();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1063,7 +1063,7 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
|
|||
{
|
||||
char warn_buff[MYSQL_ERRMSG_SIZE];
|
||||
sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
|
||||
ER_SELECT_REDUCED, warn_buff);
|
||||
}
|
||||
substitution= select_lex->item_list.head();
|
||||
|
|
@ -1727,7 +1727,7 @@ Item_in_subselect::single_value_transformer(JOIN *join)
|
|||
{
|
||||
char warn_buff[MYSQL_ERRMSG_SIZE];
|
||||
sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
|
||||
ER_SELECT_REDUCED, warn_buff);
|
||||
}
|
||||
DBUG_RETURN(false);
|
||||
|
|
|
|||
|
|
@ -3067,7 +3067,7 @@ int dump_leaf_key(void* key_arg, element_count count __attribute__((unused)),
|
|||
&well_formed_error);
|
||||
result->length(old_length + add_length);
|
||||
item->warning_for_row= TRUE;
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_CUT_VALUE_GROUP_CONCAT, ER(ER_CUT_VALUE_GROUP_CONCAT),
|
||||
item->row_count);
|
||||
|
||||
|
|
|
|||
|
|
@ -425,7 +425,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
|
|||
{
|
||||
if (!my_isspace(&my_charset_latin1,*val))
|
||||
{
|
||||
make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
val_begin, length,
|
||||
cached_timestamp_type, NullS);
|
||||
break;
|
||||
|
|
@ -438,7 +438,7 @@ err:
|
|||
{
|
||||
char buff[128];
|
||||
strmake(buff, val_begin, MY_MIN(length, sizeof(buff)-1));
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WRONG_VALUE_FOR_TYPE, ER(ER_WRONG_VALUE_FOR_TYPE),
|
||||
date_time_type, buff, "str_to_date");
|
||||
}
|
||||
|
|
@ -1721,7 +1721,7 @@ overflow:
|
|||
|
||||
ltime->hour= TIME_MAX_HOUR+1;
|
||||
check_time_range(ltime, decimals, &unused);
|
||||
make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
err->ptr(), err->length(),
|
||||
MYSQL_TIMESTAMP_TIME, NullS);
|
||||
return 0;
|
||||
|
|
@ -2270,7 +2270,7 @@ String *Item_char_typecast::val_str(String *str)
|
|||
if (cast_length != ~0U &&
|
||||
cast_length > current_thd->variables.max_allowed_packet)
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_ALLOWED_PACKET_OVERFLOWED,
|
||||
ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
|
||||
cast_cs == &my_charset_bin ?
|
||||
|
|
@ -2328,7 +2328,7 @@ String *Item_char_typecast::val_str(String *str)
|
|||
res= &str_value;
|
||||
}
|
||||
ErrConvString err(res);
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_TRUNCATED_WRONG_VALUE,
|
||||
ER(ER_TRUNCATED_WRONG_VALUE), char_type,
|
||||
err.ptr());
|
||||
|
|
@ -2350,7 +2350,7 @@ String *Item_char_typecast::val_str(String *str)
|
|||
|
||||
if (res->length() > current_thd->variables.max_allowed_packet)
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_ALLOWED_PACKET_OVERFLOWED,
|
||||
ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
|
||||
cast_cs == &my_charset_bin ?
|
||||
|
|
@ -2442,7 +2442,7 @@ bool Item_date_typecast::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
|
|||
fuzzy_date, &unused))
|
||||
{
|
||||
ErrConvTime str(ltime);
|
||||
make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
&str, MYSQL_TIMESTAMP_DATE, 0);
|
||||
return (null_value= 1);
|
||||
}
|
||||
|
|
@ -2468,7 +2468,7 @@ bool Item_datetime_typecast::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
|
|||
if (ltime->neg)
|
||||
{
|
||||
ErrConvTime str(ltime);
|
||||
make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
&str, MYSQL_TIMESTAMP_DATETIME, 0);
|
||||
return (null_value= 1);
|
||||
}
|
||||
|
|
@ -2622,7 +2622,7 @@ bool Item_func_add_time::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
|
|||
|
||||
check_time_range(ltime, decimals, &was_cut);
|
||||
if (was_cut)
|
||||
make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
&str, MYSQL_TIMESTAMP_TIME, NullS);
|
||||
|
||||
return (null_value= 0);
|
||||
|
|
@ -2710,7 +2710,7 @@ bool Item_func_timediff::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
|
|||
check_time_range(ltime, decimals, &was_cut);
|
||||
|
||||
if (was_cut)
|
||||
make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
&str, MYSQL_TIMESTAMP_TIME, NullS);
|
||||
return (null_value= 0);
|
||||
}
|
||||
|
|
@ -2762,7 +2762,7 @@ bool Item_func_maketime::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
|
|||
char buf[28];
|
||||
char *ptr= longlong10_to_str(hour, buf, args[0]->unsigned_flag ? 10 : -10);
|
||||
int len = (int)(ptr - buf) + sprintf(ptr, ":%02u:%02u", (uint)minute, (uint)second);
|
||||
make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
buf, len, MYSQL_TIMESTAMP_TIME,
|
||||
NullS);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1037,7 +1037,7 @@ static char simpletok[128]=
|
|||
/*
|
||||
! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
|
||||
@ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _
|
||||
` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ €
|
||||
` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \200
|
||||
*/
|
||||
0,1,0,0,1,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,0,
|
||||
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,
|
||||
|
|
@ -2811,7 +2811,7 @@ String *Item_xml_str_func::parse_xml(String *raw_xml, String *parsed_xml_buf)
|
|||
my_xml_error_lineno(&p) + 1,
|
||||
(ulong) my_xml_error_pos(&p) + 1,
|
||||
my_xml_error_string(&p));
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WRONG_VALUE,
|
||||
ER(ER_WRONG_VALUE), "XML", buf);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -150,6 +150,7 @@ static SYMBOL symbols[] = {
|
|||
{ "CREATE", SYM(CREATE)},
|
||||
{ "CROSS", SYM(CROSS)},
|
||||
{ "CUBE", SYM(CUBE_SYM)},
|
||||
{ "CURRENT", SYM(CURRENT_SYM)},
|
||||
{ "CURRENT_DATE", SYM(CURDATE)},
|
||||
{ "CURRENT_TIME", SYM(CURTIME)},
|
||||
{ "CURRENT_TIMESTAMP", SYM(NOW_SYM)},
|
||||
|
|
@ -180,6 +181,7 @@ static SYMBOL symbols[] = {
|
|||
{ "DESCRIBE", SYM(DESCRIBE)},
|
||||
{ "DES_KEY_FILE", SYM(DES_KEY_FILE)},
|
||||
{ "DETERMINISTIC", SYM(DETERMINISTIC_SYM)},
|
||||
{ "DIAGNOSTICS", SYM(DIAGNOSTICS_SYM)},
|
||||
{ "DIRECTORY", SYM(DIRECTORY_SYM)},
|
||||
{ "DISABLE", SYM(DISABLE_SYM)},
|
||||
{ "DISCARD", SYM(DISCARD)},
|
||||
|
|
@ -212,6 +214,7 @@ static SYMBOL symbols[] = {
|
|||
{ "EVENTS", SYM(EVENTS_SYM)},
|
||||
{ "EVERY", SYM(EVERY_SYM)},
|
||||
{ "EXAMINED", SYM(EXAMINED_SYM)},
|
||||
{ "EXCHANGE", SYM(EXCHANGE_SYM)},
|
||||
{ "EXECUTE", SYM(EXECUTE_SYM)},
|
||||
{ "EXISTS", SYM(EXISTS)},
|
||||
{ "EXIT", SYM(EXIT_SYM)},
|
||||
|
|
@ -244,6 +247,7 @@ static SYMBOL symbols[] = {
|
|||
{ "GEOMETRY", SYM(GEOMETRY_SYM)},
|
||||
{ "GEOMETRYCOLLECTION",SYM(GEOMETRYCOLLECTION)},
|
||||
{ "GET_FORMAT", SYM(GET_FORMAT)},
|
||||
{ "GET", SYM(GET_SYM)},
|
||||
{ "GLOBAL", SYM(GLOBAL_SYM)},
|
||||
{ "GRANT", SYM(GRANT)},
|
||||
{ "GRANTS", SYM(GRANTS)},
|
||||
|
|
@ -394,6 +398,7 @@ static SYMBOL symbols[] = {
|
|||
{ "NOT", SYM(NOT_SYM)},
|
||||
{ "NO_WRITE_TO_BINLOG", SYM(NO_WRITE_TO_BINLOG)},
|
||||
{ "NULL", SYM(NULL_SYM)},
|
||||
{ "NUMBER", SYM(NUMBER_SYM)},
|
||||
{ "NUMERIC", SYM(NUMERIC_SYM)},
|
||||
{ "NVARCHAR", SYM(NVARCHAR_SYM)},
|
||||
{ "OFFSET", SYM(OFFSET_SYM)},
|
||||
|
|
@ -480,6 +485,7 @@ static SYMBOL symbols[] = {
|
|||
{ "RESTORE", SYM(RESTORE_SYM)},
|
||||
{ "RESTRICT", SYM(RESTRICT)},
|
||||
{ "RESUME", SYM(RESUME_SYM)},
|
||||
{ "RETURNED_SQLSTATE",SYM(RETURNED_SQLSTATE_SYM)},
|
||||
{ "RETURN", SYM(RETURN_SYM)},
|
||||
{ "RETURNS", SYM(RETURNS_SYM)},
|
||||
{ "REVOKE", SYM(REVOKE)},
|
||||
|
|
@ -489,6 +495,7 @@ static SYMBOL symbols[] = {
|
|||
{ "ROLLUP", SYM(ROLLUP_SYM)},
|
||||
{ "ROUTINE", SYM(ROUTINE_SYM)},
|
||||
{ "ROW", SYM(ROW_SYM)},
|
||||
{ "ROW_COUNT", SYM(ROW_COUNT_SYM)},
|
||||
{ "ROWS", SYM(ROWS_SYM)},
|
||||
{ "ROW_FORMAT", SYM(ROW_FORMAT_SYM)},
|
||||
{ "RTREE", SYM(RTREE_SYM)},
|
||||
|
|
|
|||
34
sql/log.cc
34
sql/log.cc
|
|
@ -170,9 +170,9 @@ public:
|
|||
virtual bool handle_condition(THD *thd,
|
||||
uint sql_errno,
|
||||
const char* sql_state,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
Sql_condition::enum_warning_level level,
|
||||
const char* msg,
|
||||
MYSQL_ERROR ** cond_hdl);
|
||||
Sql_condition ** cond_hdl);
|
||||
const char *message() const { return m_message; }
|
||||
};
|
||||
|
||||
|
|
@ -180,9 +180,9 @@ bool
|
|||
Silence_log_table_errors::handle_condition(THD *,
|
||||
uint,
|
||||
const char*,
|
||||
MYSQL_ERROR::enum_warning_level,
|
||||
Sql_condition::enum_warning_level,
|
||||
const char* msg,
|
||||
MYSQL_ERROR ** cond_hdl)
|
||||
Sql_condition ** cond_hdl)
|
||||
{
|
||||
*cond_hdl= NULL;
|
||||
strmake(m_message, msg, sizeof(m_message)-1);
|
||||
|
|
@ -2057,7 +2057,7 @@ bool MYSQL_BIN_LOG::check_write_error(THD *thd)
|
|||
if (!thd->is_error())
|
||||
DBUG_RETURN(checked);
|
||||
|
||||
switch (thd->stmt_da->sql_errno())
|
||||
switch (thd->get_stmt_da()->sql_errno())
|
||||
{
|
||||
case ER_TRANS_CACHE_FULL:
|
||||
case ER_STMT_CACHE_FULL:
|
||||
|
|
@ -3778,7 +3778,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd, bool create_new_log)
|
|||
{
|
||||
if (my_errno == ENOENT)
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
|
||||
linfo.log_file_name);
|
||||
sql_print_information("Failed to delete file '%s'",
|
||||
|
|
@ -3788,7 +3788,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd, bool create_new_log)
|
|||
}
|
||||
else
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_BINLOG_PURGE_FATAL_ERR,
|
||||
"a problem with deleting %s; "
|
||||
"consider examining correspondence "
|
||||
|
|
@ -3809,7 +3809,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd, bool create_new_log)
|
|||
{
|
||||
if (my_errno == ENOENT)
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
|
||||
index_file_name);
|
||||
sql_print_information("Failed to delete file '%s'",
|
||||
|
|
@ -3819,7 +3819,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd, bool create_new_log)
|
|||
}
|
||||
else
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_BINLOG_PURGE_FATAL_ERR,
|
||||
"a problem with deleting %s; "
|
||||
"consider examining correspondence "
|
||||
|
|
@ -4261,7 +4261,7 @@ int MYSQL_BIN_LOG::purge_index_entry(THD *thd, ulonglong *decrease_log_space,
|
|||
*/
|
||||
if (thd)
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
|
||||
log_info.log_file_name);
|
||||
}
|
||||
|
|
@ -4276,7 +4276,7 @@ int MYSQL_BIN_LOG::purge_index_entry(THD *thd, ulonglong *decrease_log_space,
|
|||
*/
|
||||
if (thd)
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_BINLOG_PURGE_FATAL_ERR,
|
||||
"a problem with getting info on being purged %s; "
|
||||
"consider examining correspondence "
|
||||
|
|
@ -4304,7 +4304,7 @@ int MYSQL_BIN_LOG::purge_index_entry(THD *thd, ulonglong *decrease_log_space,
|
|||
{
|
||||
if (thd)
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_BINLOG_PURGE_FATAL_ERR,
|
||||
"a problem with deleting %s and "
|
||||
"reading the binlog index file",
|
||||
|
|
@ -4340,7 +4340,7 @@ int MYSQL_BIN_LOG::purge_index_entry(THD *thd, ulonglong *decrease_log_space,
|
|||
{
|
||||
if (thd)
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
|
||||
log_info.log_file_name);
|
||||
}
|
||||
|
|
@ -4352,7 +4352,7 @@ int MYSQL_BIN_LOG::purge_index_entry(THD *thd, ulonglong *decrease_log_space,
|
|||
{
|
||||
if (thd)
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_BINLOG_PURGE_FATAL_ERR,
|
||||
"a problem with deleting %s; "
|
||||
"consider examining correspondence "
|
||||
|
|
@ -4442,7 +4442,7 @@ int MYSQL_BIN_LOG::purge_logs_before_date(time_t purge_time)
|
|||
*/
|
||||
if (thd)
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_BINLOG_PURGE_FATAL_ERR,
|
||||
"a problem with getting info on being purged %s; "
|
||||
"consider examining correspondence "
|
||||
|
|
@ -6066,9 +6066,9 @@ int query_error_code(THD *thd, bool not_killed)
|
|||
|
||||
if (not_killed || (killed_mask_hard(thd->killed) == KILL_BAD_DATA))
|
||||
{
|
||||
error= thd->is_error() ? thd->stmt_da->sql_errno() : 0;
|
||||
error= thd->is_error() ? thd->get_stmt_da()->sql_errno() : 0;
|
||||
|
||||
/* thd->stmt_da->sql_errno() might be ER_SERVER_SHUTDOWN or
|
||||
/* thd->get_get_stmt_da()->sql_errno() might be ER_SERVER_SHUTDOWN or
|
||||
ER_QUERY_INTERRUPTED, So here we need to make sure that error
|
||||
is not set to these errors when specified not_killed by the
|
||||
caller.
|
||||
|
|
|
|||
|
|
@ -215,8 +215,9 @@ static void inline slave_rows_error_report(enum loglevel level, int ha_error,
|
|||
char buff[MAX_SLAVE_ERRMSG], *slider;
|
||||
const char *buff_end= buff + sizeof(buff);
|
||||
uint len;
|
||||
List_iterator_fast<MYSQL_ERROR> it(thd->warning_info->warn_list());
|
||||
MYSQL_ERROR *err;
|
||||
Diagnostics_area::Sql_condition_iterator it=
|
||||
thd->get_stmt_da()->sql_conditions();
|
||||
const Sql_condition *err;
|
||||
buff[0]= 0;
|
||||
|
||||
for (err= it++, slider= buff; err && slider < buff_end - 1;
|
||||
|
|
@ -228,7 +229,7 @@ static void inline slave_rows_error_report(enum loglevel level, int ha_error,
|
|||
}
|
||||
|
||||
if (ha_error != 0)
|
||||
rli->report(level, thd->is_error() ? thd->stmt_da->sql_errno() : 0,
|
||||
rli->report(level, thd->is_error() ? thd->get_stmt_da()->sql_errno() : 0,
|
||||
"Could not execute %s event on table %s.%s;"
|
||||
"%s handler error %s; "
|
||||
"the event's master log %s, end_log_pos %lu",
|
||||
|
|
@ -236,7 +237,7 @@ static void inline slave_rows_error_report(enum loglevel level, int ha_error,
|
|||
buff, handler_error == NULL ? "<unknown>" : handler_error,
|
||||
log_name, pos);
|
||||
else
|
||||
rli->report(level, thd->is_error() ? thd->stmt_da->sql_errno() : 0,
|
||||
rli->report(level, thd->is_error() ? thd->get_stmt_da()->sql_errno() : 0,
|
||||
"Could not execute %s event on table %s.%s;"
|
||||
"%s the event's master log %s, end_log_pos %lu",
|
||||
type, table->s->db.str, table->s->table_name.str,
|
||||
|
|
@ -440,13 +441,13 @@ inline int ignored_error_code(int err_code)
|
|||
*/
|
||||
int convert_handler_error(int error, THD* thd, TABLE *table)
|
||||
{
|
||||
uint actual_error= (thd->is_error() ? thd->stmt_da->sql_errno() :
|
||||
uint actual_error= (thd->is_error() ? thd->get_stmt_da()->sql_errno() :
|
||||
0);
|
||||
|
||||
if (actual_error == 0)
|
||||
{
|
||||
table->file->print_error(error, MYF(0));
|
||||
actual_error= (thd->is_error() ? thd->stmt_da->sql_errno() :
|
||||
actual_error= (thd->is_error() ? thd->get_stmt_da()->sql_errno() :
|
||||
ER_UNKNOWN_ERROR);
|
||||
if (actual_error == ER_UNKNOWN_ERROR)
|
||||
if (global_system_variables.log_warnings)
|
||||
|
|
@ -2108,7 +2109,8 @@ log_event_print_value(IO_CACHE *file, const uchar *ptr,
|
|||
{
|
||||
uint i32= uint3korr(ptr);
|
||||
my_b_printf(file , "'%04d:%02d:%02d'",
|
||||
(i32 / (16L * 32L)), (i32 / 32L % 16L), (i32 % 32L));
|
||||
(int)(i32 / (16L * 32L)), (int)(i32 / 32L % 16L),
|
||||
(int)(i32 % 32L));
|
||||
my_snprintf(typestr, typestr_length, "DATE");
|
||||
return 3;
|
||||
}
|
||||
|
|
@ -2236,11 +2238,11 @@ Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
|
|||
|
||||
if (is_null)
|
||||
{
|
||||
my_b_printf(file, "### @%d=NULL", i + 1);
|
||||
my_b_printf(file, "### @%lu=NULL", (ulong)i + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
my_b_printf(file, "### @%d=", i + 1);
|
||||
my_b_printf(file, "### @%lu=", (ulong)i + 1);
|
||||
size_t size= log_event_print_value(file, value,
|
||||
td->type(i), td->field_metadata(i),
|
||||
typestr, sizeof(typestr));
|
||||
|
|
@ -2311,14 +2313,23 @@ void Rows_log_event::print_verbose(IO_CACHE *file,
|
|||
if (!(map= print_event_info->m_table_map.get_table(m_table_id)) ||
|
||||
!(td= map->create_table_def()))
|
||||
{
|
||||
my_b_printf(file, "### Row event for unknown table #%d", m_table_id);
|
||||
my_b_printf(file, "### Row event for unknown table #%lu",
|
||||
(ulong) m_table_id);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the write rows event contained no values for the AI */
|
||||
if (((type_code == WRITE_ROWS_EVENT) && (m_rows_buf==m_rows_end)))
|
||||
{
|
||||
my_b_printf(file, "### INSERT INTO `%s`.`%s` VALUES ()\n",
|
||||
map->get_db_name(), map->get_table_name());
|
||||
goto end;
|
||||
}
|
||||
|
||||
for (const uchar *value= m_rows_buf; value < m_rows_end; )
|
||||
{
|
||||
size_t length;
|
||||
my_b_printf(file, "### %s %`s.%`s\n",
|
||||
my_b_printf(file, "### %s '%s'.'%s'\n",
|
||||
sql_command,
|
||||
map->get_db_name(), map->get_table_name());
|
||||
/* Print the first image */
|
||||
|
|
@ -3467,7 +3478,7 @@ void Query_log_event::print_query_header(IO_CACHE* file,
|
|||
if (different_db)
|
||||
memcpy(print_event_info->db, db, db_len + 1);
|
||||
if (db[0] && different_db)
|
||||
my_b_printf(file, "use %`s%s\n", db, print_event_info->delimiter);
|
||||
my_b_printf(file, "use %s%s\n", db, print_event_info->delimiter);
|
||||
}
|
||||
|
||||
end=int10_to_str((long) when, strmov(buff,"SET TIMESTAMP="),10);
|
||||
|
|
@ -3943,7 +3954,8 @@ START SLAVE; . Query: '%s'", expected_error, thd->query());
|
|||
}
|
||||
|
||||
/* If the query was not ignored, it is printed to the general log */
|
||||
if (!thd->is_error() || thd->stmt_da->sql_errno() != ER_SLAVE_IGNORED_TABLE)
|
||||
if (!thd->is_error() ||
|
||||
thd->get_stmt_da()->sql_errno() != ER_SLAVE_IGNORED_TABLE)
|
||||
general_log_write(thd, COM_QUERY, thd->query(), thd->query_length());
|
||||
else
|
||||
{
|
||||
|
|
@ -3968,14 +3980,14 @@ compare_errors:
|
|||
not exist errors", we silently clear the error if TEMPORARY was used.
|
||||
*/
|
||||
if (thd->lex->sql_command == SQLCOM_DROP_TABLE && thd->lex->drop_temporary &&
|
||||
thd->is_error() && thd->stmt_da->sql_errno() == ER_BAD_TABLE_ERROR &&
|
||||
thd->is_error() && thd->get_stmt_da()->sql_errno() == ER_BAD_TABLE_ERROR &&
|
||||
!expected_error)
|
||||
thd->stmt_da->reset_diagnostics_area();
|
||||
thd->get_stmt_da()->reset_diagnostics_area();
|
||||
/*
|
||||
If we expected a non-zero error code, and we don't get the same error
|
||||
code, and it should be ignored or is related to a concurrency issue.
|
||||
*/
|
||||
actual_error= thd->is_error() ? thd->stmt_da->sql_errno() : 0;
|
||||
actual_error= thd->is_error() ? thd->get_stmt_da()->sql_errno() : 0;
|
||||
DBUG_PRINT("info",("expected_error: %d sql_errno: %d",
|
||||
expected_error, actual_error));
|
||||
|
||||
|
|
@ -3993,7 +4005,7 @@ Error on slave: actual message='%s', error code=%d. \
|
|||
Default database: '%s'. Query: '%s'",
|
||||
ER_SAFE(expected_error),
|
||||
expected_error,
|
||||
actual_error ? thd->stmt_da->message() : "no error",
|
||||
actual_error ? thd->get_stmt_da()->message() : "no error",
|
||||
actual_error,
|
||||
print_slave_db_safe(db), query_arg);
|
||||
thd->is_slave_error= 1;
|
||||
|
|
@ -4017,7 +4029,7 @@ Default database: '%s'. Query: '%s'",
|
|||
{
|
||||
rli->report(ERROR_LEVEL, actual_error,
|
||||
"Error '%s' on query. Default database: '%s'. Query: '%s'",
|
||||
(actual_error ? thd->stmt_da->message() :
|
||||
(actual_error ? thd->get_stmt_da()->message() :
|
||||
"unexpected success or fatal error"),
|
||||
print_slave_db_safe(thd->db), query_arg);
|
||||
thd->is_slave_error= 1;
|
||||
|
|
@ -5301,7 +5313,7 @@ void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
|
|||
}
|
||||
|
||||
if (db && db[0] && different_db)
|
||||
my_b_printf(&cache, "%suse %`s%s\n",
|
||||
my_b_printf(&cache, "%suse %s%s\n",
|
||||
commented ? "# " : "",
|
||||
db, print_event_info->delimiter);
|
||||
|
||||
|
|
@ -5353,7 +5365,7 @@ void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
|
|||
{
|
||||
if (i)
|
||||
my_b_printf(&cache, ",");
|
||||
my_b_printf(&cache, "%`s", field);
|
||||
my_b_printf(&cache, "%s", field);
|
||||
|
||||
field += field_lens[i] + 1;
|
||||
}
|
||||
|
|
@ -5484,7 +5496,7 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
|
|||
{
|
||||
thd->set_time(when, when_sec_part);
|
||||
thd->set_query_id(next_query_id());
|
||||
thd->warning_info->opt_clear_warning_info(thd->query_id);
|
||||
thd->get_stmt_da()->opt_clear_warning_info(thd->query_id);
|
||||
|
||||
TABLE_LIST tables;
|
||||
tables.init_one_table(thd->strmake(thd->db, thd->db_length),
|
||||
|
|
@ -5630,9 +5642,9 @@ error:
|
|||
thd->catalog= 0;
|
||||
thd->set_db(NULL, 0); /* will free the current database */
|
||||
thd->reset_query();
|
||||
thd->stmt_da->can_overwrite_status= TRUE;
|
||||
thd->get_stmt_da()->set_overwrite_status(true);
|
||||
thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
|
||||
thd->stmt_da->can_overwrite_status= FALSE;
|
||||
thd->get_stmt_da()->set_overwrite_status(false);
|
||||
close_thread_tables(thd);
|
||||
/*
|
||||
- If inside a multi-statement transaction,
|
||||
|
|
@ -5659,8 +5671,8 @@ error:
|
|||
int sql_errno;
|
||||
if (thd->is_error())
|
||||
{
|
||||
err= thd->stmt_da->message();
|
||||
sql_errno= thd->stmt_da->sql_errno();
|
||||
err= thd->get_stmt_da()->message();
|
||||
sql_errno= thd->get_stmt_da()->sql_errno();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -8496,7 +8508,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
|
|||
|
||||
if (open_and_lock_tables(thd, rli->tables_to_lock, FALSE, 0))
|
||||
{
|
||||
uint actual_error= thd->stmt_da->sql_errno();
|
||||
uint actual_error= thd->get_stmt_da()->sql_errno();
|
||||
if (thd->is_slave_error || thd->is_fatal_error)
|
||||
{
|
||||
/*
|
||||
|
|
@ -8507,7 +8519,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
|
|||
*/
|
||||
rli->report(ERROR_LEVEL, actual_error,
|
||||
"Error executing row event: '%s'",
|
||||
(actual_error ? thd->stmt_da->message() :
|
||||
(actual_error ? thd->get_stmt_da()->message() :
|
||||
"unexpected success or fatal error"));
|
||||
thd->is_slave_error= 1;
|
||||
}
|
||||
|
|
@ -9835,8 +9847,8 @@ void Table_map_log_event::print(FILE *, PRINT_EVENT_INFO *print_event_info)
|
|||
{
|
||||
print_header(&print_event_info->head_cache, print_event_info, TRUE);
|
||||
my_b_printf(&print_event_info->head_cache,
|
||||
"\tTable_map: %`s.%`s mapped to number %lu\n",
|
||||
m_dbnam, m_tblnam, m_table_id);
|
||||
"\tTable_map: '%s'.'%s' mapped to number %lu\n",
|
||||
m_dbnam, m_tblnam, (ulong) m_table_id);
|
||||
print_base64(&print_event_info->body_cache, print_event_info, TRUE);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info
|
|||
|
||||
if (open_and_lock_tables(ev_thd, rli->tables_to_lock, FALSE, 0))
|
||||
{
|
||||
uint actual_error= ev_thd->stmt_da->sql_errno();
|
||||
uint actual_error= ev_thd->get_stmt_da()->sql_errno();
|
||||
if (ev_thd->is_slave_error || ev_thd->is_fatal_error)
|
||||
{
|
||||
/*
|
||||
|
|
@ -108,7 +108,7 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info
|
|||
*/
|
||||
rli->report(ERROR_LEVEL, actual_error,
|
||||
"Error '%s' on opening tables",
|
||||
(actual_error ? ev_thd->stmt_da->message() :
|
||||
(actual_error ? ev_thd->get_stmt_da()->message() :
|
||||
"unexpected success or fatal error"));
|
||||
ev_thd->is_slave_error= 1;
|
||||
}
|
||||
|
|
@ -243,10 +243,10 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info
|
|||
break;
|
||||
|
||||
default:
|
||||
rli->report(ERROR_LEVEL, ev_thd->stmt_da->sql_errno(),
|
||||
rli->report(ERROR_LEVEL, ev_thd->get_stmt_da()->sql_errno(),
|
||||
"Error in %s event: row application failed. %s",
|
||||
ev->get_type_str(),
|
||||
ev_thd->is_error() ? ev_thd->stmt_da->message() : "");
|
||||
ev_thd->is_error() ? ev_thd->get_stmt_da()->message() : "");
|
||||
thd->is_slave_error= 1;
|
||||
break;
|
||||
}
|
||||
|
|
@ -260,12 +260,12 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info
|
|||
|
||||
if (error)
|
||||
{ /* error has occured during the transaction */
|
||||
rli->report(ERROR_LEVEL, ev_thd->stmt_da->sql_errno(),
|
||||
rli->report(ERROR_LEVEL, ev_thd->get_stmt_da()->sql_errno(),
|
||||
"Error in %s event: error during transaction execution "
|
||||
"on table %s.%s. %s",
|
||||
ev->get_type_str(), table->s->db.str,
|
||||
table->s->table_name.str,
|
||||
ev_thd->is_error() ? ev_thd->stmt_da->message() : "");
|
||||
ev_thd->is_error() ? ev_thd->get_stmt_da()->message() : "");
|
||||
|
||||
/*
|
||||
If one day we honour --skip-slave-errors in row-based replication, and
|
||||
|
|
|
|||
152
sql/mdl.cc
152
sql/mdl.cc
|
|
@ -317,7 +317,7 @@ Deadlock_detection_visitor::opt_change_victim_to(MDL_context *new_victim)
|
|||
class MDL_lock
|
||||
{
|
||||
public:
|
||||
typedef uchar bitmap_t;
|
||||
typedef unsigned short bitmap_t;
|
||||
|
||||
class Ticket_list
|
||||
{
|
||||
|
|
@ -1108,7 +1108,7 @@ void MDL_ticket::destroy(MDL_ticket *ticket)
|
|||
uint MDL_ticket::get_deadlock_weight() const
|
||||
{
|
||||
return (m_lock->key.mdl_namespace() == MDL_key::GLOBAL ||
|
||||
m_type >= MDL_SHARED_NO_WRITE ?
|
||||
m_type >= MDL_SHARED_UPGRADABLE ?
|
||||
DEADLOCK_WEIGHT_DDL : DEADLOCK_WEIGHT_DML);
|
||||
}
|
||||
|
||||
|
|
@ -1440,16 +1440,6 @@ void MDL_lock::reschedule_waiters()
|
|||
lock. Arrays of bitmaps which elements specify which granted/waiting locks
|
||||
are incompatible with type of lock being requested.
|
||||
|
||||
Here is how types of individual locks are translated to type of scoped lock:
|
||||
|
||||
----------------+-------------+
|
||||
Type of request | Correspond. |
|
||||
for indiv. lock | scoped lock |
|
||||
----------------+-------------+
|
||||
S, SH, SR, SW | IS |
|
||||
SNW, SNRW, X | IX |
|
||||
SNW, SNRW -> X | IX (*) |
|
||||
|
||||
The first array specifies if particular type of request can be satisfied
|
||||
if there is granted scoped lock of certain type.
|
||||
|
||||
|
|
@ -1478,24 +1468,33 @@ void MDL_lock::reschedule_waiters()
|
|||
Here: "+" -- means that request can be satisfied
|
||||
"-" -- means that request can't be satisfied and should wait
|
||||
|
||||
(*) Since for upgradable locks we always take intention exclusive scoped
|
||||
lock at the same time when obtaining the shared lock, there is no
|
||||
need to obtain such lock during the upgrade itself.
|
||||
(**) Since intention shared scoped locks are compatible with all other
|
||||
type of locks we don't even have any accounting for them.
|
||||
(*) Since intention shared scoped locks are compatible with all other
|
||||
type of locks we don't even have any accounting for them.
|
||||
|
||||
Note that relation between scoped locks and objects locks requested
|
||||
by statement is not straightforward and is therefore fully defined
|
||||
by SQL-layer.
|
||||
For example, in order to support global read lock implementation
|
||||
SQL-layer acquires IX lock in GLOBAL namespace for each statement
|
||||
that can modify metadata or data (i.e. for each statement that
|
||||
needs SW, SU, SNW, SNRW or X object locks). OTOH, to ensure that
|
||||
DROP DATABASE works correctly with concurrent DDL, IX metadata locks
|
||||
in SCHEMA namespace are acquired for DDL statements which can update
|
||||
metadata in the schema (i.e. which acquire SU, SNW, SNRW and X locks
|
||||
on schema objects) and aren't acquired for DML.
|
||||
*/
|
||||
|
||||
const MDL_lock::bitmap_t MDL_scoped_lock::m_granted_incompatible[MDL_TYPE_END] =
|
||||
{
|
||||
MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED),
|
||||
MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_INTENTION_EXCLUSIVE), 0, 0, 0, 0, 0,
|
||||
MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_INTENTION_EXCLUSIVE), 0, 0, 0, 0, 0, 0,
|
||||
MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED) | MDL_BIT(MDL_INTENTION_EXCLUSIVE)
|
||||
};
|
||||
|
||||
const MDL_lock::bitmap_t MDL_scoped_lock::m_waiting_incompatible[MDL_TYPE_END] =
|
||||
{
|
||||
MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED),
|
||||
MDL_BIT(MDL_EXCLUSIVE), 0, 0, 0, 0, 0, 0
|
||||
MDL_BIT(MDL_EXCLUSIVE), 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -1507,35 +1506,39 @@ const MDL_lock::bitmap_t MDL_scoped_lock::m_waiting_incompatible[MDL_TYPE_END] =
|
|||
The first array specifies if particular type of request can be satisfied
|
||||
if there is granted lock of certain type.
|
||||
|
||||
Request | Granted requests for lock |
|
||||
type | S SH SR SW SNW SNRW X |
|
||||
----------+------------------------------+
|
||||
S | + + + + + + - |
|
||||
SH | + + + + + + - |
|
||||
SR | + + + + + - - |
|
||||
SW | + + + + - - - |
|
||||
SNW | + + + - - - - |
|
||||
SNRW | + + - - - - - |
|
||||
X | - - - - - - - |
|
||||
SNW -> X | - - - 0 0 0 0 |
|
||||
SNRW -> X | - - 0 0 0 0 0 |
|
||||
Request | Granted requests for lock |
|
||||
type | S SH SR SW SU SNW SNRW X |
|
||||
----------+----------------------------------+
|
||||
S | + + + + + + + - |
|
||||
SH | + + + + + + + - |
|
||||
SR | + + + + + + - - |
|
||||
SW | + + + + + - - - |
|
||||
SU | + + + + - - - - |
|
||||
SNW | + + + - - - - - |
|
||||
SNRW | + + - - - - - - |
|
||||
X | - - - - - - - - |
|
||||
SU -> X | - - - - 0 0 0 0 |
|
||||
SNW -> X | - - - 0 0 0 0 0 |
|
||||
SNRW -> X | - - 0 0 0 0 0 0 |
|
||||
|
||||
The second array specifies if particular type of request can be satisfied
|
||||
if there is waiting request for the same lock of certain type. In other
|
||||
words it specifies what is the priority of different lock types.
|
||||
|
||||
Request | Pending requests for lock |
|
||||
type | S SH SR SW SNW SNRW X |
|
||||
----------+-----------------------------+
|
||||
S | + + + + + + - |
|
||||
SH | + + + + + + + |
|
||||
SR | + + + + + - - |
|
||||
SW | + + + + - - - |
|
||||
SNW | + + + + + + - |
|
||||
SNRW | + + + + + + - |
|
||||
X | + + + + + + + |
|
||||
SNW -> X | + + + + + + + |
|
||||
SNRW -> X | + + + + + + + |
|
||||
Request | Pending requests for lock |
|
||||
type | S SH SR SW SU SNW SNRW X |
|
||||
----------+---------------------------------+
|
||||
S | + + + + + + + - |
|
||||
SH | + + + + + + + + |
|
||||
SR | + + + + + + - - |
|
||||
SW | + + + + + - - - |
|
||||
SU | + + + + + + + - |
|
||||
SNW | + + + + + + + - |
|
||||
SNRW | + + + + + + + - |
|
||||
X | + + + + + + + + |
|
||||
SU -> X | + + + + + + + + |
|
||||
SNW -> X | + + + + + + + + |
|
||||
SNRW -> X | + + + + + + + + |
|
||||
|
||||
Here: "+" -- means that request can be satisfied
|
||||
"-" -- means that request can't be satisfied and should wait
|
||||
|
|
@ -1544,6 +1547,9 @@ const MDL_lock::bitmap_t MDL_scoped_lock::m_waiting_incompatible[MDL_TYPE_END] =
|
|||
@note In cases then current context already has "stronger" type
|
||||
of lock on the object it will be automatically granted
|
||||
thanks to usage of the MDL_context::find_ticket() method.
|
||||
|
||||
@note IX locks are excluded since they are not used for per-object
|
||||
metadata locks.
|
||||
*/
|
||||
|
||||
const MDL_lock::bitmap_t
|
||||
|
|
@ -1556,14 +1562,17 @@ MDL_object_lock::m_granted_incompatible[MDL_TYPE_END] =
|
|||
MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE) |
|
||||
MDL_BIT(MDL_SHARED_NO_WRITE),
|
||||
MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE) |
|
||||
MDL_BIT(MDL_SHARED_NO_WRITE) | MDL_BIT(MDL_SHARED_WRITE),
|
||||
MDL_BIT(MDL_SHARED_NO_WRITE) | MDL_BIT(MDL_SHARED_UPGRADABLE),
|
||||
MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE) |
|
||||
MDL_BIT(MDL_SHARED_NO_WRITE) | MDL_BIT(MDL_SHARED_WRITE) |
|
||||
MDL_BIT(MDL_SHARED_READ),
|
||||
MDL_BIT(MDL_SHARED_NO_WRITE) | MDL_BIT(MDL_SHARED_UPGRADABLE) |
|
||||
MDL_BIT(MDL_SHARED_WRITE),
|
||||
MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE) |
|
||||
MDL_BIT(MDL_SHARED_NO_WRITE) | MDL_BIT(MDL_SHARED_WRITE) |
|
||||
MDL_BIT(MDL_SHARED_READ) | MDL_BIT(MDL_SHARED_HIGH_PRIO) |
|
||||
MDL_BIT(MDL_SHARED)
|
||||
MDL_BIT(MDL_SHARED_NO_WRITE) | MDL_BIT(MDL_SHARED_UPGRADABLE) |
|
||||
MDL_BIT(MDL_SHARED_WRITE) | MDL_BIT(MDL_SHARED_READ),
|
||||
MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE) |
|
||||
MDL_BIT(MDL_SHARED_NO_WRITE) | MDL_BIT(MDL_SHARED_UPGRADABLE) |
|
||||
MDL_BIT(MDL_SHARED_WRITE) | MDL_BIT(MDL_SHARED_READ) |
|
||||
MDL_BIT(MDL_SHARED_HIGH_PRIO) | MDL_BIT(MDL_SHARED)
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -1578,6 +1587,7 @@ MDL_object_lock::m_waiting_incompatible[MDL_TYPE_END] =
|
|||
MDL_BIT(MDL_SHARED_NO_WRITE),
|
||||
MDL_BIT(MDL_EXCLUSIVE),
|
||||
MDL_BIT(MDL_EXCLUSIVE),
|
||||
MDL_BIT(MDL_EXCLUSIVE),
|
||||
0
|
||||
};
|
||||
|
||||
|
|
@ -1990,7 +2000,7 @@ void MDL_object_lock::notify_conflicting_locks(MDL_context *ctx)
|
|||
{
|
||||
/* Only try to abort locks on which we back off. */
|
||||
if (conflicting_ticket->get_ctx() != ctx &&
|
||||
conflicting_ticket->get_type() < MDL_SHARED_NO_WRITE)
|
||||
conflicting_ticket->get_type() < MDL_SHARED_UPGRADABLE)
|
||||
|
||||
{
|
||||
MDL_context *conflicting_ctx= conflicting_ticket->get_ctx();
|
||||
|
|
@ -2258,11 +2268,12 @@ err:
|
|||
|
||||
|
||||
/**
|
||||
Upgrade a shared metadata lock to exclusive.
|
||||
Upgrade a shared metadata lock.
|
||||
|
||||
Used in ALTER TABLE, when a copy of the table with the
|
||||
new definition has been constructed.
|
||||
Used in ALTER TABLE.
|
||||
|
||||
@param mdl_ticket Lock to upgrade.
|
||||
@param new_type Lock type to upgrade to.
|
||||
@param lock_wait_timeout Seconds to wait before timeout.
|
||||
|
||||
@note In case of failure to upgrade lock (e.g. because upgrader
|
||||
|
|
@ -2270,7 +2281,7 @@ err:
|
|||
shared mode).
|
||||
|
||||
@note There can be only one upgrader for a lock or we will have deadlock.
|
||||
This invariant is ensured by the fact that upgradeable locks SNW
|
||||
This invariant is ensured by the fact that upgradeable locks SU, SNW
|
||||
and SNRW are not compatible with each other and themselves.
|
||||
|
||||
@retval FALSE Success
|
||||
|
|
@ -2278,28 +2289,30 @@ err:
|
|||
*/
|
||||
|
||||
bool
|
||||
MDL_context::upgrade_shared_lock_to_exclusive(MDL_ticket *mdl_ticket,
|
||||
ulong lock_wait_timeout)
|
||||
MDL_context::upgrade_shared_lock(MDL_ticket *mdl_ticket,
|
||||
enum_mdl_type new_type,
|
||||
ulong lock_wait_timeout)
|
||||
{
|
||||
MDL_request mdl_xlock_request;
|
||||
MDL_savepoint mdl_svp= mdl_savepoint();
|
||||
bool is_new_ticket;
|
||||
|
||||
DBUG_ENTER("MDL_ticket::upgrade_shared_lock_to_exclusive");
|
||||
DEBUG_SYNC(get_thd(), "mdl_upgrade_shared_lock_to_exclusive");
|
||||
DBUG_ENTER("MDL_context::upgrade_shared_lock");
|
||||
DEBUG_SYNC(get_thd(), "mdl_upgrade_lock");
|
||||
|
||||
/*
|
||||
Do nothing if already upgraded. Used when we FLUSH TABLE under
|
||||
LOCK TABLES and a table is listed twice in LOCK TABLES list.
|
||||
*/
|
||||
if (mdl_ticket->m_type == MDL_EXCLUSIVE)
|
||||
if (mdl_ticket->has_stronger_or_equal_type(new_type))
|
||||
DBUG_RETURN(FALSE);
|
||||
|
||||
/* Only allow upgrades from MDL_SHARED_NO_WRITE/NO_READ_WRITE */
|
||||
DBUG_ASSERT(mdl_ticket->m_type == MDL_SHARED_NO_WRITE ||
|
||||
/* Only allow upgrades from SHARED_UPGRADABLE/NO_WRITE/NO_READ_WRITE */
|
||||
DBUG_ASSERT(mdl_ticket->m_type == MDL_SHARED_UPGRADABLE ||
|
||||
mdl_ticket->m_type == MDL_SHARED_NO_WRITE ||
|
||||
mdl_ticket->m_type == MDL_SHARED_NO_READ_WRITE);
|
||||
|
||||
mdl_xlock_request.init(&mdl_ticket->m_lock->key, MDL_EXCLUSIVE,
|
||||
mdl_xlock_request.init(&mdl_ticket->m_lock->key, new_type,
|
||||
MDL_TRANSACTION);
|
||||
|
||||
if (acquire_lock(&mdl_xlock_request, lock_wait_timeout))
|
||||
|
|
@ -2317,7 +2330,7 @@ MDL_context::upgrade_shared_lock_to_exclusive(MDL_ticket *mdl_ticket,
|
|||
ticket from the granted queue and then include it back.
|
||||
*/
|
||||
mdl_ticket->m_lock->m_granted.remove_ticket(mdl_ticket);
|
||||
mdl_ticket->m_type= MDL_EXCLUSIVE;
|
||||
mdl_ticket->m_type= new_type;
|
||||
mdl_ticket->m_lock->m_granted.add_ticket(mdl_ticket);
|
||||
|
||||
mysql_prlock_unlock(&mdl_ticket->m_lock->m_rwlock);
|
||||
|
|
@ -2681,22 +2694,29 @@ void MDL_context::release_all_locks_for_name(MDL_ticket *name)
|
|||
|
||||
|
||||
/**
|
||||
Downgrade an exclusive lock to shared metadata lock.
|
||||
Downgrade an EXCLUSIVE or SHARED_NO_WRITE lock to shared metadata lock.
|
||||
|
||||
@param type Type of lock to which exclusive lock should be downgraded.
|
||||
*/
|
||||
|
||||
void MDL_ticket::downgrade_exclusive_lock(enum_mdl_type type)
|
||||
void MDL_ticket::downgrade_lock(enum_mdl_type type)
|
||||
{
|
||||
mysql_mutex_assert_not_owner(&LOCK_open);
|
||||
|
||||
/*
|
||||
Do nothing if already downgraded. Used when we FLUSH TABLE under
|
||||
LOCK TABLES and a table is listed twice in LOCK TABLES list.
|
||||
Note that this code might even try to "downgrade" a weak lock
|
||||
(e.g. SW) to a stronger one (e.g SNRW). So we can't even assert
|
||||
here that target lock is weaker than existing lock.
|
||||
*/
|
||||
if (m_type != MDL_EXCLUSIVE)
|
||||
if (m_type == type || !has_stronger_or_equal_type(type))
|
||||
return;
|
||||
|
||||
/* Only allow downgrade from EXCLUSIVE and SHARED_NO_WRITE. */
|
||||
DBUG_ASSERT(m_type == MDL_EXCLUSIVE ||
|
||||
m_type == MDL_SHARED_NO_WRITE);
|
||||
|
||||
mysql_prlock_wrlock(&m_lock->m_rwlock);
|
||||
/*
|
||||
To update state of MDL_lock object correctly we need to temporarily
|
||||
|
|
|
|||
19
sql/mdl.h
19
sql/mdl.h
|
|
@ -131,6 +131,15 @@ enum enum_mdl_type {
|
|||
SELECT ... FOR UPDATE.
|
||||
*/
|
||||
MDL_SHARED_WRITE,
|
||||
/*
|
||||
An upgradable shared metadata lock for cases when there is an intention
|
||||
to modify (and not just read) data in the table.
|
||||
Can be upgraded to MDL_SHARED_NO_WRITE and MDL_EXCLUSIVE.
|
||||
A connection holding SU lock can read table metadata and modify or read
|
||||
table data (after acquiring appropriate table and row-level locks).
|
||||
To be used for the first phase of ALTER TABLE.
|
||||
*/
|
||||
MDL_SHARED_UPGRADABLE,
|
||||
/*
|
||||
An upgradable shared metadata lock which blocks all attempts to update
|
||||
table data, allowing reads.
|
||||
|
|
@ -502,13 +511,14 @@ public:
|
|||
MDL_context *get_ctx() const { return m_ctx; }
|
||||
bool is_upgradable_or_exclusive() const
|
||||
{
|
||||
return m_type == MDL_SHARED_NO_WRITE ||
|
||||
return m_type == MDL_SHARED_UPGRADABLE ||
|
||||
m_type == MDL_SHARED_NO_WRITE ||
|
||||
m_type == MDL_SHARED_NO_READ_WRITE ||
|
||||
m_type == MDL_EXCLUSIVE;
|
||||
}
|
||||
enum_mdl_type get_type() const { return m_type; }
|
||||
MDL_lock *get_lock() const { return m_lock; }
|
||||
void downgrade_exclusive_lock(enum_mdl_type type);
|
||||
void downgrade_lock(enum_mdl_type type);
|
||||
|
||||
bool has_stronger_or_equal_type(enum_mdl_type type) const;
|
||||
|
||||
|
|
@ -660,8 +670,9 @@ public:
|
|||
bool try_acquire_lock(MDL_request *mdl_request);
|
||||
bool acquire_lock(MDL_request *mdl_request, ulong lock_wait_timeout);
|
||||
bool acquire_locks(MDL_request_list *requests, ulong lock_wait_timeout);
|
||||
bool upgrade_shared_lock_to_exclusive(MDL_ticket *mdl_ticket,
|
||||
ulong lock_wait_timeout);
|
||||
bool upgrade_shared_lock(MDL_ticket *mdl_ticket,
|
||||
enum_mdl_type new_type,
|
||||
ulong lock_wait_timeout);
|
||||
|
||||
bool clone_ticket(MDL_request *mdl_request);
|
||||
|
||||
|
|
|
|||
|
|
@ -1496,7 +1496,7 @@ ha_rows DsMrr_impl::dsmrr_info_const(uint keyno, RANGE_SEQ_IF *seq,
|
|||
bool key_uses_partial_cols(TABLE *table, uint keyno)
|
||||
{
|
||||
KEY_PART_INFO *kp= table->key_info[keyno].key_part;
|
||||
KEY_PART_INFO *kp_end= kp + table->key_info[keyno].key_parts;
|
||||
KEY_PART_INFO *kp_end= kp + table->key_info[keyno].user_defined_key_parts;
|
||||
for (; kp != kp_end; kp++)
|
||||
{
|
||||
if (!kp->field->part_of_key.is_set(keyno))
|
||||
|
|
|
|||
|
|
@ -45,21 +45,21 @@ int decimal_operation_results(int result, const char *value, const char *type)
|
|||
case E_DEC_OK:
|
||||
break;
|
||||
case E_DEC_TRUNCATED:
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_DATA_TRUNCATED, ER(ER_DATA_TRUNCATED),
|
||||
value, type);
|
||||
break;
|
||||
case E_DEC_OVERFLOW:
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_DATA_OVERFLOW, ER(ER_DATA_OVERFLOW),
|
||||
value, type);
|
||||
break;
|
||||
case E_DEC_DIV_ZERO:
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_DIVISION_BY_ZERO, ER(ER_DIVISION_BY_ZERO));
|
||||
break;
|
||||
case E_DEC_BAD_NUM:
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_BAD_DATA, ER(ER_BAD_DATA),
|
||||
value, type);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -738,6 +738,7 @@ static char **remaining_argv;
|
|||
int orig_argc;
|
||||
char **orig_argv;
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
static struct my_option pfs_early_options[]=
|
||||
{
|
||||
{"performance_schema_instrument", OPT_PFS_INSTRUMENT,
|
||||
|
|
@ -805,8 +806,7 @@ static struct my_option pfs_early_options[]=
|
|||
&pfs_param.m_consumer_statement_digest_enabled, 0,
|
||||
GET_BOOL, OPT_ARG, TRUE, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PSI_INTERFACE
|
||||
#ifdef HAVE_MMAP
|
||||
|
|
@ -1086,7 +1086,8 @@ void net_after_header_psi(struct st_net *net, void *user_data, size_t /* unused:
|
|||
{
|
||||
thd->m_statement_psi= MYSQL_START_STATEMENT(&thd->m_statement_state,
|
||||
stmt_info_new_packet.m_key,
|
||||
thd->db, thd->db_length);
|
||||
thd->db, thd->db_length,
|
||||
thd->charset());
|
||||
|
||||
THD_STAGE_INFO(thd, stage_init);
|
||||
}
|
||||
|
|
@ -1118,12 +1119,6 @@ void init_net_server_extension(THD *thd)
|
|||
}
|
||||
#endif /* EMBEDDED_LIBRARY */
|
||||
|
||||
/*
|
||||
Since buffered_option_error_reporter is only used currently
|
||||
for parsing performance schema options, this code is not needed
|
||||
when the performance schema is not compiled in.
|
||||
*/
|
||||
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
|
||||
/**
|
||||
A log message for the error log, buffered in memory.
|
||||
Log messages are temporarily buffered when generated before the error log
|
||||
|
|
@ -1259,13 +1254,16 @@ void Buffered_logs::print()
|
|||
/** Logs reported before a logger is available. */
|
||||
static Buffered_logs buffered_logs;
|
||||
|
||||
static MYSQL_SOCKET unix_sock, base_ip_sock, extra_ip_sock;
|
||||
struct my_rnd_struct sql_rand; ///< used by sql_class.cc:THD::THD()
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
/**
|
||||
Error reporter that buffer log messages.
|
||||
@param level log message level
|
||||
@param format log message format string
|
||||
*/
|
||||
C_MODE_START
|
||||
|
||||
static void buffered_option_error_reporter(enum loglevel level,
|
||||
const char *format, ...)
|
||||
{
|
||||
|
|
@ -1277,14 +1275,7 @@ static void buffered_option_error_reporter(enum loglevel level,
|
|||
va_end(args);
|
||||
buffered_logs.buffer(level, buffer);
|
||||
}
|
||||
C_MODE_END
|
||||
#endif /* !EMBEDDED_LIBRARY */
|
||||
#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
|
||||
|
||||
static MYSQL_SOCKET unix_sock, base_ip_sock, extra_ip_sock;
|
||||
struct my_rnd_struct sql_rand; ///< used by sql_class.cc:THD::THD()
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
struct passwd *user_info;
|
||||
static pthread_t select_thread;
|
||||
#endif
|
||||
|
|
@ -3246,7 +3237,7 @@ extern "C" void my_message_sql(uint error, const char *str, myf MyFlags);
|
|||
void my_message_sql(uint error, const char *str, myf MyFlags)
|
||||
{
|
||||
THD *thd= current_thd;
|
||||
MYSQL_ERROR::enum_warning_level level;
|
||||
Sql_condition::enum_warning_level level;
|
||||
sql_print_message_func func;
|
||||
DBUG_ENTER("my_message_sql");
|
||||
DBUG_PRINT("error", ("error: %u message: '%s' Flag: %lu", error, str,
|
||||
|
|
@ -3258,17 +3249,17 @@ void my_message_sql(uint error, const char *str, myf MyFlags)
|
|||
mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_ERROR, error, str);
|
||||
if (MyFlags & ME_JUST_INFO)
|
||||
{
|
||||
level= MYSQL_ERROR::WARN_LEVEL_NOTE;
|
||||
level= Sql_condition::WARN_LEVEL_NOTE;
|
||||
func= sql_print_information;
|
||||
}
|
||||
else if (MyFlags & ME_JUST_WARNING)
|
||||
{
|
||||
level= MYSQL_ERROR::WARN_LEVEL_WARN;
|
||||
level= Sql_condition::WARN_LEVEL_WARN;
|
||||
func= sql_print_warning;
|
||||
}
|
||||
else
|
||||
{
|
||||
level= MYSQL_ERROR::WARN_LEVEL_ERROR;
|
||||
level= Sql_condition::WARN_LEVEL_ERROR;
|
||||
func= sql_print_error;
|
||||
}
|
||||
|
||||
|
|
@ -3428,6 +3419,7 @@ SHOW_VAR com_status_vars[]= {
|
|||
{"empty_query", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_EMPTY_QUERY]), SHOW_LONG_STATUS},
|
||||
{"execute_sql", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_EXECUTE]), SHOW_LONG_STATUS},
|
||||
{"flush", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_FLUSH]), SHOW_LONG_STATUS},
|
||||
{"get_diagnostics", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_GET_DIAGNOSTICS]), SHOW_LONG_STATUS},
|
||||
{"grant", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_GRANT]), SHOW_LONG_STATUS},
|
||||
{"ha_close", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HA_CLOSE]), SHOW_LONG_STATUS},
|
||||
{"ha_open", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HA_OPEN]), SHOW_LONG_STATUS},
|
||||
|
|
@ -4916,7 +4908,6 @@ int mysqld_main(int argc, char **argv)
|
|||
|
||||
sys_var_init();
|
||||
|
||||
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
|
||||
/*
|
||||
The performance schema needs to be initialized as early as possible,
|
||||
before to-be-instrumented objects of the server are initialized.
|
||||
|
|
@ -4944,22 +4935,30 @@ int mysqld_main(int argc, char **argv)
|
|||
my_charset_error_reporter= buffered_option_error_reporter;
|
||||
pfs_param.m_pfs_instrument= const_cast<char*>("");
|
||||
|
||||
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
|
||||
/*
|
||||
Initialize the array of performance schema instrument configurations.
|
||||
*/
|
||||
init_pfs_instrument_array();
|
||||
#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
|
||||
|
||||
ho_error= handle_options(&remaining_argc, &remaining_argv,
|
||||
(my_option*)(all_early_options.buffer),
|
||||
mysqld_get_one_option);
|
||||
delete_dynamic(&all_early_options);
|
||||
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
|
||||
if (ho_error == 0)
|
||||
{
|
||||
/* Add back the program name handle_options removes */
|
||||
remaining_argc++;
|
||||
remaining_argv--;
|
||||
if (pfs_param.m_enabled)
|
||||
if (pfs_param.m_enabled && !opt_help && !opt_bootstrap)
|
||||
{
|
||||
/* Add sizing hints from the server sizing parameters. */
|
||||
pfs_param.m_hints.m_table_definition_cache= table_def_size;
|
||||
pfs_param.m_hints.m_table_open_cache= table_cache_size;
|
||||
pfs_param.m_hints.m_max_connections= max_connections;
|
||||
pfs_param.m_hints.m_open_files_limit= open_files_limit;
|
||||
PSI_hook= initialize_performance_schema(&pfs_param);
|
||||
if (PSI_hook == NULL)
|
||||
{
|
||||
|
|
@ -6853,7 +6852,7 @@ static int show_slave_running(THD *thd, SHOW_VAR *var, char *buff)
|
|||
mysql_mutex_lock(&LOCK_active_mi);
|
||||
mi= master_info_index->
|
||||
get_master_info(&thd->variables.default_master_connection,
|
||||
MYSQL_ERROR::WARN_LEVEL_NOTE);
|
||||
Sql_condition::WARN_LEVEL_NOTE);
|
||||
if (mi)
|
||||
*((my_bool *)buff)= (my_bool) (mi->slave_running ==
|
||||
MYSQL_SLAVE_RUN_CONNECT &&
|
||||
|
|
@ -6873,7 +6872,7 @@ static int show_slave_received_heartbeats(THD *thd, SHOW_VAR *var, char *buff)
|
|||
mysql_mutex_lock(&LOCK_active_mi);
|
||||
mi= master_info_index->
|
||||
get_master_info(&thd->variables.default_master_connection,
|
||||
MYSQL_ERROR::WARN_LEVEL_NOTE);
|
||||
Sql_condition::WARN_LEVEL_NOTE);
|
||||
if (mi)
|
||||
*((longlong *)buff)= mi->received_heartbeats;
|
||||
else
|
||||
|
|
@ -6891,7 +6890,7 @@ static int show_heartbeat_period(THD *thd, SHOW_VAR *var, char *buff)
|
|||
mysql_mutex_lock(&LOCK_active_mi);
|
||||
mi= master_info_index->
|
||||
get_master_info(&thd->variables.default_master_connection,
|
||||
MYSQL_ERROR::WARN_LEVEL_NOTE);
|
||||
Sql_condition::WARN_LEVEL_NOTE);
|
||||
if (mi)
|
||||
sprintf(buff, "%.3f", mi->heartbeat_period);
|
||||
else
|
||||
|
|
@ -8892,6 +8891,9 @@ static PSI_file_info all_server_files[]=
|
|||
|
||||
PSI_stage_info stage_after_create= { 0, "After create", 0};
|
||||
PSI_stage_info stage_allocating_local_table= { 0, "allocating local table", 0};
|
||||
PSI_stage_info stage_alter_inplace_prepare= { 0, "preparing for alter table", 0};
|
||||
PSI_stage_info stage_alter_inplace= { 0, "altering table", 0};
|
||||
PSI_stage_info stage_alter_inplace_commit= { 0, "committing alter table to storage engine", 0};
|
||||
PSI_stage_info stage_changing_master= { 0, "Changing master", 0};
|
||||
PSI_stage_info stage_checking_master_version= { 0, "Checking master version", 0};
|
||||
PSI_stage_info stage_checking_permissions= { 0, "checking permissions", 0};
|
||||
|
|
|
|||
|
|
@ -306,6 +306,9 @@ void init_server_psi_keys();
|
|||
*/
|
||||
extern PSI_stage_info stage_after_create;
|
||||
extern PSI_stage_info stage_allocating_local_table;
|
||||
extern PSI_stage_info stage_alter_inplace_prepare;
|
||||
extern PSI_stage_info stage_alter_inplace;
|
||||
extern PSI_stage_info stage_alter_inplace_commit;
|
||||
extern PSI_stage_info stage_changing_master;
|
||||
extern PSI_stage_info stage_checking_master_version;
|
||||
extern PSI_stage_info stage_checking_permissions;
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@
|
|||
#include "key.h" // is_key_used, key_copy, key_cmp, key_restore
|
||||
#include "sql_parse.h" // check_stack_overrun
|
||||
#include "sql_partition.h" // get_part_id_func, PARTITION_ITERATOR,
|
||||
// struct partition_info
|
||||
// struct partition_info, NOT_A_PARTITION_ID
|
||||
#include "sql_base.h" // free_io_cache
|
||||
#include "records.h" // init_read_record, end_read_record
|
||||
#include <m_ctype.h>
|
||||
|
|
@ -3386,29 +3386,26 @@ static void dbug_print_singlepoint_range(SEL_ARG **start, uint num);
|
|||
#endif
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Perform partition pruning for a given table and condition.
|
||||
|
||||
SYNOPSIS
|
||||
prune_partitions()
|
||||
thd Thread handle
|
||||
table Table to perform partition pruning for
|
||||
pprune_cond Condition to use for partition pruning
|
||||
@param thd Thread handle
|
||||
@param table Table to perform partition pruning for
|
||||
@param pprune_cond Condition to use for partition pruning
|
||||
|
||||
DESCRIPTION
|
||||
This function assumes that all partitions are marked as unused when it
|
||||
is invoked. The function analyzes the condition, finds partitions that
|
||||
need to be used to retrieve the records that match the condition, and
|
||||
marks them as used by setting appropriate bit in part_info->used_partitions
|
||||
In the worst case all partitions are marked as used.
|
||||
@note This function assumes that lock_partitions are setup when it
|
||||
is invoked. The function analyzes the condition, finds partitions that
|
||||
need to be used to retrieve the records that match the condition, and
|
||||
marks them as used by setting appropriate bit in part_info->read_partitions
|
||||
In the worst case all partitions are marked as used. If the table is not
|
||||
yet locked, it will also unset bits in part_info->lock_partitions that is
|
||||
not set in read_partitions.
|
||||
|
||||
NOTE
|
||||
This function returns promptly if called for non-partitioned table.
|
||||
This function returns promptly if called for non-partitioned table.
|
||||
|
||||
RETURN
|
||||
TRUE We've inferred that no partitions need to be used (i.e. no table
|
||||
records will satisfy pprune_cond)
|
||||
FALSE Otherwise
|
||||
@return Operation status
|
||||
@retval true Failure
|
||||
@retval false Success
|
||||
*/
|
||||
|
||||
bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond)
|
||||
|
|
@ -3461,7 +3458,7 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond)
|
|||
thd->no_errors=1; // Don't warn about NULL
|
||||
thd->mem_root=&alloc;
|
||||
|
||||
bitmap_clear_all(&part_info->used_partitions);
|
||||
bitmap_clear_all(&part_info->read_partitions);
|
||||
|
||||
prune_param.key= prune_param.range_param.key_parts;
|
||||
SEL_TREE *tree;
|
||||
|
|
@ -3545,6 +3542,30 @@ end:
|
|||
thd->mem_root= range_par->old_root;
|
||||
free_root(&alloc,MYF(0)); // Return memory & allocator
|
||||
DBUG_RETURN(retval);
|
||||
/*
|
||||
Must be a subset of the locked partitions.
|
||||
lock_partitions contains the partitions marked by explicit partition
|
||||
selection (... t PARTITION (pX) ...) and we must only use partitions
|
||||
within that set.
|
||||
*/
|
||||
bitmap_intersect(&prune_param.part_info->read_partitions,
|
||||
&prune_param.part_info->lock_partitions);
|
||||
/*
|
||||
If not yet locked, also prune partitions to lock if not UPDATEing
|
||||
partition key fields. This will also prune lock_partitions if we are under
|
||||
LOCK TABLES, so prune away calls to start_stmt().
|
||||
TODO: enhance this prune locking to also allow pruning of
|
||||
'UPDATE t SET part_key = const WHERE cond_is_prunable' so it adds
|
||||
a lock for part_key partition.
|
||||
*/
|
||||
if (!thd->lex->is_query_tables_locked() &&
|
||||
!partition_key_modified(table, table->write_set))
|
||||
{
|
||||
bitmap_copy(&prune_param.part_info->lock_partitions,
|
||||
&prune_param.part_info->read_partitions);
|
||||
}
|
||||
if (bitmap_is_clear_all(&(prune_param.part_info->read_partitions)))
|
||||
table->all_partitions_pruned_away= true;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -3619,7 +3640,7 @@ static void mark_full_partition_used_no_parts(partition_info* part_info,
|
|||
{
|
||||
DBUG_ENTER("mark_full_partition_used_no_parts");
|
||||
DBUG_PRINT("enter", ("Mark partition %u as used", part_id));
|
||||
bitmap_set_bit(&part_info->used_partitions, part_id);
|
||||
bitmap_set_bit(&part_info->read_partitions, part_id);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
|
@ -3635,7 +3656,7 @@ static void mark_full_partition_used_with_parts(partition_info *part_info,
|
|||
for (; start != end; start++)
|
||||
{
|
||||
DBUG_PRINT("info", ("1:Mark subpartition %u as used", start));
|
||||
bitmap_set_bit(&part_info->used_partitions, start);
|
||||
bitmap_set_bit(&part_info->read_partitions, start);
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
|
@ -3663,7 +3684,7 @@ static int find_used_partitions_imerge_list(PART_PRUNE_PARAM *ppar,
|
|||
MY_BITMAP all_merges;
|
||||
uint bitmap_bytes;
|
||||
my_bitmap_map *bitmap_buf;
|
||||
uint n_bits= ppar->part_info->used_partitions.n_bits;
|
||||
uint n_bits= ppar->part_info->read_partitions.n_bits;
|
||||
bitmap_bytes= bitmap_buffer_size(n_bits);
|
||||
if (!(bitmap_buf= (my_bitmap_map*) alloc_root(ppar->range_param.mem_root,
|
||||
bitmap_bytes)))
|
||||
|
|
@ -3689,14 +3710,15 @@ static int find_used_partitions_imerge_list(PART_PRUNE_PARAM *ppar,
|
|||
}
|
||||
|
||||
if (res != -1)
|
||||
bitmap_intersect(&all_merges, &ppar->part_info->used_partitions);
|
||||
bitmap_intersect(&all_merges, &ppar->part_info->read_partitions);
|
||||
|
||||
|
||||
if (bitmap_is_clear_all(&all_merges))
|
||||
return 0;
|
||||
|
||||
bitmap_clear_all(&ppar->part_info->used_partitions);
|
||||
bitmap_clear_all(&ppar->part_info->read_partitions);
|
||||
}
|
||||
memcpy(ppar->part_info->used_partitions.bitmap, all_merges.bitmap,
|
||||
memcpy(ppar->part_info->read_partitions.bitmap, all_merges.bitmap,
|
||||
bitmap_bytes);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -4056,7 +4078,7 @@ int find_used_partitions(PART_PRUNE_PARAM *ppar, SEL_ARG *key_tree)
|
|||
{
|
||||
for (uint i= 0; i < ppar->part_info->num_subparts; i++)
|
||||
if (bitmap_is_set(&ppar->subparts_bitmap, i))
|
||||
bitmap_set_bit(&ppar->part_info->used_partitions,
|
||||
bitmap_set_bit(&ppar->part_info->read_partitions,
|
||||
part_id * ppar->part_info->num_subparts + i);
|
||||
}
|
||||
goto pop_and_go_right;
|
||||
|
|
@ -4118,7 +4140,7 @@ int find_used_partitions(PART_PRUNE_PARAM *ppar, SEL_ARG *key_tree)
|
|||
while ((part_id= ppar->part_iter.get_next(&ppar->part_iter)) !=
|
||||
NOT_A_PARTITION_ID)
|
||||
{
|
||||
bitmap_set_bit(&part_info->used_partitions,
|
||||
bitmap_set_bit(&part_info->read_partitions,
|
||||
part_id * part_info->num_subparts + subpart_id);
|
||||
}
|
||||
res= 1; /* Some partitions were marked as used */
|
||||
|
|
@ -4204,7 +4226,8 @@ pop_and_go_right:
|
|||
|
||||
static void mark_all_partitions_as_used(partition_info *part_info)
|
||||
{
|
||||
bitmap_set_all(&part_info->used_partitions);
|
||||
bitmap_copy(&(part_info->read_partitions),
|
||||
&(part_info->lock_partitions));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2370,7 +2370,7 @@ bool find_eq_ref_candidate(TABLE *table, table_map sj_inner_tables)
|
|||
keyuse++;
|
||||
} while (keyuse->key == key && keyuse->table == table);
|
||||
|
||||
if (bound_parts == PREV_BITS(uint, keyinfo->key_parts))
|
||||
if (bound_parts == PREV_BITS(uint, keyinfo->user_defined_key_parts))
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
|
|
@ -3521,7 +3521,7 @@ bool setup_sj_materialization_part2(JOIN_TAB *sjm_tab)
|
|||
KEY *tmp_key; /* The only index on the temporary table. */
|
||||
uint tmp_key_parts; /* Number of keyparts in tmp_key. */
|
||||
tmp_key= sjm->table->key_info;
|
||||
tmp_key_parts= tmp_key->key_parts;
|
||||
tmp_key_parts= tmp_key->user_defined_key_parts;
|
||||
|
||||
/*
|
||||
Create/initialize everything we will need to index lookups into the
|
||||
|
|
@ -4057,7 +4057,7 @@ SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd)
|
|||
table->key_info=keyinfo;
|
||||
keyinfo->key_part=key_part_info;
|
||||
keyinfo->flags=HA_NOSAME;
|
||||
keyinfo->usable_key_parts= keyinfo->key_parts= 1;
|
||||
keyinfo->usable_key_parts= keyinfo->user_defined_key_parts= 1;
|
||||
keyinfo->key_length=0;
|
||||
keyinfo->rec_per_key=0;
|
||||
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
|
||||
|
|
|
|||
|
|
@ -464,7 +464,7 @@ int opt_sum_query(THD *thd,
|
|||
}
|
||||
|
||||
if (thd->is_error())
|
||||
DBUG_RETURN(thd->stmt_da->sql_errno());
|
||||
DBUG_RETURN(thd->get_stmt_da()->sql_errno());
|
||||
|
||||
/*
|
||||
If we have a where clause, we can only ignore searching in the
|
||||
|
|
|
|||
|
|
@ -1563,7 +1563,7 @@ Dep_value_table *Dep_analysis_context::create_table_value(TABLE *table)
|
|||
if (key->flags & HA_NOSAME)
|
||||
{
|
||||
Dep_module_key *key_dep;
|
||||
if (!(key_dep= new Dep_module_key(tbl_dep, i, key->key_parts)))
|
||||
if (!(key_dep= new Dep_module_key(tbl_dep, i, key->user_defined_key_parts)))
|
||||
return NULL;
|
||||
*key_list= key_dep;
|
||||
key_list= &(key_dep->next_table_key);
|
||||
|
|
|
|||
|
|
@ -23,10 +23,12 @@
|
|||
#include "sql_priv.h"
|
||||
// Required to get server definitions for mysql/plugin.h right
|
||||
#include "sql_plugin.h"
|
||||
#include "sql_partition.h" /* partition_info.h: LIST_PART_ENTRY */
|
||||
#include "sql_partition.h" // partition_info.h: LIST_PART_ENTRY
|
||||
// NOT_A_PARTITION_ID
|
||||
#include "partition_info.h"
|
||||
#include "sql_parse.h" // test_if_data_home_dir
|
||||
#include "sql_acl.h" // *_ACL
|
||||
#include "sql_base.h" // fill_record
|
||||
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
#include "ha_partition.h"
|
||||
|
|
@ -34,17 +36,21 @@
|
|||
|
||||
partition_info *partition_info::get_clone()
|
||||
{
|
||||
DBUG_ENTER("partition_info::get_clone");
|
||||
if (!this)
|
||||
return 0;
|
||||
DBUG_RETURN(NULL);
|
||||
List_iterator<partition_element> part_it(partitions);
|
||||
partition_element *part;
|
||||
partition_info *clone= new partition_info();
|
||||
if (!clone)
|
||||
{
|
||||
mem_alloc_error(sizeof(partition_info));
|
||||
return NULL;
|
||||
DBUG_RETURN(NULL);
|
||||
}
|
||||
memcpy(clone, this, sizeof(partition_info));
|
||||
memset(&(clone->read_partitions), 0, sizeof(clone->read_partitions));
|
||||
memset(&(clone->lock_partitions), 0, sizeof(clone->lock_partitions));
|
||||
clone->bitmaps_are_initialized= FALSE;
|
||||
clone->partitions.empty();
|
||||
|
||||
while ((part= (part_it++)))
|
||||
|
|
@ -55,7 +61,7 @@ partition_info *partition_info::get_clone()
|
|||
if (!part_clone)
|
||||
{
|
||||
mem_alloc_error(sizeof(partition_element));
|
||||
return NULL;
|
||||
DBUG_RETURN(NULL);
|
||||
}
|
||||
memcpy(part_clone, part, sizeof(partition_element));
|
||||
part_clone->subpartitions.empty();
|
||||
|
|
@ -65,16 +71,427 @@ partition_info *partition_info::get_clone()
|
|||
if (!subpart_clone)
|
||||
{
|
||||
mem_alloc_error(sizeof(partition_element));
|
||||
return NULL;
|
||||
DBUG_RETURN(NULL);
|
||||
}
|
||||
memcpy(subpart_clone, subpart, sizeof(partition_element));
|
||||
part_clone->subpartitions.push_back(subpart_clone);
|
||||
}
|
||||
clone->partitions.push_back(part_clone);
|
||||
}
|
||||
return clone;
|
||||
DBUG_RETURN(clone);
|
||||
}
|
||||
|
||||
/**
|
||||
Mark named [sub]partition to be used/locked.
|
||||
|
||||
@param part_name Partition name to match.
|
||||
@param length Partition name length.
|
||||
|
||||
@return Success if partition found
|
||||
@retval true Partition found
|
||||
@retval false Partition not found
|
||||
*/
|
||||
|
||||
bool partition_info::add_named_partition(const char *part_name,
|
||||
uint length)
|
||||
{
|
||||
HASH *part_name_hash;
|
||||
PART_NAME_DEF *part_def;
|
||||
Partition_share *part_share;
|
||||
DBUG_ENTER("partition_info::add_named_partition");
|
||||
DBUG_ASSERT(table && table->s && table->s->ha_share);
|
||||
part_share= static_cast<Partition_share*>((table->s->ha_share));
|
||||
DBUG_ASSERT(part_share->partition_name_hash_initialized);
|
||||
part_name_hash= &part_share->partition_name_hash;
|
||||
DBUG_ASSERT(part_name_hash->records);
|
||||
|
||||
part_def= (PART_NAME_DEF*) my_hash_search(part_name_hash,
|
||||
(const uchar*) part_name,
|
||||
length);
|
||||
if (!part_def)
|
||||
{
|
||||
// my_error(ER_UNKNOWN_PARTITION, MYF(0), part_name, table->alias);
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
|
||||
if (part_def->is_subpart)
|
||||
{
|
||||
bitmap_set_bit(&read_partitions, part_def->part_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_sub_partitioned())
|
||||
{
|
||||
/* Mark all subpartitions in the partition */
|
||||
uint j, start= part_def->part_id;
|
||||
uint end= start + num_subparts;
|
||||
for (j= start; j < end; j++)
|
||||
bitmap_set_bit(&read_partitions, j);
|
||||
}
|
||||
else
|
||||
bitmap_set_bit(&read_partitions, part_def->part_id);
|
||||
}
|
||||
DBUG_PRINT("info", ("Found partition %u is_subpart %d for name %s",
|
||||
part_def->part_id, part_def->is_subpart,
|
||||
part_name));
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Mark named [sub]partition to be used/locked.
|
||||
|
||||
@param part_elem Partition element that matched.
|
||||
*/
|
||||
|
||||
bool partition_info::set_named_partition_bitmap(const char *part_name,
|
||||
uint length)
|
||||
{
|
||||
DBUG_ENTER("partition_info::set_named_partition_bitmap");
|
||||
bitmap_clear_all(&read_partitions);
|
||||
if (add_named_partition(part_name, length))
|
||||
DBUG_RETURN(true);
|
||||
bitmap_copy(&lock_partitions, &read_partitions);
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Prune away partitions not mentioned in the PARTITION () clause,
|
||||
if used.
|
||||
|
||||
@param table_list Table list pointing to table to prune.
|
||||
|
||||
@return Operation status
|
||||
@retval true Failure
|
||||
@retval false Success
|
||||
*/
|
||||
bool partition_info::prune_partition_bitmaps(TABLE_LIST *table_list)
|
||||
{
|
||||
List_iterator<String> partition_names_it(*(table_list->partition_names));
|
||||
uint num_names= table_list->partition_names->elements;
|
||||
uint i= 0;
|
||||
DBUG_ENTER("partition_info::prune_partition_bitmaps");
|
||||
|
||||
if (num_names < 1)
|
||||
DBUG_RETURN(true);
|
||||
|
||||
/*
|
||||
TODO: When adding support for FK in partitioned tables, the referenced
|
||||
table must probably lock all partitions for read, and also write depending
|
||||
of ON DELETE/UPDATE.
|
||||
*/
|
||||
bitmap_clear_all(&read_partitions);
|
||||
|
||||
/* No check for duplicate names or overlapping partitions/subpartitions. */
|
||||
|
||||
DBUG_PRINT("info", ("Searching through partition_name_hash"));
|
||||
do
|
||||
{
|
||||
String *part_name_str= partition_names_it++;
|
||||
if (add_named_partition(part_name_str->c_ptr(), part_name_str->length()))
|
||||
DBUG_RETURN(true);
|
||||
} while (++i < num_names);
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Set read/lock_partitions bitmap over non pruned partitions
|
||||
|
||||
@param table_list Possible TABLE_LIST which can contain
|
||||
list of partition names to query
|
||||
|
||||
@return Operation status
|
||||
@retval FALSE OK
|
||||
@retval TRUE Failed to allocate memory for bitmap or list of partitions
|
||||
did not match
|
||||
|
||||
@note OK to call multiple times without the need for free_bitmaps.
|
||||
*/
|
||||
|
||||
bool partition_info::set_partition_bitmaps(TABLE_LIST *table_list)
|
||||
{
|
||||
DBUG_ENTER("partition_info::set_partition_bitmaps");
|
||||
|
||||
DBUG_ASSERT(bitmaps_are_initialized);
|
||||
DBUG_ASSERT(table);
|
||||
is_pruning_completed= false;
|
||||
if (!bitmaps_are_initialized)
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
if (table_list &&
|
||||
table_list->partition_names &&
|
||||
table_list->partition_names->elements)
|
||||
{
|
||||
if (table->s->db_type()->partition_flags() & HA_USE_AUTO_PARTITION)
|
||||
{
|
||||
/*
|
||||
Don't allow PARTITION () clause on a NDB tables yet.
|
||||
TODO: Add partition name handling to NDB/partition_info.
|
||||
which is currently ha_partition specific.
|
||||
*/
|
||||
my_error(ER_PARTITION_CLAUSE_ON_NONPARTITIONED, MYF(0));
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
if (prune_partition_bitmaps(table_list))
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
bitmap_set_all(&read_partitions);
|
||||
DBUG_PRINT("info", ("Set all partitions"));
|
||||
}
|
||||
bitmap_copy(&lock_partitions, &read_partitions);
|
||||
DBUG_ASSERT(bitmap_get_first_set(&lock_partitions) != MY_BIT_NONE);
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Checks if possible to do prune partitions on insert.
|
||||
|
||||
@param thd Thread context
|
||||
@param duplic How to handle duplicates
|
||||
@param update In case of ON DUPLICATE UPDATE, default function fields
|
||||
@param update_fields In case of ON DUPLICATE UPDATE, which fields to update
|
||||
@param fields Listed fields
|
||||
@param empty_values True if values is empty (only defaults)
|
||||
@param[out] prune_needs_default_values Set on return if copying of default
|
||||
values is needed
|
||||
@param[out] can_prune_partitions Enum showing if possible to prune
|
||||
@param[inout] used_partitions If possible to prune the bitmap
|
||||
is initialized and cleared
|
||||
|
||||
@return Operation status
|
||||
@retval false Success
|
||||
@retval true Failure
|
||||
*/
|
||||
|
||||
bool partition_info::can_prune_insert(THD* thd,
|
||||
enum_duplicates duplic,
|
||||
COPY_INFO &update,
|
||||
List<Item> &update_fields,
|
||||
List<Item> &fields,
|
||||
bool empty_values,
|
||||
enum_can_prune *can_prune_partitions,
|
||||
bool *prune_needs_default_values,
|
||||
MY_BITMAP *used_partitions)
|
||||
{
|
||||
uint32 *bitmap_buf;
|
||||
uint bitmap_bytes;
|
||||
uint num_partitions= 0;
|
||||
*can_prune_partitions= PRUNE_NO;
|
||||
DBUG_ASSERT(bitmaps_are_initialized);
|
||||
DBUG_ENTER("partition_info::can_prune_insert");
|
||||
|
||||
if (table->s->db_type()->partition_flags() & HA_USE_AUTO_PARTITION)
|
||||
DBUG_RETURN(false); /* Should not insert prune NDB tables */
|
||||
|
||||
/*
|
||||
If under LOCK TABLES pruning will skip start_stmt instead of external_lock
|
||||
for unused partitions.
|
||||
|
||||
Cannot prune if there are BEFORE INSERT triggers that changes any
|
||||
partitioning column, since they may change the row to be in another
|
||||
partition.
|
||||
*/
|
||||
if (table->triggers &&
|
||||
table->triggers->has_triggers(TRG_EVENT_INSERT, TRG_ACTION_BEFORE) &&
|
||||
table->triggers->is_fields_updated_in_trigger(&full_part_field_set,
|
||||
TRG_EVENT_INSERT,
|
||||
TRG_ACTION_BEFORE))
|
||||
DBUG_RETURN(false);
|
||||
|
||||
if (table->found_next_number_field)
|
||||
{
|
||||
/*
|
||||
If the field is used in the partitioning expression, we cannot prune.
|
||||
TODO: If all rows have not null values and
|
||||
is not 0 (with NO_AUTO_VALUE_ON_ZERO sql_mode), then pruning is possible!
|
||||
*/
|
||||
if (bitmap_is_set(&full_part_field_set,
|
||||
table->found_next_number_field->field_index))
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
|
||||
/*
|
||||
If updating a field in the partitioning expression, we cannot prune.
|
||||
|
||||
Note: TIMESTAMP_AUTO_SET_ON_INSERT is handled by converting Item_null
|
||||
to the start time of the statement. Which will be the same as in
|
||||
write_row(). So pruning of TIMESTAMP DEFAULT CURRENT_TIME will work.
|
||||
But TIMESTAMP_AUTO_SET_ON_UPDATE cannot be pruned if the timestamp
|
||||
column is a part of any part/subpart expression.
|
||||
*/
|
||||
if (duplic == DUP_UPDATE)
|
||||
{
|
||||
/*
|
||||
TODO: add check for static update values, which can be pruned.
|
||||
*/
|
||||
if (is_field_in_part_expr(update_fields))
|
||||
DBUG_RETURN(false);
|
||||
|
||||
/*
|
||||
Cannot prune if there are BEFORE UPDATE triggers that changes any
|
||||
partitioning column, since they may change the row to be in another
|
||||
partition.
|
||||
*/
|
||||
if (table->triggers &&
|
||||
table->triggers->has_triggers(TRG_EVENT_UPDATE,
|
||||
TRG_ACTION_BEFORE) &&
|
||||
table->triggers->is_fields_updated_in_trigger(&full_part_field_set,
|
||||
TRG_EVENT_UPDATE,
|
||||
TRG_ACTION_BEFORE))
|
||||
{
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
If not all partitioning fields are given,
|
||||
we also must set all non given partitioning fields
|
||||
to get correct defaults.
|
||||
TODO: If any gain, we could enhance this by only copy the needed default
|
||||
fields by
|
||||
1) check which fields needs to be set.
|
||||
2) only copy those fields from the default record.
|
||||
*/
|
||||
*prune_needs_default_values= false;
|
||||
if (fields.elements)
|
||||
{
|
||||
if (!is_full_part_expr_in_fields(fields))
|
||||
*prune_needs_default_values= true;
|
||||
}
|
||||
else if (empty_values)
|
||||
{
|
||||
*prune_needs_default_values= true; // like 'INSERT INTO t () VALUES ()'
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
In case of INSERT INTO t VALUES (...) we must get values for
|
||||
all fields in table from VALUES (...) part, so no defaults
|
||||
are needed.
|
||||
*/
|
||||
}
|
||||
|
||||
/* Pruning possible, have to initialize the used_partitions bitmap. */
|
||||
num_partitions= lock_partitions.n_bits;
|
||||
bitmap_bytes= bitmap_buffer_size(num_partitions);
|
||||
if (!(bitmap_buf= (uint32*) thd->alloc(bitmap_bytes)))
|
||||
{
|
||||
mem_alloc_error(bitmap_bytes);
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
/* Also clears all bits. */
|
||||
if (bitmap_init(used_partitions, bitmap_buf, num_partitions, false))
|
||||
{
|
||||
/* purecov: begin deadcode */
|
||||
/* Cannot happen, due to pre-alloc. */
|
||||
mem_alloc_error(bitmap_bytes);
|
||||
DBUG_RETURN(true);
|
||||
/* purecov: end */
|
||||
}
|
||||
/*
|
||||
If no partitioning field in set (e.g. defaults) check pruning only once.
|
||||
*/
|
||||
if (fields.elements &&
|
||||
!is_field_in_part_expr(fields))
|
||||
*can_prune_partitions= PRUNE_DEFAULTS;
|
||||
else
|
||||
*can_prune_partitions= PRUNE_YES;
|
||||
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Mark the partition, the record belongs to, as used.
|
||||
|
||||
@param fields Fields to set
|
||||
@param values Values to use
|
||||
@param info COPY_INFO used for default values handling
|
||||
@param copy_default_values True if we should copy default values
|
||||
@param used_partitions Bitmap to set
|
||||
|
||||
@returns Operational status
|
||||
@retval false Success
|
||||
@retval true Failure
|
||||
*/
|
||||
|
||||
bool partition_info::set_used_partition(List<Item> &fields,
|
||||
List<Item> &values,
|
||||
COPY_INFO &info,
|
||||
bool copy_default_values,
|
||||
MY_BITMAP *used_partitions)
|
||||
{
|
||||
THD *thd= table->in_use;
|
||||
uint32 part_id;
|
||||
longlong func_value;
|
||||
Dummy_error_handler error_handler;
|
||||
bool ret= true;
|
||||
DBUG_ENTER("set_partition");
|
||||
DBUG_ASSERT(thd);
|
||||
|
||||
/* Only allow checking of constant values */
|
||||
List_iterator_fast<Item> v(values);
|
||||
Item *item;
|
||||
thd->push_internal_handler(&error_handler);
|
||||
while ((item= v++))
|
||||
{
|
||||
if (!item->const_item())
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (copy_default_values)
|
||||
restore_record(table,s->default_values);
|
||||
|
||||
if (fields.elements || !values.elements)
|
||||
{
|
||||
if (fill_record(thd, table, fields, values, false))
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fill_record(thd, table, table->field, values, false, false))
|
||||
goto err;
|
||||
}
|
||||
DBUG_ASSERT(!table->auto_increment_field_not_null);
|
||||
|
||||
/*
|
||||
Evaluate DEFAULT functions like CURRENT_TIMESTAMP.
|
||||
TODO: avoid setting non partitioning fields default value, to avoid
|
||||
overhead. Not yet done, since mostly only one DEFAULT function per
|
||||
table, or at least very few such columns.
|
||||
*/
|
||||
// if (info.function_defaults_apply_on_columns(&full_part_field_set))
|
||||
// info.set_function_defaults(table);
|
||||
|
||||
{
|
||||
/*
|
||||
This function is used in INSERT; 'values' are supplied by user,
|
||||
or are default values, not values read from a table, so read_set is
|
||||
irrelevant.
|
||||
*/
|
||||
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
|
||||
const int rc= get_partition_id(this, &part_id, &func_value);
|
||||
dbug_tmp_restore_column_map(table->read_set, old_map);
|
||||
if (rc)
|
||||
goto err;
|
||||
}
|
||||
|
||||
DBUG_PRINT("info", ("Insert into partition %u", part_id));
|
||||
bitmap_set_bit(used_partitions, part_id);
|
||||
ret= false;
|
||||
|
||||
err:
|
||||
thd->pop_internal_handler();
|
||||
DBUG_RETURN(ret);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Create a memory area where default partition names are stored and fill it
|
||||
up with the names.
|
||||
|
|
@ -160,8 +577,9 @@ void partition_info::set_show_version_string(String *packet)
|
|||
|
||||
/*
|
||||
Create a unique name for the subpartition as part_name'sp''subpart_no'
|
||||
|
||||
SYNOPSIS
|
||||
create_subpartition_name()
|
||||
create_default_subpartition_name()
|
||||
subpart_no Number of subpartition
|
||||
part_name Name of partition
|
||||
RETURN VALUES
|
||||
|
|
@ -169,12 +587,12 @@ void partition_info::set_show_version_string(String *packet)
|
|||
0 Memory allocation error
|
||||
*/
|
||||
|
||||
char *partition_info::create_subpartition_name(uint subpart_no,
|
||||
char *partition_info::create_default_subpartition_name(uint subpart_no,
|
||||
const char *part_name)
|
||||
{
|
||||
uint size_alloc= strlen(part_name) + MAX_PART_NAME_SIZE;
|
||||
char *ptr= (char*) sql_calloc(size_alloc);
|
||||
DBUG_ENTER("create_subpartition_name");
|
||||
DBUG_ENTER("create_default_subpartition_name");
|
||||
|
||||
if (likely(ptr != NULL))
|
||||
{
|
||||
|
|
@ -320,7 +738,8 @@ bool partition_info::set_up_default_subpartitions(handler *file,
|
|||
if (likely(subpart_elem != 0 &&
|
||||
(!part_elem->subpartitions.push_back(subpart_elem))))
|
||||
{
|
||||
char *ptr= create_subpartition_name(j, part_elem->partition_name);
|
||||
char *ptr= create_default_subpartition_name(j,
|
||||
part_elem->partition_name);
|
||||
if (!ptr)
|
||||
goto end;
|
||||
subpart_elem->engine_type= default_engine_type;
|
||||
|
|
@ -380,7 +799,7 @@ bool partition_info::set_up_defaults_for_partitioning(handler *file,
|
|||
Support routine for check_partition_info
|
||||
|
||||
SYNOPSIS
|
||||
has_unique_fields
|
||||
find_duplicate_field
|
||||
no parameters
|
||||
|
||||
RETURN VALUE
|
||||
|
|
@ -391,13 +810,13 @@ bool partition_info::set_up_defaults_for_partitioning(handler *file,
|
|||
Check that the user haven't defined the same field twice in
|
||||
key or column list partitioning.
|
||||
*/
|
||||
char* partition_info::has_unique_fields()
|
||||
char* partition_info::find_duplicate_field()
|
||||
{
|
||||
char *field_name_outer, *field_name_inner;
|
||||
List_iterator<char> it_outer(part_field_list);
|
||||
uint num_fields= part_field_list.elements;
|
||||
uint i,j;
|
||||
DBUG_ENTER("partition_info::has_unique_fields");
|
||||
DBUG_ENTER("partition_info::find_duplicate_field");
|
||||
|
||||
for (i= 0; i < num_fields; i++)
|
||||
{
|
||||
|
|
@ -419,88 +838,149 @@ char* partition_info::has_unique_fields()
|
|||
DBUG_RETURN(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
A support function to check if a partition element's name is unique
|
||||
|
||||
SYNOPSIS
|
||||
has_unique_name()
|
||||
partition_element element to check
|
||||
|
||||
RETURN VALUES
|
||||
TRUE Has unique name
|
||||
FALSE Doesn't
|
||||
/**
|
||||
@brief Get part_elem and part_id from partition name
|
||||
|
||||
@param partition_name Name of partition to search for.
|
||||
@param file_name[out] Partition file name (part after table name,
|
||||
#P#<part>[#SP#<subpart>]), skipped if NULL.
|
||||
@param part_id[out] Id of found partition or NOT_A_PARTITION_ID.
|
||||
|
||||
@retval Pointer to part_elem of [sub]partition, if not found NULL
|
||||
|
||||
@note Since names of partitions AND subpartitions must be unique,
|
||||
this function searches both partitions and subpartitions and if name of
|
||||
a partition is given for a subpartitioned table, part_elem will be
|
||||
the partition, but part_id will be NOT_A_PARTITION_ID and file_name not set.
|
||||
*/
|
||||
|
||||
bool partition_info::has_unique_name(partition_element *element)
|
||||
partition_element *partition_info::get_part_elem(const char *partition_name,
|
||||
char *file_name,
|
||||
uint32 *part_id)
|
||||
{
|
||||
DBUG_ENTER("partition_info::has_unique_name");
|
||||
|
||||
const char *name_to_check= element->partition_name;
|
||||
List_iterator<partition_element> parts_it(partitions);
|
||||
|
||||
partition_element *el;
|
||||
while ((el= (parts_it++)))
|
||||
List_iterator<partition_element> part_it(partitions);
|
||||
uint i= 0;
|
||||
DBUG_ENTER("partition_info::get_part_elem");
|
||||
DBUG_ASSERT(part_id);
|
||||
*part_id= NOT_A_PARTITION_ID;
|
||||
do
|
||||
{
|
||||
if (!(my_strcasecmp(system_charset_info, el->partition_name,
|
||||
name_to_check)) && el != element)
|
||||
DBUG_RETURN(FALSE);
|
||||
|
||||
if (!el->subpartitions.is_empty())
|
||||
partition_element *part_elem= part_it++;
|
||||
if (is_sub_partitioned())
|
||||
{
|
||||
partition_element *sub_el;
|
||||
List_iterator<partition_element> subparts_it(el->subpartitions);
|
||||
while ((sub_el= (subparts_it++)))
|
||||
List_iterator<partition_element> sub_part_it(part_elem->subpartitions);
|
||||
uint j= 0;
|
||||
do
|
||||
{
|
||||
if (!(my_strcasecmp(system_charset_info, sub_el->partition_name,
|
||||
name_to_check)) && sub_el != element)
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
partition_element *sub_part_elem= sub_part_it++;
|
||||
if (!my_strcasecmp(system_charset_info,
|
||||
sub_part_elem->partition_name, partition_name))
|
||||
{
|
||||
if (file_name)
|
||||
create_subpartition_name(file_name, "",
|
||||
part_elem->partition_name,
|
||||
partition_name,
|
||||
NORMAL_PART_NAME);
|
||||
*part_id= j + (i * num_subparts);
|
||||
DBUG_RETURN(sub_part_elem);
|
||||
}
|
||||
} while (++j < num_subparts);
|
||||
|
||||
/* Naming a partition (first level) on a subpartitioned table. */
|
||||
if (!my_strcasecmp(system_charset_info,
|
||||
part_elem->partition_name, partition_name))
|
||||
DBUG_RETURN(part_elem);
|
||||
}
|
||||
}
|
||||
DBUG_RETURN(TRUE);
|
||||
else if (!my_strcasecmp(system_charset_info,
|
||||
part_elem->partition_name, partition_name))
|
||||
{
|
||||
if (file_name)
|
||||
create_partition_name(file_name, "", partition_name,
|
||||
NORMAL_PART_NAME, TRUE);
|
||||
*part_id= i;
|
||||
DBUG_RETURN(part_elem);
|
||||
}
|
||||
} while (++i < num_parts);
|
||||
DBUG_RETURN(NULL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Helper function to find_duplicate_name.
|
||||
*/
|
||||
|
||||
static const char *get_part_name_from_elem(const char *name, size_t *length,
|
||||
my_bool not_used __attribute__((unused)))
|
||||
{
|
||||
*length= strlen(name);
|
||||
return name;
|
||||
}
|
||||
|
||||
/*
|
||||
A support function to check partition names for duplication in a
|
||||
partitioned table
|
||||
|
||||
SYNOPSIS
|
||||
has_unique_names()
|
||||
find_duplicate_name()
|
||||
|
||||
RETURN VALUES
|
||||
TRUE Has unique part and subpart names
|
||||
FALSE Doesn't
|
||||
NULL Has unique part and subpart names
|
||||
!NULL Pointer to duplicated name
|
||||
|
||||
DESCRIPTION
|
||||
Checks that the list of names in the partitions doesn't contain any
|
||||
duplicated names.
|
||||
*/
|
||||
|
||||
char *partition_info::has_unique_names()
|
||||
char *partition_info::find_duplicate_name()
|
||||
{
|
||||
DBUG_ENTER("partition_info::has_unique_names");
|
||||
|
||||
HASH partition_names;
|
||||
uint max_names;
|
||||
const uchar *curr_name= NULL;
|
||||
List_iterator<partition_element> parts_it(partitions);
|
||||
partition_element *p_elem;
|
||||
|
||||
partition_element *el;
|
||||
while ((el= (parts_it++)))
|
||||
DBUG_ENTER("partition_info::find_duplicate_name");
|
||||
|
||||
/*
|
||||
TODO: If table->s->ha_part_data->partition_name_hash.elements is > 0,
|
||||
then we could just return NULL, but that has not been verified.
|
||||
And this only happens when in ALTER TABLE with full table copy.
|
||||
*/
|
||||
|
||||
max_names= num_parts;
|
||||
if (is_sub_partitioned())
|
||||
max_names+= num_parts * num_subparts;
|
||||
if (my_hash_init(&partition_names, system_charset_info, max_names, 0, 0,
|
||||
(my_hash_get_key) get_part_name_from_elem, 0, HASH_UNIQUE))
|
||||
{
|
||||
if (! has_unique_name(el))
|
||||
DBUG_RETURN(el->partition_name);
|
||||
|
||||
if (!el->subpartitions.is_empty())
|
||||
DBUG_ASSERT(0);
|
||||
curr_name= (const uchar*) "Internal failure";
|
||||
goto error;
|
||||
}
|
||||
while ((p_elem= (parts_it++)))
|
||||
{
|
||||
curr_name= (const uchar*) p_elem->partition_name;
|
||||
if (my_hash_insert(&partition_names, curr_name))
|
||||
goto error;
|
||||
|
||||
if (!p_elem->subpartitions.is_empty())
|
||||
{
|
||||
List_iterator<partition_element> subparts_it(el->subpartitions);
|
||||
partition_element *subel;
|
||||
while ((subel= (subparts_it++)))
|
||||
List_iterator<partition_element> subparts_it(p_elem->subpartitions);
|
||||
partition_element *subp_elem;
|
||||
while ((subp_elem= (subparts_it++)))
|
||||
{
|
||||
if (! has_unique_name(subel))
|
||||
DBUG_RETURN(subel->partition_name);
|
||||
curr_name= (const uchar*) subp_elem->partition_name;
|
||||
if (my_hash_insert(&partition_names, curr_name))
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
my_hash_free(&partition_names);
|
||||
DBUG_RETURN(NULL);
|
||||
error:
|
||||
my_hash_free(&partition_names);
|
||||
DBUG_RETURN((char*) curr_name);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1058,11 +1538,11 @@ static void warn_if_dir_in_part_elem(THD *thd, partition_element *part_elem)
|
|||
#endif
|
||||
{
|
||||
if (part_elem->data_file_name)
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
WARN_OPTION_IGNORED, ER(WARN_OPTION_IGNORED),
|
||||
"DATA DIRECTORY");
|
||||
if (part_elem->index_file_name)
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
WARN_OPTION_IGNORED, ER(WARN_OPTION_IGNORED),
|
||||
"INDEX DIRECTORY");
|
||||
part_elem->data_file_name= part_elem->index_file_name= NULL;
|
||||
|
|
@ -1188,12 +1668,12 @@ bool partition_info::check_partition_info(THD *thd, handlerton **eng_type,
|
|||
}
|
||||
|
||||
if (part_field_list.elements > 0 &&
|
||||
(same_name= has_unique_fields()))
|
||||
(same_name= find_duplicate_field()))
|
||||
{
|
||||
my_error(ER_SAME_NAME_PARTITION_FIELD, MYF(0), same_name);
|
||||
goto end;
|
||||
}
|
||||
if ((same_name= has_unique_names()))
|
||||
if ((same_name= find_duplicate_name()))
|
||||
{
|
||||
my_error(ER_SAME_NAME_PARTITION, MYF(0), same_name);
|
||||
goto end;
|
||||
|
|
@ -1653,6 +2133,71 @@ void partition_info::report_part_expr_error(bool use_subpart_expr)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
Check if fields are in the partitioning expression.
|
||||
|
||||
@param fields List of Items (fields)
|
||||
|
||||
@return True if any field in the fields list is used by a partitioning expr.
|
||||
@retval true At least one field in the field list is found.
|
||||
@retval false No field is within any partitioning expression.
|
||||
*/
|
||||
|
||||
bool partition_info::is_field_in_part_expr(List<Item> &fields)
|
||||
{
|
||||
List_iterator<Item> it(fields);
|
||||
Item *item;
|
||||
Item_field *field;
|
||||
DBUG_ENTER("is_fields_in_part_expr");
|
||||
while ((item= it++))
|
||||
{
|
||||
field= item->field_for_view_update();
|
||||
DBUG_ASSERT(field->field->table == table);
|
||||
if (bitmap_is_set(&full_part_field_set, field->field->field_index))
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Check if all partitioning fields are included.
|
||||
*/
|
||||
|
||||
bool partition_info::is_full_part_expr_in_fields(List<Item> &fields)
|
||||
{
|
||||
Field **part_field= full_part_field_array;
|
||||
DBUG_ASSERT(*part_field);
|
||||
DBUG_ENTER("is_full_part_expr_in_fields");
|
||||
/*
|
||||
It is very seldom many fields in full_part_field_array, so it is OK
|
||||
to loop over all of them instead of creating a bitmap fields argument
|
||||
to compare with.
|
||||
*/
|
||||
do
|
||||
{
|
||||
List_iterator<Item> it(fields);
|
||||
Item *item;
|
||||
Item_field *field;
|
||||
bool found= false;
|
||||
|
||||
while ((item= it++))
|
||||
{
|
||||
field= item->field_for_view_update();
|
||||
DBUG_ASSERT(field->field->table == table);
|
||||
if (*part_field == field->field)
|
||||
{
|
||||
found= true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
DBUG_RETURN(false);
|
||||
} while (*(++part_field));
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Create a new column value in current list with maxvalue
|
||||
Called from parser
|
||||
|
|
|
|||
|
|
@ -20,10 +20,11 @@
|
|||
#pragma interface /* gcc class implementation */
|
||||
#endif
|
||||
|
||||
#include "sql_class.h"
|
||||
#include "partition_element.h"
|
||||
|
||||
class partition_info;
|
||||
|
||||
struct TABLE_LIST;
|
||||
/* Some function typedefs */
|
||||
typedef int (*get_part_id_func)(partition_info *part_info,
|
||||
uint32 *part_id,
|
||||
|
|
@ -111,14 +112,30 @@ public:
|
|||
struct st_ddl_log_memory_entry *frm_log_entry;
|
||||
|
||||
/*
|
||||
A bitmap of partitions used by the current query.
|
||||
Bitmaps of partitions used by the current query.
|
||||
* read_partitions - partitions to be used for reading.
|
||||
* lock_partitions - partitions that must be locked (read or write).
|
||||
Usually read_partitions is the same set as lock_partitions, but
|
||||
in case of UPDATE the WHERE clause can limit the read_partitions set,
|
||||
but not neccesarily the lock_partitions set.
|
||||
Usage pattern:
|
||||
* The handler->extra(HA_EXTRA_RESET) call at query start/end sets all
|
||||
partitions to be unused.
|
||||
* Before index/rnd_init(), partition pruning code sets the bits for used
|
||||
partitions.
|
||||
* Initialized in ha_partition::open().
|
||||
* read+lock_partitions is set according to explicit PARTITION,
|
||||
WL#5217, in open_and_lock_tables().
|
||||
* Bits in read_partitions can be cleared in prune_partitions()
|
||||
in the optimizing step.
|
||||
(WL#4443 is about allowing prune_partitions() to affect lock_partitions
|
||||
and be done before locking too).
|
||||
* When the partition enabled handler get an external_lock call it locks
|
||||
all partitions in lock_partitions (and remembers which partitions it
|
||||
locked, so that it can unlock them later). In case of LOCK TABLES it will
|
||||
lock all partitions, and keep them locked while lock_partitions can
|
||||
change for each statement under LOCK TABLES.
|
||||
* Freed at the same time item_free_list is freed.
|
||||
*/
|
||||
MY_BITMAP used_partitions;
|
||||
MY_BITMAP read_partitions;
|
||||
MY_BITMAP lock_partitions;
|
||||
bool bitmaps_are_initialized;
|
||||
|
||||
union {
|
||||
longlong *range_int_array;
|
||||
|
|
@ -157,6 +174,7 @@ public:
|
|||
uint curr_list_object;
|
||||
uint num_columns;
|
||||
|
||||
TABLE *table;
|
||||
/*
|
||||
These key_map's are used for Partitioning to enable quick decisions
|
||||
on whether we can derive more information about which partition to
|
||||
|
|
@ -207,6 +225,15 @@ public:
|
|||
bool from_openfrm;
|
||||
bool has_null_value;
|
||||
bool column_list;
|
||||
/**
|
||||
True if pruning has been completed and can not be pruned any further,
|
||||
even if there are subqueries or stored programs in the condition.
|
||||
|
||||
Some times it is needed to run prune_partitions() a second time to prune
|
||||
read partitions after tables are locked, when subquery and
|
||||
stored functions might have been evaluated.
|
||||
*/
|
||||
bool is_pruning_completed;
|
||||
|
||||
partition_info()
|
||||
: get_partition_id(NULL), get_part_partition_id(NULL),
|
||||
|
|
@ -219,6 +246,7 @@ public:
|
|||
restore_part_field_ptrs(NULL), restore_subpart_field_ptrs(NULL),
|
||||
part_expr(NULL), subpart_expr(NULL), item_free_list(NULL),
|
||||
first_log_entry(NULL), exec_log_entry(NULL), frm_log_entry(NULL),
|
||||
bitmaps_are_initialized(FALSE),
|
||||
list_array(NULL), err_value(0),
|
||||
part_info_string(NULL),
|
||||
part_func_string(NULL), subpart_func_string(NULL),
|
||||
|
|
@ -238,7 +266,7 @@ public:
|
|||
list_of_part_fields(FALSE), list_of_subpart_fields(FALSE),
|
||||
linear_hash_ind(FALSE), fixed(FALSE),
|
||||
is_auto_partitioned(FALSE), from_openfrm(FALSE),
|
||||
has_null_value(FALSE), column_list(FALSE)
|
||||
has_null_value(FALSE), column_list(FALSE), is_pruning_completed(false)
|
||||
{
|
||||
all_fields_in_PF.clear_all();
|
||||
all_fields_in_PPF.clear_all();
|
||||
|
|
@ -252,6 +280,8 @@ public:
|
|||
~partition_info() {}
|
||||
|
||||
partition_info *get_clone();
|
||||
bool set_named_partition_bitmap(const char *part_name, uint length);
|
||||
bool set_partition_bitmaps(TABLE_LIST *table_list);
|
||||
/* Answers the question if subpartitioning is used for a certain table */
|
||||
bool is_sub_partitioned()
|
||||
{
|
||||
|
|
@ -266,8 +296,8 @@ public:
|
|||
|
||||
bool set_up_defaults_for_partitioning(handler *file, HA_CREATE_INFO *info,
|
||||
uint start_no);
|
||||
char *has_unique_fields();
|
||||
char *has_unique_names();
|
||||
char *find_duplicate_field();
|
||||
char *find_duplicate_name();
|
||||
bool check_engine_mix(handlerton *engine_type, bool default_engine);
|
||||
bool check_range_constants(THD *thd);
|
||||
bool check_list_constants(THD *thd);
|
||||
|
|
@ -297,7 +327,34 @@ public:
|
|||
bool init_column_part();
|
||||
bool add_column_list_value(THD *thd, Item *item);
|
||||
void set_show_version_string(String *packet);
|
||||
partition_element *get_part_elem(const char *partition_name,
|
||||
char *file_name,
|
||||
uint32 *part_id);
|
||||
void report_part_expr_error(bool use_subpart_expr);
|
||||
bool set_used_partition(List<Item> &fields,
|
||||
List<Item> &values,
|
||||
COPY_INFO &info,
|
||||
bool copy_default_values,
|
||||
MY_BITMAP *used_partitions);
|
||||
/**
|
||||
PRUNE_NO - Unable to prune.
|
||||
PRUNE_DEFAULTS - Partitioning field is only set to
|
||||
DEFAULT values, only need to check
|
||||
pruning for one row where the DEFAULTS
|
||||
values are set.
|
||||
PRUNE_YES - Pruning is possible, calculate the used partition set
|
||||
by evaluate the partition_id on row by row basis.
|
||||
*/
|
||||
enum enum_can_prune {PRUNE_NO=0, PRUNE_DEFAULTS, PRUNE_YES};
|
||||
bool can_prune_insert(THD *thd,
|
||||
enum_duplicates duplic,
|
||||
COPY_INFO &update,
|
||||
List<Item> &update_fields,
|
||||
List<Item> &fields,
|
||||
bool empty_values,
|
||||
enum_can_prune *can_prune_partitions,
|
||||
bool *prune_needs_default_values,
|
||||
MY_BITMAP *used_partitions);
|
||||
private:
|
||||
static int list_part_cmp(const void* a, const void* b);
|
||||
bool set_up_default_partitions(handler *file, HA_CREATE_INFO *info,
|
||||
|
|
@ -305,7 +362,13 @@ private:
|
|||
bool set_up_default_subpartitions(handler *file, HA_CREATE_INFO *info);
|
||||
char *create_default_partition_names(uint part_no, uint num_parts,
|
||||
uint start_no);
|
||||
char *create_subpartition_name(uint subpart_no, const char *part_name);
|
||||
char *create_default_subpartition_name(uint subpart_no,
|
||||
const char *part_name);
|
||||
bool prune_partition_bitmaps(TABLE_LIST *table_list);
|
||||
bool add_named_partition(const char *part_name, uint length);
|
||||
bool is_field_in_part_expr(List<Item> &fields);
|
||||
bool is_full_part_expr_in_fields(List<Item> &fields);
|
||||
public:
|
||||
bool has_unique_name(partition_element *element);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -161,14 +161,14 @@ bool net_send_error(THD *thd, uint sql_errno, const char *err,
|
|||
It's one case when we can push an error even though there
|
||||
is an OK or EOF already.
|
||||
*/
|
||||
thd->stmt_da->can_overwrite_status= TRUE;
|
||||
thd->get_stmt_da()->set_overwrite_status(true);
|
||||
|
||||
/* Abort multi-result sets */
|
||||
thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
|
||||
|
||||
error= net_send_error_packet(thd, sql_errno, err, sqlstate);
|
||||
|
||||
thd->stmt_da->can_overwrite_status= FALSE;
|
||||
thd->get_stmt_da()->set_overwrite_status(false);
|
||||
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
|
@ -242,7 +242,7 @@ net_send_ok(THD *thd,
|
|||
int2store(pos, server_status);
|
||||
pos+=2;
|
||||
}
|
||||
thd->stmt_da->can_overwrite_status= TRUE;
|
||||
thd->get_stmt_da()->set_overwrite_status(true);
|
||||
|
||||
if (message && message[0])
|
||||
pos= net_store_data(pos, (uchar*) message, strlen(message));
|
||||
|
|
@ -251,7 +251,7 @@ net_send_ok(THD *thd,
|
|||
error= net_flush(net);
|
||||
|
||||
|
||||
thd->stmt_da->can_overwrite_status= FALSE;
|
||||
thd->get_stmt_da()->set_overwrite_status(false);
|
||||
DBUG_PRINT("info", ("OK sent, so no more error sending allowed"));
|
||||
|
||||
DBUG_RETURN(error);
|
||||
|
|
@ -291,11 +291,11 @@ net_send_eof(THD *thd, uint server_status, uint statement_warn_count)
|
|||
/* Set to TRUE if no active vio, to work well in case of --init-file */
|
||||
if (net->vio != 0)
|
||||
{
|
||||
thd->stmt_da->can_overwrite_status= TRUE;
|
||||
thd->get_stmt_da()->set_overwrite_status(true);
|
||||
error= write_eof_packet(thd, net, server_status, statement_warn_count);
|
||||
if (!error)
|
||||
error= net_flush(net);
|
||||
thd->stmt_da->can_overwrite_status= FALSE;
|
||||
thd->get_stmt_da()->set_overwrite_status(false);
|
||||
DBUG_PRINT("info", ("EOF sent, so no more error sending allowed"));
|
||||
}
|
||||
DBUG_RETURN(error);
|
||||
|
|
@ -486,30 +486,30 @@ static uchar *net_store_length_fast(uchar *packet, uint length)
|
|||
void Protocol::end_statement()
|
||||
{
|
||||
DBUG_ENTER("Protocol::end_statement");
|
||||
DBUG_ASSERT(! thd->stmt_da->is_sent);
|
||||
DBUG_ASSERT(! thd->get_stmt_da()->is_sent());
|
||||
bool error= FALSE;
|
||||
|
||||
/* Can not be true, but do not take chances in production. */
|
||||
if (thd->stmt_da->is_sent)
|
||||
if (thd->get_stmt_da()->is_sent())
|
||||
DBUG_VOID_RETURN;
|
||||
|
||||
switch (thd->stmt_da->status()) {
|
||||
switch (thd->get_stmt_da()->status()) {
|
||||
case Diagnostics_area::DA_ERROR:
|
||||
/* The query failed, send error to log and abort bootstrap. */
|
||||
error= send_error(thd->stmt_da->sql_errno(),
|
||||
thd->stmt_da->message(),
|
||||
thd->stmt_da->get_sqlstate());
|
||||
error= send_error(thd->get_stmt_da()->sql_errno(),
|
||||
thd->get_stmt_da()->message(),
|
||||
thd->get_stmt_da()->get_sqlstate());
|
||||
break;
|
||||
case Diagnostics_area::DA_EOF:
|
||||
error= send_eof(thd->server_status,
|
||||
thd->stmt_da->statement_warn_count());
|
||||
thd->get_stmt_da()->statement_warn_count());
|
||||
break;
|
||||
case Diagnostics_area::DA_OK:
|
||||
error= send_ok(thd->server_status,
|
||||
thd->stmt_da->statement_warn_count(),
|
||||
thd->stmt_da->affected_rows(),
|
||||
thd->stmt_da->last_insert_id(),
|
||||
thd->stmt_da->message());
|
||||
thd->get_stmt_da()->statement_warn_count(),
|
||||
thd->get_stmt_da()->affected_rows(),
|
||||
thd->get_stmt_da()->last_insert_id(),
|
||||
thd->get_stmt_da()->message());
|
||||
break;
|
||||
case Diagnostics_area::DA_DISABLED:
|
||||
break;
|
||||
|
|
@ -520,7 +520,7 @@ void Protocol::end_statement()
|
|||
break;
|
||||
}
|
||||
if (!error)
|
||||
thd->stmt_da->is_sent= TRUE;
|
||||
thd->get_stmt_da()->set_is_sent(true);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
|
@ -688,9 +688,9 @@ bool Protocol::flush()
|
|||
{
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
bool error;
|
||||
thd->stmt_da->can_overwrite_status= TRUE;
|
||||
thd->get_stmt_da()->set_overwrite_status(true);
|
||||
error= net_flush(&thd->net);
|
||||
thd->stmt_da->can_overwrite_status= FALSE;
|
||||
thd->get_stmt_da()->set_overwrite_status(false);
|
||||
return error;
|
||||
#else
|
||||
return 0;
|
||||
|
|
@ -856,7 +856,7 @@ bool Protocol::send_result_set_metadata(List<Item> *list, uint flags)
|
|||
Send no warning information, as it will be sent at statement end.
|
||||
*/
|
||||
if (write_eof_packet(thd, &thd->net, thd->server_status,
|
||||
thd->warning_info->statement_warn_count()))
|
||||
thd->get_stmt_da()->current_statement_warn_count()))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
DBUG_RETURN(prepare_for_send(list->elements));
|
||||
|
|
|
|||
|
|
@ -818,7 +818,7 @@ bool Master_info_index::init_all_master_info()
|
|||
sql_print_error("Initialized Master_info from '%s' failed",
|
||||
buf_master_info_file);
|
||||
if (!master_info_index->get_master_info(&connection_name,
|
||||
MYSQL_ERROR::WARN_LEVEL_NOTE))
|
||||
Sql_condition::WARN_LEVEL_NOTE))
|
||||
{
|
||||
/* Master_info is not in HASH; Add it */
|
||||
if (master_info_index->add_master_info(mi, FALSE))
|
||||
|
|
@ -843,7 +843,7 @@ bool Master_info_index::init_all_master_info()
|
|||
sql_print_information("Initialized Master_info from '%s'",
|
||||
buf_master_info_file);
|
||||
if (master_info_index->get_master_info(&connection_name,
|
||||
MYSQL_ERROR::WARN_LEVEL_NOTE))
|
||||
Sql_condition::WARN_LEVEL_NOTE))
|
||||
{
|
||||
/* Master_info was already registered */
|
||||
sql_print_error(ER(ER_CONNECTION_ALREADY_EXISTS),
|
||||
|
|
@ -940,7 +940,7 @@ bool Master_info_index::write_master_name_to_index_file(LEX_STRING *name,
|
|||
|
||||
Master_info *
|
||||
Master_info_index::get_master_info(LEX_STRING *connection_name,
|
||||
MYSQL_ERROR::enum_warning_level warning)
|
||||
Sql_condition::enum_warning_level warning)
|
||||
{
|
||||
Master_info *mi;
|
||||
char buff[MAX_CONNECTION_NAME+1], *res;
|
||||
|
|
@ -957,10 +957,10 @@ Master_info_index::get_master_info(LEX_STRING *connection_name,
|
|||
|
||||
mi= (Master_info*) my_hash_search(&master_info_hash,
|
||||
(uchar*) buff, buff_length);
|
||||
if (!mi && warning != MYSQL_ERROR::WARN_LEVEL_NOTE)
|
||||
if (!mi && warning != Sql_condition::WARN_LEVEL_NOTE)
|
||||
{
|
||||
my_error(WARN_NO_MASTER_INFO,
|
||||
MYF(warning == MYSQL_ERROR::WARN_LEVEL_WARN ? ME_JUST_WARNING :
|
||||
MYF(warning == Sql_condition::WARN_LEVEL_WARN ? ME_JUST_WARNING :
|
||||
0),
|
||||
(int) connection_name->length,
|
||||
connection_name->str);
|
||||
|
|
@ -979,7 +979,7 @@ bool Master_info_index::check_duplicate_master_info(LEX_STRING *name_arg,
|
|||
|
||||
/* Get full host and port name */
|
||||
if ((mi= master_info_index->get_master_info(name_arg,
|
||||
MYSQL_ERROR::WARN_LEVEL_NOTE)))
|
||||
Sql_condition::WARN_LEVEL_NOTE)))
|
||||
{
|
||||
if (!host)
|
||||
host= mi->host;
|
||||
|
|
@ -1043,7 +1043,7 @@ bool Master_info_index::remove_master_info(LEX_STRING *name)
|
|||
Master_info* mi;
|
||||
DBUG_ENTER("remove_master_info");
|
||||
|
||||
if ((mi= get_master_info(name, MYSQL_ERROR::WARN_LEVEL_WARN)))
|
||||
if ((mi= get_master_info(name, Sql_condition::WARN_LEVEL_WARN)))
|
||||
{
|
||||
// Delete Master_info and rewrite others to file
|
||||
if (!my_hash_delete(&master_info_hash, (uchar*) mi))
|
||||
|
|
@ -1155,7 +1155,7 @@ bool Master_info_index::start_all_slaves(THD *thd)
|
|||
break;
|
||||
}
|
||||
else
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
|
||||
ER_SLAVE_STARTED, ER(ER_SLAVE_STARTED),
|
||||
(int) mi->connection_name.length,
|
||||
mi->connection_name.str);
|
||||
|
|
@ -1200,7 +1200,7 @@ bool Master_info_index::stop_all_slaves(THD *thd)
|
|||
break;
|
||||
}
|
||||
else
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
|
||||
ER_SLAVE_STOPPED, ER(ER_SLAVE_STOPPED),
|
||||
(int) mi->connection_name.length,
|
||||
mi->connection_name.str);
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ public:
|
|||
bool add_master_info(Master_info *mi, bool write_to_file);
|
||||
bool remove_master_info(LEX_STRING *connection_name);
|
||||
Master_info *get_master_info(LEX_STRING *connection_name,
|
||||
MYSQL_ERROR::enum_warning_level warning);
|
||||
Sql_condition::enum_warning_level warning);
|
||||
bool give_error_if_slave_running();
|
||||
bool start_all_slaves(THD *thd);
|
||||
bool stop_all_slaves(THD *thd);
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@ unpack_row(Relay_log_info const *rli,
|
|||
else
|
||||
{
|
||||
f->set_default();
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_BAD_NULL_ERROR, ER(ER_BAD_NULL_ERROR),
|
||||
f->field_name);
|
||||
}
|
||||
|
|
@ -447,7 +447,7 @@ int prepare_record(TABLE *const table, const uint skip, const bool check)
|
|||
{
|
||||
f->set_default();
|
||||
push_warning_printf(current_thd,
|
||||
MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_NO_DEFAULT_FOR_FIELD,
|
||||
ER(ER_NO_DEFAULT_FOR_FIELD),
|
||||
f->field_name);
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@ a file name for --relay-log-index option", opt_relaylog_index_name);
|
|||
{
|
||||
sql_print_error("Failed to create a new relay log info file (\
|
||||
file '%s', errno %d)", fname, my_errno);
|
||||
msg= current_thd->stmt_da->message();
|
||||
msg= current_thd->get_stmt_da()->message();
|
||||
goto err;
|
||||
}
|
||||
if (init_io_cache(&rli->info_file, info_fd, IO_SIZE*2, READ_CACHE, 0L,0,
|
||||
|
|
@ -255,7 +255,7 @@ file '%s', errno %d)", fname, my_errno);
|
|||
{
|
||||
sql_print_error("Failed to create a cache on relay log info file '%s'",
|
||||
fname);
|
||||
msg= current_thd->stmt_da->message();
|
||||
msg= current_thd->get_stmt_da()->message();
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
|
@ -1334,9 +1334,9 @@ void Relay_log_info::clear_tables_to_lock()
|
|||
void Relay_log_info::slave_close_thread_tables(THD *thd)
|
||||
{
|
||||
DBUG_ENTER("Relay_log_info::slave_close_thread_tables(THD *thd)");
|
||||
thd->stmt_da->can_overwrite_status= TRUE;
|
||||
thd->get_stmt_da()->set_overwrite_status(true);
|
||||
thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
|
||||
thd->stmt_da->can_overwrite_status= FALSE;
|
||||
thd->get_stmt_da()->set_overwrite_status(false);
|
||||
|
||||
close_thread_tables(thd);
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -279,7 +279,7 @@ void sys_var::do_deprecated_warning(THD *thd)
|
|||
? ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT
|
||||
: ER_WARN_DEPRECATED_SYNTAX;
|
||||
if (thd)
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_DEPRECATED_SYNTAX, ER(errmsg),
|
||||
buf1, deprecation_substitute);
|
||||
else
|
||||
|
|
@ -316,7 +316,7 @@ bool throw_bounds_warning(THD *thd, const char *name,
|
|||
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buf);
|
||||
return true;
|
||||
}
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_TRUNCATED_WRONG_VALUE,
|
||||
ER(ER_TRUNCATED_WRONG_VALUE), name, buf);
|
||||
}
|
||||
|
|
@ -336,7 +336,7 @@ bool throw_bounds_warning(THD *thd, const char *name, bool fixed, double v)
|
|||
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buf);
|
||||
return true;
|
||||
}
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_TRUNCATED_WRONG_VALUE,
|
||||
ER(ER_TRUNCATED_WRONG_VALUE), name, buf);
|
||||
}
|
||||
|
|
|
|||
33
sql/slave.cc
33
sql/slave.cc
|
|
@ -2650,7 +2650,7 @@ static int has_temporary_error(THD *thd)
|
|||
DBUG_ENTER("has_temporary_error");
|
||||
|
||||
DBUG_EXECUTE_IF("all_errors_are_temporary_errors",
|
||||
if (thd->stmt_da->is_error())
|
||||
if (thd->get_stmt_da()->is_error())
|
||||
{
|
||||
thd->clear_error();
|
||||
my_error(ER_LOCK_DEADLOCK, MYF(0));
|
||||
|
|
@ -2669,16 +2669,16 @@ static int has_temporary_error(THD *thd)
|
|||
currently, InnoDB deadlock detected by InnoDB or lock
|
||||
wait timeout (innodb_lock_wait_timeout exceeded
|
||||
*/
|
||||
if (thd->stmt_da->sql_errno() == ER_LOCK_DEADLOCK ||
|
||||
thd->stmt_da->sql_errno() == ER_LOCK_WAIT_TIMEOUT)
|
||||
if (thd->get_stmt_da()->sql_errno() == ER_LOCK_DEADLOCK ||
|
||||
thd->get_stmt_da()->sql_errno() == ER_LOCK_WAIT_TIMEOUT)
|
||||
DBUG_RETURN(1);
|
||||
|
||||
#ifdef HAVE_NDB_BINLOG
|
||||
/*
|
||||
currently temporary error set in ndbcluster
|
||||
*/
|
||||
List_iterator_fast<MYSQL_ERROR> it(thd->warning_info->warn_list());
|
||||
MYSQL_ERROR *err;
|
||||
List_iterator_fast<Sql_condition> it(thd->warning_info->warn_list());
|
||||
Sql_condition *err;
|
||||
while ((err= it++))
|
||||
{
|
||||
DBUG_PRINT("info", ("has condition %d %s", err->get_sql_errno(),
|
||||
|
|
@ -3738,9 +3738,9 @@ log '%s' at position %s, relay log '%s' position: %s", RPL_LOG_NAME,
|
|||
|
||||
if (check_temp_dir(rli->slave_patternload_file))
|
||||
{
|
||||
rli->report(ERROR_LEVEL, thd->stmt_da->sql_errno(),
|
||||
rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
|
||||
"Unable to use slave's temporary directory %s - %s",
|
||||
slave_load_tmpdir, thd->stmt_da->message());
|
||||
slave_load_tmpdir, thd->get_stmt_da()->message());
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
|
@ -3750,7 +3750,7 @@ log '%s' at position %s, relay log '%s' position: %s", RPL_LOG_NAME,
|
|||
execute_init_command(thd, &opt_init_slave, &LOCK_sys_init_slave);
|
||||
if (thd->is_slave_error)
|
||||
{
|
||||
rli->report(ERROR_LEVEL, thd->stmt_da->sql_errno(),
|
||||
rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
|
||||
"Slave SQL thread aborted. Can't execute init_slave query");
|
||||
goto err;
|
||||
}
|
||||
|
|
@ -3817,20 +3817,20 @@ log '%s' at position %s, relay log '%s' position: %s", RPL_LOG_NAME,
|
|||
|
||||
if (thd->is_error())
|
||||
{
|
||||
char const *const errmsg= thd->stmt_da->message();
|
||||
char const *const errmsg= thd->get_stmt_da()->message();
|
||||
|
||||
DBUG_PRINT("info",
|
||||
("thd->stmt_da->sql_errno()=%d; rli->last_error.number=%d",
|
||||
thd->stmt_da->sql_errno(), last_errno));
|
||||
("thd->get_stmt_da()->sql_errno()=%d; rli->last_error.number=%d",
|
||||
thd->get_stmt_da()->sql_errno(), last_errno));
|
||||
if (last_errno == 0)
|
||||
{
|
||||
/*
|
||||
This function is reporting an error which was not reported
|
||||
while executing exec_relay_log_event().
|
||||
*/
|
||||
rli->report(ERROR_LEVEL, thd->stmt_da->sql_errno(), "%s", errmsg);
|
||||
rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(), "%s", errmsg);
|
||||
}
|
||||
else if (last_errno != thd->stmt_da->sql_errno())
|
||||
else if (last_errno != thd->get_stmt_da()->sql_errno())
|
||||
{
|
||||
/*
|
||||
* An error was reported while executing exec_relay_log_event()
|
||||
|
|
@ -3839,13 +3839,14 @@ log '%s' at position %s, relay log '%s' position: %s", RPL_LOG_NAME,
|
|||
* what caused the problem.
|
||||
*/
|
||||
sql_print_error("Slave (additional info): %s Error_code: %d",
|
||||
errmsg, thd->stmt_da->sql_errno());
|
||||
errmsg, thd->get_stmt_da()->sql_errno());
|
||||
}
|
||||
}
|
||||
|
||||
/* Print any warnings issued */
|
||||
List_iterator_fast<MYSQL_ERROR> it(thd->warning_info->warn_list());
|
||||
MYSQL_ERROR *err;
|
||||
Diagnostics_area::Sql_condition_iterator it=
|
||||
thd->get_stmt_da()->sql_conditions();
|
||||
const Sql_condition *err;
|
||||
/*
|
||||
Added controlled slave thread cancel for replication
|
||||
of user-defined variables.
|
||||
|
|
|
|||
26
sql/sp.cc
26
sql/sp.cc
|
|
@ -325,7 +325,7 @@ Stored_routine_creation_ctx::load_from_db(THD *thd,
|
|||
if (invalid_creation_ctx)
|
||||
{
|
||||
push_warning_printf(thd,
|
||||
MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_SR_INVALID_CREATION_CTX,
|
||||
ER(ER_SR_INVALID_CREATION_CTX),
|
||||
(const char *) db_name,
|
||||
|
|
@ -683,9 +683,9 @@ public:
|
|||
virtual bool handle_condition(THD *thd,
|
||||
uint sql_errno,
|
||||
const char* sqlstate,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
Sql_condition::enum_warning_level level,
|
||||
const char* msg,
|
||||
MYSQL_ERROR ** cond_hdl);
|
||||
Sql_condition ** cond_hdl);
|
||||
};
|
||||
|
||||
bool
|
||||
|
|
@ -693,13 +693,13 @@ Silence_deprecated_warning::handle_condition(
|
|||
THD *,
|
||||
uint sql_errno,
|
||||
const char*,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
Sql_condition::enum_warning_level level,
|
||||
const char*,
|
||||
MYSQL_ERROR ** cond_hdl)
|
||||
Sql_condition ** cond_hdl)
|
||||
{
|
||||
*cond_hdl= NULL;
|
||||
if (sql_errno == ER_WARN_DEPRECATED_SYNTAX &&
|
||||
level == MYSQL_ERROR::WARN_LEVEL_WARN)
|
||||
level == Sql_condition::WARN_LEVEL_WARN)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
|
|
@ -772,9 +772,9 @@ public:
|
|||
virtual bool handle_condition(THD *thd,
|
||||
uint sql_errno,
|
||||
const char* sqlstate,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
Sql_condition::enum_warning_level level,
|
||||
const char* message,
|
||||
MYSQL_ERROR ** cond_hdl);
|
||||
Sql_condition ** cond_hdl);
|
||||
|
||||
bool error_caught() const { return m_error_caught; }
|
||||
|
||||
|
|
@ -786,9 +786,9 @@ bool
|
|||
Bad_db_error_handler::handle_condition(THD *thd,
|
||||
uint sql_errno,
|
||||
const char* sqlstate,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
Sql_condition::enum_warning_level level,
|
||||
const char* message,
|
||||
MYSQL_ERROR ** cond_hdl)
|
||||
Sql_condition ** cond_hdl)
|
||||
{
|
||||
if (sql_errno == ER_BAD_DB_ERROR)
|
||||
{
|
||||
|
|
@ -1390,9 +1390,9 @@ public:
|
|||
bool handle_condition(THD *thd,
|
||||
uint sql_errno,
|
||||
const char* sqlstate,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
Sql_condition::enum_warning_level level,
|
||||
const char* msg,
|
||||
MYSQL_ERROR ** cond_hdl)
|
||||
Sql_condition ** cond_hdl)
|
||||
{
|
||||
if (sql_errno == ER_NO_SUCH_TABLE ||
|
||||
sql_errno == ER_NO_SUCH_TABLE_IN_ENGINE ||
|
||||
|
|
@ -1757,7 +1757,7 @@ sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any)
|
|||
&thd->sp_proc_cache, FALSE) != NULL ||
|
||||
sp_find_routine(thd, TYPE_ENUM_FUNCTION, name,
|
||||
&thd->sp_func_cache, FALSE) != NULL;
|
||||
thd->warning_info->clear_warning_info(thd->query_id);
|
||||
thd->get_stmt_da()->clear_warning_info(thd->query_id);
|
||||
if (sp_object_found)
|
||||
{
|
||||
if (any)
|
||||
|
|
|
|||
|
|
@ -1148,19 +1148,20 @@ find_handler_after_execution(THD *thd, sp_rcontext *ctx)
|
|||
if (thd->is_error())
|
||||
{
|
||||
ctx->find_handler(thd,
|
||||
thd->stmt_da->sql_errno(),
|
||||
thd->stmt_da->get_sqlstate(),
|
||||
MYSQL_ERROR::WARN_LEVEL_ERROR,
|
||||
thd->stmt_da->message());
|
||||
thd->get_stmt_da()->sql_errno(),
|
||||
thd->get_stmt_da()->get_sqlstate(),
|
||||
Sql_condition::WARN_LEVEL_ERROR,
|
||||
thd->get_stmt_da()->message());
|
||||
}
|
||||
else if (thd->warning_info->statement_warn_count())
|
||||
else if (thd->get_stmt_da()->statement_warn_count())
|
||||
{
|
||||
List_iterator<MYSQL_ERROR> it(thd->warning_info->warn_list());
|
||||
MYSQL_ERROR *err;
|
||||
Diagnostics_area::Sql_condition_iterator it=
|
||||
thd->get_stmt_da()->sql_conditions();
|
||||
const Sql_condition *err;
|
||||
while ((err= it++))
|
||||
{
|
||||
if (err->get_level() != MYSQL_ERROR::WARN_LEVEL_WARN &&
|
||||
err->get_level() != MYSQL_ERROR::WARN_LEVEL_NOTE)
|
||||
if (err->get_level() != Sql_condition::WARN_LEVEL_WARN &&
|
||||
err->get_level() != Sql_condition::WARN_LEVEL_NOTE)
|
||||
continue;
|
||||
|
||||
if (ctx->find_handler(thd,
|
||||
|
|
@ -1221,8 +1222,8 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
|
|||
String old_packet;
|
||||
Reprepare_observer *save_reprepare_observer= thd->m_reprepare_observer;
|
||||
Object_creation_ctx *saved_creation_ctx;
|
||||
Warning_info *saved_warning_info;
|
||||
Warning_info warning_info(thd->warning_info->warn_id(), false);
|
||||
Diagnostics_area *da= thd->get_stmt_da();
|
||||
Warning_info sp_wi(da->warning_info_id(), false, true);
|
||||
|
||||
/*
|
||||
Just reporting a stack overrun error
|
||||
|
|
@ -1293,9 +1294,8 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
|
|||
old_arena= thd->stmt_arena;
|
||||
|
||||
/* Push a new warning information area. */
|
||||
warning_info.append_warning_info(thd, thd->warning_info);
|
||||
saved_warning_info= thd->warning_info;
|
||||
thd->warning_info= &warning_info;
|
||||
da->copy_sql_conditions_to_wi(thd, &sp_wi);
|
||||
da->push_warning_info(&sp_wi);
|
||||
|
||||
/*
|
||||
Switch query context. This has to be done early as this is sometimes
|
||||
|
|
@ -1395,7 +1395,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
|
|||
}
|
||||
|
||||
/* Reset number of warnings for this query. */
|
||||
thd->warning_info->reset_for_next_command();
|
||||
thd->get_stmt_da()->reset_for_next_command();
|
||||
|
||||
DBUG_PRINT("execute", ("Instruction %u", ip));
|
||||
|
||||
|
|
@ -1502,9 +1502,40 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
|
|||
- if there was an exception during execution, warning info should be
|
||||
propagated to the caller in any case.
|
||||
*/
|
||||
da->pop_warning_info();
|
||||
|
||||
if (err_status || merge_da_on_success)
|
||||
saved_warning_info->merge_with_routine_info(thd, thd->warning_info);
|
||||
thd->warning_info= saved_warning_info;
|
||||
{
|
||||
/*
|
||||
If a routine body is empty or if a routine did not generate any warnings,
|
||||
do not duplicate our own contents by appending the contents of the called
|
||||
routine. We know that the called routine did not change its warning info.
|
||||
|
||||
On the other hand, if the routine body is not empty and some statement in
|
||||
the routine generates a warning or uses tables, warning info is guaranteed
|
||||
to have changed. In this case we know that the routine warning info
|
||||
contains only new warnings, and thus we perform a copy.
|
||||
*/
|
||||
if (da->warning_info_changed(&sp_wi))
|
||||
{
|
||||
/*
|
||||
If the invocation of the routine was a standalone statement,
|
||||
rather than a sub-statement, in other words, if it's a CALL
|
||||
of a procedure, rather than invocation of a function or a
|
||||
trigger, we need to clear the current contents of the caller's
|
||||
warning info.
|
||||
|
||||
This is per MySQL rules: if a statement generates a warning,
|
||||
warnings from the previous statement are flushed. Normally
|
||||
it's done in push_warning(). However, here we don't use
|
||||
push_warning() to avoid invocation of condition handlers or
|
||||
escalation of warnings to errors.
|
||||
*/
|
||||
da->opt_clear_warning_info(thd->query_id);
|
||||
da->copy_sql_conditions_from_wi(thd, &sp_wi);
|
||||
da->remove_marked_sql_conditions();
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
DBUG_PRINT("info", ("err_status: %d killed: %d is_slave_error: %d report_error: %d",
|
||||
|
|
@ -1958,7 +1989,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
|
|||
if (mysql_bin_log.write(&qinfo) &&
|
||||
thd->binlog_evt_union.unioned_events_trans)
|
||||
{
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
|
||||
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
|
||||
"Invoked ROUTINE modified a transactional table but MySQL "
|
||||
"failed to reflect this change in the binary log");
|
||||
err_status= TRUE;
|
||||
|
|
@ -2137,9 +2168,9 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
|
|||
|
||||
if (!thd->in_sub_stmt)
|
||||
{
|
||||
thd->stmt_da->can_overwrite_status= TRUE;
|
||||
thd->get_stmt_da()->set_overwrite_status(true);
|
||||
thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
|
||||
thd->stmt_da->can_overwrite_status= FALSE;
|
||||
thd->get_stmt_da()->set_overwrite_status(false);
|
||||
}
|
||||
|
||||
thd_proc_info(thd, "closing tables");
|
||||
|
|
@ -2884,7 +2915,7 @@ sp_head::show_routine_code(THD *thd)
|
|||
Since this is for debugging purposes only, we don't bother to
|
||||
introduce a special error code for it.
|
||||
*/
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR, tmp);
|
||||
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR, tmp);
|
||||
}
|
||||
protocol->prepare_for_resend();
|
||||
protocol->store((longlong)ip);
|
||||
|
|
@ -2991,9 +3022,9 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
|
|||
/* Here we also commit or rollback the current statement. */
|
||||
if (! thd->in_sub_stmt)
|
||||
{
|
||||
thd->stmt_da->can_overwrite_status= TRUE;
|
||||
thd->get_stmt_da()->set_overwrite_status(true);
|
||||
thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
|
||||
thd->stmt_da->can_overwrite_status= FALSE;
|
||||
thd->get_stmt_da()->set_overwrite_status(false);
|
||||
}
|
||||
thd_proc_info(thd, "closing tables");
|
||||
close_thread_tables(thd);
|
||||
|
|
@ -3027,10 +3058,10 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
|
|||
open_tables stage.
|
||||
*/
|
||||
if (!res || !thd->is_error() ||
|
||||
(thd->stmt_da->sql_errno() != ER_CANT_REOPEN_TABLE &&
|
||||
thd->stmt_da->sql_errno() != ER_NO_SUCH_TABLE &&
|
||||
thd->stmt_da->sql_errno() != ER_NO_SUCH_TABLE_IN_ENGINE &&
|
||||
thd->stmt_da->sql_errno() != ER_UPDATE_TABLE_USED))
|
||||
(thd->get_stmt_da()->sql_errno() != ER_CANT_REOPEN_TABLE &&
|
||||
thd->get_stmt_da()->sql_errno() != ER_NO_SUCH_TABLE &&
|
||||
thd->get_stmt_da()->sql_errno() != ER_NO_SUCH_TABLE_IN_ENGINE &&
|
||||
thd->get_stmt_da()->sql_errno() != ER_UPDATE_TABLE_USED))
|
||||
thd->stmt_arena->state= Query_arena::STMT_EXECUTED;
|
||||
|
||||
/*
|
||||
|
|
@ -3117,7 +3148,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
|
|||
{
|
||||
res= m_lex_keeper.reset_lex_and_exec_core(thd, nextp, FALSE, this);
|
||||
|
||||
if (thd->stmt_da->is_eof())
|
||||
if (thd->get_stmt_da()->is_eof())
|
||||
{
|
||||
/* Finalize server status flags after executing a statement. */
|
||||
thd->update_server_status();
|
||||
|
|
@ -3136,7 +3167,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
|
|||
thd->query_name_consts= 0;
|
||||
|
||||
if (!thd->is_error())
|
||||
thd->stmt_da->reset_diagnostics_area();
|
||||
thd->get_stmt_da()->reset_diagnostics_area();
|
||||
}
|
||||
DBUG_RETURN(res || thd->is_error());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -274,6 +274,15 @@ public:
|
|||
*/
|
||||
Security_context m_security_ctx;
|
||||
|
||||
/**
|
||||
List of all items (Item_trigger_field objects) representing fields in
|
||||
old/new version of row in trigger. We use this list for checking whenever
|
||||
all such fields are valid at trigger creation time and for binding these
|
||||
fields to TABLE object at table open (although for latter pointer to table
|
||||
being opened is probably enough).
|
||||
*/
|
||||
SQL_I_List<Item_trigger_field> m_trg_table_fields;
|
||||
|
||||
static void *
|
||||
operator new(size_t size) throw ();
|
||||
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ bool
|
|||
sp_rcontext::find_handler(THD *thd,
|
||||
uint sql_errno,
|
||||
const char *sqlstate,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
Sql_condition::enum_warning_level level,
|
||||
const char *msg)
|
||||
{
|
||||
int i= m_hcount;
|
||||
|
|
@ -248,7 +248,7 @@ sp_rcontext::find_handler(THD *thd,
|
|||
break;
|
||||
case sp_cond_type_t::warning:
|
||||
if ((IS_WARNING_CONDITION(sqlstate) ||
|
||||
level == MYSQL_ERROR::WARN_LEVEL_WARN) &&
|
||||
level == Sql_condition::WARN_LEVEL_WARN) &&
|
||||
m_hfound < 0)
|
||||
m_hfound= i;
|
||||
break;
|
||||
|
|
@ -258,7 +258,7 @@ sp_rcontext::find_handler(THD *thd,
|
|||
break;
|
||||
case sp_cond_type_t::exception:
|
||||
if (IS_EXCEPTION_CONDITION(sqlstate) &&
|
||||
level == MYSQL_ERROR::WARN_LEVEL_ERROR &&
|
||||
level == Sql_condition::WARN_LEVEL_ERROR &&
|
||||
m_hfound < 0)
|
||||
m_hfound= i;
|
||||
break;
|
||||
|
|
@ -281,7 +281,7 @@ sp_rcontext::find_handler(THD *thd,
|
|||
(warning or "not found") we will simply resume execution.
|
||||
*/
|
||||
if (m_prev_runtime_ctx && IS_EXCEPTION_CONDITION(sqlstate) &&
|
||||
level == MYSQL_ERROR::WARN_LEVEL_ERROR)
|
||||
level == Sql_condition::WARN_LEVEL_ERROR)
|
||||
{
|
||||
return m_prev_runtime_ctx->find_handler(thd, sql_errno, sqlstate,
|
||||
level, msg);
|
||||
|
|
@ -575,7 +575,7 @@ sp_cursor::fetch(THD *thd, List<struct sp_variable> *vars)
|
|||
}
|
||||
|
||||
DBUG_EXECUTE_IF("bug23032_emit_warning",
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_UNKNOWN_ERROR,
|
||||
ER(ER_UNKNOWN_ERROR)););
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ public:
|
|||
uint m_sql_errno;
|
||||
|
||||
/** Error level. */
|
||||
MYSQL_ERROR::enum_warning_level m_level;
|
||||
Sql_condition::enum_warning_level m_level;
|
||||
|
||||
/** SQLSTATE. */
|
||||
char m_sql_state[SQLSTATE_LENGTH + 1];
|
||||
|
|
@ -75,7 +75,7 @@ public:
|
|||
char m_message[MYSQL_ERRMSG_SIZE];
|
||||
|
||||
void set(uint sql_errno, const char* sqlstate,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
Sql_condition::enum_warning_level level,
|
||||
const char* msg)
|
||||
{
|
||||
m_sql_errno= sql_errno;
|
||||
|
|
@ -90,7 +90,7 @@ public:
|
|||
void clear()
|
||||
{
|
||||
m_sql_errno= 0;
|
||||
m_level= MYSQL_ERROR::WARN_LEVEL_ERROR;
|
||||
m_level= Sql_condition::WARN_LEVEL_ERROR;
|
||||
|
||||
m_sql_state[0]= '\0';
|
||||
m_message[0]= '\0';
|
||||
|
|
@ -183,7 +183,7 @@ class sp_rcontext : public Sql_alloc
|
|||
find_handler(THD *thd,
|
||||
uint sql_errno,
|
||||
const char *sqlstate,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
Sql_condition::enum_warning_level level,
|
||||
const char *msg);
|
||||
|
||||
Sql_condition_info *raised_condition() const;
|
||||
|
|
|
|||
|
|
@ -1207,9 +1207,9 @@ my_bool acl_reload(THD *thd)
|
|||
Execution might have been interrupted; only print the error message
|
||||
if an error condition has been raised.
|
||||
*/
|
||||
if (thd->stmt_da->is_error())
|
||||
if (thd->get_stmt_da()->is_error())
|
||||
sql_print_error("Fatal error: Can't open and lock privilege tables: %s",
|
||||
thd->stmt_da->message());
|
||||
thd->get_stmt_da()->message());
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
|
@ -1968,7 +1968,7 @@ bool change_password(THD *thd, const char *host, const char *user,
|
|||
set_user_plugin(acl_user, new_password_len);
|
||||
}
|
||||
else
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
|
||||
ER_SET_PASSWORD_AUTH_PLUGIN, ER(ER_SET_PASSWORD_AUTH_PLUGIN));
|
||||
|
||||
if (update_user_table(thd, table,
|
||||
|
|
@ -6857,9 +6857,9 @@ public:
|
|||
virtual bool handle_condition(THD *thd,
|
||||
uint sql_errno,
|
||||
const char* sqlstate,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
Sql_condition::enum_warning_level level,
|
||||
const char* msg,
|
||||
MYSQL_ERROR ** cond_hdl);
|
||||
Sql_condition ** cond_hdl);
|
||||
|
||||
bool has_errors() { return is_grave; }
|
||||
|
||||
|
|
@ -6872,18 +6872,18 @@ Silence_routine_definer_errors::handle_condition(
|
|||
THD *thd,
|
||||
uint sql_errno,
|
||||
const char*,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
Sql_condition::enum_warning_level level,
|
||||
const char* msg,
|
||||
MYSQL_ERROR ** cond_hdl)
|
||||
Sql_condition ** cond_hdl)
|
||||
{
|
||||
*cond_hdl= NULL;
|
||||
if (level == MYSQL_ERROR::WARN_LEVEL_ERROR)
|
||||
if (level == Sql_condition::WARN_LEVEL_ERROR)
|
||||
{
|
||||
switch (sql_errno)
|
||||
{
|
||||
case ER_NONEXISTING_PROC_GRANT:
|
||||
/* Convert the error into a warning. */
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
sql_errno, msg);
|
||||
return TRUE;
|
||||
default:
|
||||
|
|
@ -7050,7 +7050,7 @@ bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
|
|||
}
|
||||
else
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_PASSWD_LENGTH,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_PASSWD_LENGTH,
|
||||
ER(ER_PASSWD_LENGTH), SCRAMBLED_PASSWORD_CHAR_LENGTH);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -9156,15 +9156,14 @@ bool acl_authenticate(THD *thd, uint connect_errors,
|
|||
sctx->external_user= my_strdup(mpvio.auth_info.external_user, MYF(0));
|
||||
|
||||
if (res == CR_OK_HANDSHAKE_COMPLETE)
|
||||
thd->stmt_da->disable_status();
|
||||
thd->get_stmt_da()->disable_status();
|
||||
else
|
||||
my_ok(thd);
|
||||
|
||||
#ifdef HAVE_PSI_THREAD_INTERFACE
|
||||
PSI_CALL(set_thread_user_host)(thd->main_security_ctx.user,
|
||||
strlen(thd->main_security_ctx.user),
|
||||
thd->main_security_ctx.host_or_ip,
|
||||
strlen(thd->main_security_ctx.host_or_ip));
|
||||
PSI_THREAD_CALL(set_thread_user_host)
|
||||
(thd->main_security_ctx.user, strlen(thd->main_security_ctx.user),
|
||||
thd->main_security_ctx.host_or_ip, strlen(thd->main_security_ctx.host_or_ip));
|
||||
#endif
|
||||
|
||||
/* Ready to handle queries */
|
||||
|
|
|
|||
|
|
@ -52,8 +52,8 @@ static bool admin_recreate_table(THD *thd, TABLE_LIST *table_list)
|
|||
we will store the error message in a result set row
|
||||
and then clear.
|
||||
*/
|
||||
if (thd->stmt_da->is_ok())
|
||||
thd->stmt_da->reset_diagnostics_area();
|
||||
if (thd->get_stmt_da()->is_ok())
|
||||
thd->get_stmt_da()->reset_diagnostics_area();
|
||||
table_list->table= NULL;
|
||||
result_code= result_code ? HA_ADMIN_FAILED : HA_ADMIN_OK;
|
||||
DBUG_RETURN(result_code);
|
||||
|
|
@ -98,7 +98,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
|
|||
|
||||
if (!(table= table_list->table))
|
||||
{
|
||||
char key[MAX_DBKEY_LENGTH];
|
||||
const char *key;
|
||||
uint key_length;
|
||||
/*
|
||||
If the table didn't exist, we have a shared metadata lock
|
||||
|
|
@ -114,7 +114,8 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
|
|||
*/
|
||||
my_hash_value_type hash_value;
|
||||
|
||||
key_length= create_table_def_key(thd, key, table_list, 0);
|
||||
key_length= get_table_def_key(table_list, &key);
|
||||
|
||||
table_list->mdl_request.init(MDL_key::TABLE,
|
||||
table_list->db, table_list->table_name,
|
||||
MDL_EXCLUSIVE, MDL_TRANSACTION);
|
||||
|
|
@ -203,7 +204,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
|
|||
goto end;
|
||||
/* Close table but don't remove from locked list */
|
||||
close_all_tables_for_name(thd, table_list->table->s,
|
||||
HA_EXTRA_NOT_USED);
|
||||
HA_EXTRA_NOT_USED, NULL);
|
||||
table_list->table= 0;
|
||||
}
|
||||
/*
|
||||
|
|
@ -398,14 +399,14 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||
because it's already known that the table is badly damaged.
|
||||
*/
|
||||
|
||||
Warning_info wi(thd->query_id, false);
|
||||
Warning_info *wi_saved= thd->warning_info;
|
||||
Diagnostics_area *da= thd->get_stmt_da();
|
||||
Warning_info tmp_wi(thd->query_id, false, true);
|
||||
|
||||
thd->warning_info= &wi;
|
||||
da->push_warning_info(&tmp_wi);
|
||||
|
||||
open_error= open_and_lock_tables(thd, table, TRUE, 0);
|
||||
|
||||
thd->warning_info= wi_saved;
|
||||
da->pop_warning_info(&tmp_wi);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -452,7 +453,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||
*/
|
||||
Alter_info *alter_info= &lex->alter_info;
|
||||
|
||||
if (alter_info->flags & ALTER_ADMIN_PARTITION)
|
||||
if (alter_info->flags & Alter_info::ALTER_ADMIN_PARTITION)
|
||||
{
|
||||
if (!table->table->part_info)
|
||||
{
|
||||
|
|
@ -516,16 +517,16 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||
if (!table->table)
|
||||
{
|
||||
DBUG_PRINT("admin", ("open table failed"));
|
||||
if (thd->warning_info->is_empty())
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
if (thd->get_stmt_da()->is_warning_info_empty())
|
||||
push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_CHECK_NO_SUCH_TABLE, ER(ER_CHECK_NO_SUCH_TABLE));
|
||||
/* if it was a view will check md5 sum */
|
||||
if (table->view &&
|
||||
view_checksum(thd, table) == HA_ADMIN_WRONG_CHECKSUM)
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_VIEW_CHECKSUM, ER(ER_VIEW_CHECKSUM));
|
||||
if (thd->stmt_da->is_error() &&
|
||||
table_not_corrupt_error(thd->stmt_da->sql_errno()))
|
||||
if (thd->get_stmt_da()->is_error() &&
|
||||
table_not_corrupt_error(thd->get_stmt_da()->sql_errno()))
|
||||
result_code= HA_ADMIN_FAILED;
|
||||
else
|
||||
/* Default failure code is corrupt table */
|
||||
|
|
@ -573,7 +574,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||
table->table=0; // For query cache
|
||||
if (protocol->write())
|
||||
goto err;
|
||||
thd->stmt_da->reset_diagnostics_area();
|
||||
thd->get_stmt_da()->reset_diagnostics_area();
|
||||
continue;
|
||||
/* purecov: end */
|
||||
}
|
||||
|
|
@ -744,8 +745,9 @@ send_result:
|
|||
lex->cleanup_after_one_table_open();
|
||||
thd->clear_error(); // these errors shouldn't get client
|
||||
{
|
||||
List_iterator_fast<MYSQL_ERROR> it(thd->warning_info->warn_list());
|
||||
MYSQL_ERROR *err;
|
||||
Diagnostics_area::Sql_condition_iterator it=
|
||||
thd->get_stmt_da()->sql_conditions();
|
||||
const Sql_condition *err;
|
||||
while ((err= it++))
|
||||
{
|
||||
protocol->prepare_for_resend();
|
||||
|
|
@ -758,7 +760,7 @@ send_result:
|
|||
if (protocol->write())
|
||||
goto err;
|
||||
}
|
||||
thd->warning_info->clear_warning_info(thd->query_id);
|
||||
thd->get_stmt_da()->clear_warning_info(thd->query_id);
|
||||
}
|
||||
protocol->prepare_for_resend();
|
||||
protocol->store(table_name, system_charset_info);
|
||||
|
|
@ -875,7 +877,7 @@ send_result_message:
|
|||
DBUG_ASSERT(thd->is_error() || thd->killed);
|
||||
if (thd->is_error())
|
||||
{
|
||||
const char *err_msg= thd->stmt_da->message();
|
||||
const char *err_msg= thd->get_stmt_da()->message();
|
||||
if (!thd->vio_ok())
|
||||
{
|
||||
sql_print_error("%s", err_msg);
|
||||
|
|
@ -1072,12 +1074,13 @@ bool mysql_preload_keys(THD* thd, TABLE_LIST* tables)
|
|||
}
|
||||
|
||||
|
||||
bool Analyze_table_statement::execute(THD *thd)
|
||||
bool Sql_cmd_analyze_table::execute(THD *thd)
|
||||
{
|
||||
LEX *m_lex= thd->lex;
|
||||
TABLE_LIST *first_table= m_lex->select_lex.table_list.first;
|
||||
bool res= TRUE;
|
||||
thr_lock_type lock_type = TL_READ_NO_INSERT;
|
||||
DBUG_ENTER("Analyze_table_statement::execute");
|
||||
DBUG_ENTER("Sql_cmd_analyze_table::execute");
|
||||
|
||||
if (check_table_access(thd, SELECT_ACL | INSERT_ACL, first_table,
|
||||
FALSE, UINT_MAX, FALSE))
|
||||
|
|
@ -1102,12 +1105,13 @@ error:
|
|||
}
|
||||
|
||||
|
||||
bool Check_table_statement::execute(THD *thd)
|
||||
bool Sql_cmd_check_table::execute(THD *thd)
|
||||
{
|
||||
LEX *m_lex= thd->lex;
|
||||
TABLE_LIST *first_table= m_lex->select_lex.table_list.first;
|
||||
thr_lock_type lock_type = TL_READ_NO_INSERT;
|
||||
bool res= TRUE;
|
||||
DBUG_ENTER("Check_table_statement::execute");
|
||||
DBUG_ENTER("Sql_cmd_check_table::execute");
|
||||
|
||||
if (check_table_access(thd, SELECT_ACL, first_table,
|
||||
TRUE, UINT_MAX, FALSE))
|
||||
|
|
@ -1126,17 +1130,18 @@ error:
|
|||
}
|
||||
|
||||
|
||||
bool Optimize_table_statement::execute(THD *thd)
|
||||
bool Sql_cmd_optimize_table::execute(THD *thd)
|
||||
{
|
||||
LEX *m_lex= thd->lex;
|
||||
TABLE_LIST *first_table= m_lex->select_lex.table_list.first;
|
||||
bool res= TRUE;
|
||||
DBUG_ENTER("Optimize_table_statement::execute");
|
||||
DBUG_ENTER("Sql_cmd_optimize_table::execute");
|
||||
|
||||
if (check_table_access(thd, SELECT_ACL | INSERT_ACL, first_table,
|
||||
FALSE, UINT_MAX, FALSE))
|
||||
goto error; /* purecov: inspected */
|
||||
thd->enable_slow_log= opt_log_slow_admin_statements;
|
||||
res= (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) ?
|
||||
res= (specialflag & SPECIAL_NO_NEW_FUNC) ?
|
||||
mysql_recreate_table(thd, first_table) :
|
||||
mysql_admin_table(thd, first_table, &m_lex->check_opt,
|
||||
"optimize", TL_WRITE, 1, 0, 0, 0,
|
||||
|
|
@ -1157,11 +1162,12 @@ error:
|
|||
}
|
||||
|
||||
|
||||
bool Repair_table_statement::execute(THD *thd)
|
||||
bool Sql_cmd_repair_table::execute(THD *thd)
|
||||
{
|
||||
LEX *m_lex= thd->lex;
|
||||
TABLE_LIST *first_table= m_lex->select_lex.table_list.first;
|
||||
bool res= TRUE;
|
||||
DBUG_ENTER("Repair_table_statement::execute");
|
||||
DBUG_ENTER("Sql_cmd_repair_table::execute");
|
||||
|
||||
if (check_table_access(thd, SELECT_ACL | INSERT_ACL, first_table,
|
||||
FALSE, UINT_MAX, FALSE))
|
||||
|
|
|
|||
|
|
@ -24,109 +24,100 @@ int reassign_keycache_tables(THD* thd, KEY_CACHE *src_cache,
|
|||
KEY_CACHE *dst_cache);
|
||||
|
||||
/**
|
||||
Analyze_statement represents the ANALYZE TABLE statement.
|
||||
Sql_cmd_analyze_table represents the ANALYZE TABLE statement.
|
||||
*/
|
||||
class Analyze_table_statement : public Sql_statement
|
||||
class Sql_cmd_analyze_table : public Sql_cmd
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Constructor, used to represent a ANALYZE TABLE statement.
|
||||
@param lex the LEX structure for this statement.
|
||||
*/
|
||||
Analyze_table_statement(LEX *lex)
|
||||
: Sql_statement(lex)
|
||||
Sql_cmd_analyze_table()
|
||||
{}
|
||||
|
||||
~Analyze_table_statement()
|
||||
~Sql_cmd_analyze_table()
|
||||
{}
|
||||
|
||||
/**
|
||||
Execute a ANALYZE TABLE statement at runtime.
|
||||
@param thd the current thread.
|
||||
@return false on success.
|
||||
*/
|
||||
bool execute(THD *thd);
|
||||
|
||||
virtual enum_sql_command sql_command_code() const
|
||||
{
|
||||
return SQLCOM_ANALYZE;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Check_table_statement represents the CHECK TABLE statement.
|
||||
Sql_cmd_check_table represents the CHECK TABLE statement.
|
||||
*/
|
||||
class Check_table_statement : public Sql_statement
|
||||
class Sql_cmd_check_table : public Sql_cmd
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Constructor, used to represent a CHECK TABLE statement.
|
||||
@param lex the LEX structure for this statement.
|
||||
*/
|
||||
Check_table_statement(LEX *lex)
|
||||
: Sql_statement(lex)
|
||||
Sql_cmd_check_table()
|
||||
{}
|
||||
|
||||
~Check_table_statement()
|
||||
~Sql_cmd_check_table()
|
||||
{}
|
||||
|
||||
/**
|
||||
Execute a CHECK TABLE statement at runtime.
|
||||
@param thd the current thread.
|
||||
@return false on success.
|
||||
*/
|
||||
bool execute(THD *thd);
|
||||
|
||||
virtual enum_sql_command sql_command_code() const
|
||||
{
|
||||
return SQLCOM_CHECK;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Optimize_table_statement represents the OPTIMIZE TABLE statement.
|
||||
Sql_cmd_optimize_table represents the OPTIMIZE TABLE statement.
|
||||
*/
|
||||
class Optimize_table_statement : public Sql_statement
|
||||
class Sql_cmd_optimize_table : public Sql_cmd
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Constructor, used to represent a OPTIMIZE TABLE statement.
|
||||
@param lex the LEX structure for this statement.
|
||||
*/
|
||||
Optimize_table_statement(LEX *lex)
|
||||
: Sql_statement(lex)
|
||||
Sql_cmd_optimize_table()
|
||||
{}
|
||||
|
||||
~Optimize_table_statement()
|
||||
~Sql_cmd_optimize_table()
|
||||
{}
|
||||
|
||||
/**
|
||||
Execute a OPTIMIZE TABLE statement at runtime.
|
||||
@param thd the current thread.
|
||||
@return false on success.
|
||||
*/
|
||||
bool execute(THD *thd);
|
||||
|
||||
virtual enum_sql_command sql_command_code() const
|
||||
{
|
||||
return SQLCOM_OPTIMIZE;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Repair_table_statement represents the REPAIR TABLE statement.
|
||||
Sql_cmd_repair_table represents the REPAIR TABLE statement.
|
||||
*/
|
||||
class Repair_table_statement : public Sql_statement
|
||||
class Sql_cmd_repair_table : public Sql_cmd
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Constructor, used to represent a REPAIR TABLE statement.
|
||||
@param lex the LEX structure for this statement.
|
||||
*/
|
||||
Repair_table_statement(LEX *lex)
|
||||
: Sql_statement(lex)
|
||||
Sql_cmd_repair_table()
|
||||
{}
|
||||
|
||||
~Repair_table_statement()
|
||||
~Sql_cmd_repair_table()
|
||||
{}
|
||||
|
||||
/**
|
||||
Execute a REPAIR TABLE statement at runtime.
|
||||
@param thd the current thread.
|
||||
@return false on success.
|
||||
*/
|
||||
bool execute(THD *thd);
|
||||
|
||||
virtual enum_sql_command sql_command_code() const
|
||||
{
|
||||
return SQLCOM_REPAIR;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
273
sql/sql_alter.cc
273
sql/sql_alter.cc
|
|
@ -16,9 +16,176 @@
|
|||
#include "sql_parse.h" // check_access
|
||||
#include "sql_table.h" // mysql_alter_table,
|
||||
// mysql_exchange_partition
|
||||
#include "sql_base.h" // open_temporary_tables
|
||||
#include "sql_alter.h"
|
||||
|
||||
bool Alter_table_statement::execute(THD *thd)
|
||||
Alter_info::Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root)
|
||||
:drop_list(rhs.drop_list, mem_root),
|
||||
alter_list(rhs.alter_list, mem_root),
|
||||
key_list(rhs.key_list, mem_root),
|
||||
create_list(rhs.create_list, mem_root),
|
||||
flags(rhs.flags),
|
||||
keys_onoff(rhs.keys_onoff),
|
||||
partition_names(rhs.partition_names, mem_root),
|
||||
num_parts(rhs.num_parts),
|
||||
requested_algorithm(rhs.requested_algorithm),
|
||||
requested_lock(rhs.requested_lock)
|
||||
{
|
||||
/*
|
||||
Make deep copies of used objects.
|
||||
This is not a fully deep copy - clone() implementations
|
||||
of Alter_drop, Alter_column, Key, foreign_key, Key_part_spec
|
||||
do not copy string constants. At the same length the only
|
||||
reason we make a copy currently is that ALTER/CREATE TABLE
|
||||
code changes input Alter_info definitions, but string
|
||||
constants never change.
|
||||
*/
|
||||
list_copy_and_replace_each_value(drop_list, mem_root);
|
||||
list_copy_and_replace_each_value(alter_list, mem_root);
|
||||
list_copy_and_replace_each_value(key_list, mem_root);
|
||||
list_copy_and_replace_each_value(create_list, mem_root);
|
||||
/* partition_names are not deeply copied currently */
|
||||
}
|
||||
|
||||
|
||||
bool Alter_info::set_requested_algorithm(const LEX_STRING *str)
|
||||
{
|
||||
// To avoid adding new keywords to the grammar, we match strings here.
|
||||
if (!my_strcasecmp(system_charset_info, str->str, "INPLACE"))
|
||||
requested_algorithm= ALTER_TABLE_ALGORITHM_INPLACE;
|
||||
else if (!my_strcasecmp(system_charset_info, str->str, "COPY"))
|
||||
requested_algorithm= ALTER_TABLE_ALGORITHM_COPY;
|
||||
else if (!my_strcasecmp(system_charset_info, str->str, "DEFAULT"))
|
||||
requested_algorithm= ALTER_TABLE_ALGORITHM_DEFAULT;
|
||||
else
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Alter_info::set_requested_lock(const LEX_STRING *str)
|
||||
{
|
||||
// To avoid adding new keywords to the grammar, we match strings here.
|
||||
if (!my_strcasecmp(system_charset_info, str->str, "NONE"))
|
||||
requested_lock= ALTER_TABLE_LOCK_NONE;
|
||||
else if (!my_strcasecmp(system_charset_info, str->str, "SHARED"))
|
||||
requested_lock= ALTER_TABLE_LOCK_SHARED;
|
||||
else if (!my_strcasecmp(system_charset_info, str->str, "EXCLUSIVE"))
|
||||
requested_lock= ALTER_TABLE_LOCK_EXCLUSIVE;
|
||||
else if (!my_strcasecmp(system_charset_info, str->str, "DEFAULT"))
|
||||
requested_lock= ALTER_TABLE_LOCK_DEFAULT;
|
||||
else
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Alter_table_ctx::Alter_table_ctx()
|
||||
: datetime_field(NULL), error_if_not_empty(false),
|
||||
tables_opened(0),
|
||||
db(NULL), table_name(NULL), alias(NULL),
|
||||
new_db(NULL), new_name(NULL), new_alias(NULL),
|
||||
fk_error_if_delete_row(false), fk_error_id(NULL),
|
||||
fk_error_table(NULL)
|
||||
#ifndef DBUG_OFF
|
||||
, tmp_table(false)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Alter_table_ctx::Alter_table_ctx(THD *thd, TABLE_LIST *table_list,
|
||||
uint tables_opened_arg,
|
||||
char *new_db_arg, char *new_name_arg)
|
||||
: datetime_field(NULL), error_if_not_empty(false),
|
||||
tables_opened(tables_opened_arg),
|
||||
new_db(new_db_arg), new_name(new_name_arg),
|
||||
fk_error_if_delete_row(false), fk_error_id(NULL),
|
||||
fk_error_table(NULL)
|
||||
#ifndef DBUG_OFF
|
||||
, tmp_table(false)
|
||||
#endif
|
||||
{
|
||||
/*
|
||||
Assign members db, table_name, new_db and new_name
|
||||
to simplify further comparisions: we want to see if it's a RENAME
|
||||
later just by comparing the pointers, avoiding the need for strcmp.
|
||||
*/
|
||||
db= table_list->db;
|
||||
table_name= table_list->table_name;
|
||||
alias= (lower_case_table_names == 2) ? table_list->alias : table_name;
|
||||
|
||||
if (!new_db || !my_strcasecmp(table_alias_charset, new_db, db))
|
||||
new_db= db;
|
||||
|
||||
if (new_name)
|
||||
{
|
||||
DBUG_PRINT("info", ("new_db.new_name: '%s'.'%s'", new_db, new_name));
|
||||
|
||||
if (lower_case_table_names == 1) // Convert new_name/new_alias to lower case
|
||||
{
|
||||
my_casedn_str(files_charset_info, new_name);
|
||||
new_alias= new_name;
|
||||
}
|
||||
else if (lower_case_table_names == 2) // Convert new_name to lower case
|
||||
{
|
||||
strmov(new_alias= new_alias_buff, new_name);
|
||||
my_casedn_str(files_charset_info, new_name);
|
||||
}
|
||||
else
|
||||
new_alias= new_name; // LCTN=0 => case sensitive + case preserving
|
||||
|
||||
if (!is_database_changed() &&
|
||||
!my_strcasecmp(table_alias_charset, new_name, table_name))
|
||||
{
|
||||
/*
|
||||
Source and destination table names are equal:
|
||||
make is_table_renamed() more efficient.
|
||||
*/
|
||||
new_alias= table_name;
|
||||
new_name= table_name;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
new_alias= alias;
|
||||
new_name= table_name;
|
||||
}
|
||||
|
||||
my_snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix,
|
||||
current_pid, thd->thread_id);
|
||||
/* Safety fix for InnoDB */
|
||||
if (lower_case_table_names)
|
||||
my_casedn_str(files_charset_info, tmp_name);
|
||||
|
||||
if (table_list->table->s->tmp_table == NO_TMP_TABLE)
|
||||
{
|
||||
build_table_filename(path, sizeof(path) - 1, db, table_name, "", 0);
|
||||
|
||||
build_table_filename(new_path, sizeof(new_path) - 1, new_db, new_name, "", 0);
|
||||
|
||||
build_table_filename(new_filename, sizeof(new_filename) - 1,
|
||||
new_db, new_name, reg_ext, 0);
|
||||
|
||||
build_table_filename(tmp_path, sizeof(tmp_path) - 1, new_db, tmp_name, "",
|
||||
FN_IS_TMP);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
We are not filling path, new_path and new_filename members if
|
||||
we are altering temporary table as these members are not used in
|
||||
this case. This fact is enforced with assert.
|
||||
*/
|
||||
build_tmptable_filename(thd, tmp_path, sizeof(tmp_path));
|
||||
#ifndef DBUG_OFF
|
||||
tmp_table= true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Sql_cmd_alter_table::execute(THD *thd)
|
||||
{
|
||||
LEX *lex= thd->lex;
|
||||
/* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */
|
||||
|
|
@ -38,7 +205,7 @@ bool Alter_table_statement::execute(THD *thd)
|
|||
ulong priv_needed= ALTER_ACL;
|
||||
bool result;
|
||||
|
||||
DBUG_ENTER("Alter_table_statement::execute");
|
||||
DBUG_ENTER("Sql_cmd_alter_table::execute");
|
||||
|
||||
if (thd->is_fatal_error) /* out of memory creating a copy of alter_info */
|
||||
DBUG_RETURN(TRUE);
|
||||
|
|
@ -46,12 +213,14 @@ bool Alter_table_statement::execute(THD *thd)
|
|||
We also require DROP priv for ALTER TABLE ... DROP PARTITION, as well
|
||||
as for RENAME TO, as being done by SQLCOM_RENAME_TABLE
|
||||
*/
|
||||
if (alter_info.flags & (ALTER_DROP_PARTITION | ALTER_RENAME))
|
||||
if (alter_info.flags & (Alter_info::ALTER_DROP_PARTITION |
|
||||
Alter_info::ALTER_RENAME))
|
||||
priv_needed|= DROP_ACL;
|
||||
|
||||
/* Must be set in the parser */
|
||||
DBUG_ASSERT(select_lex->db);
|
||||
DBUG_ASSERT(!(alter_info.flags & ALTER_ADMIN_PARTITION));
|
||||
DBUG_ASSERT(!(alter_info.flags & Alter_info::ALTER_EXCHANGE_PARTITION));
|
||||
DBUG_ASSERT(!(alter_info.flags & Alter_info::ALTER_ADMIN_PARTITION));
|
||||
if (check_access(thd, priv_needed, first_table->db,
|
||||
&first_table->grant.privilege,
|
||||
&first_table->grant.m_internal,
|
||||
|
|
@ -63,10 +232,47 @@ bool Alter_table_statement::execute(THD *thd)
|
|||
DBUG_RETURN(TRUE); /* purecov: inspected */
|
||||
|
||||
/* If it is a merge table, check privileges for merge children. */
|
||||
if (create_info.merge_list.first &&
|
||||
check_table_access(thd, SELECT_ACL | UPDATE_ACL | DELETE_ACL,
|
||||
create_info.merge_list.first, FALSE, UINT_MAX, FALSE))
|
||||
DBUG_RETURN(TRUE);
|
||||
if (create_info.merge_list.first)
|
||||
{
|
||||
/*
|
||||
The user must have (SELECT_ACL | UPDATE_ACL | DELETE_ACL) on the
|
||||
underlying base tables, even if there are temporary tables with the same
|
||||
names.
|
||||
|
||||
From user's point of view, it might look as if the user must have these
|
||||
privileges on temporary tables to create a merge table over them. This is
|
||||
one of two cases when a set of privileges is required for operations on
|
||||
temporary tables (see also CREATE TABLE).
|
||||
|
||||
The reason for this behavior stems from the following facts:
|
||||
|
||||
- For merge tables, the underlying table privileges are checked only
|
||||
at CREATE TABLE / ALTER TABLE time.
|
||||
|
||||
In other words, once a merge table is created, the privileges of
|
||||
the underlying tables can be revoked, but the user will still have
|
||||
access to the merge table (provided that the user has privileges on
|
||||
the merge table itself).
|
||||
|
||||
- Temporary tables shadow base tables.
|
||||
|
||||
I.e. there might be temporary and base tables with the same name, and
|
||||
the temporary table takes the precedence in all operations.
|
||||
|
||||
- For temporary MERGE tables we do not track if their child tables are
|
||||
base or temporary. As result we can't guarantee that privilege check
|
||||
which was done in presence of temporary child will stay relevant later
|
||||
as this temporary table might be removed.
|
||||
|
||||
If SELECT_ACL | UPDATE_ACL | DELETE_ACL privileges were not checked for
|
||||
the underlying *base* tables, it would create a security breach as in
|
||||
Bug#12771903.
|
||||
*/
|
||||
|
||||
if (check_table_access(thd, SELECT_ACL | UPDATE_ACL | DELETE_ACL,
|
||||
create_info.merge_list.first, FALSE, UINT_MAX, FALSE))
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
if (check_grant(thd, priv_needed, first_table, FALSE, UINT_MAX, FALSE))
|
||||
DBUG_RETURN(TRUE); /* purecov: inspected */
|
||||
|
|
@ -75,7 +281,7 @@ bool Alter_table_statement::execute(THD *thd)
|
|||
{
|
||||
// Rename of table
|
||||
TABLE_LIST tmp_table;
|
||||
bzero((char*) &tmp_table,sizeof(tmp_table));
|
||||
memset(&tmp_table, 0, sizeof(tmp_table));
|
||||
tmp_table.table_name= lex->name.str;
|
||||
tmp_table.db= select_lex->db;
|
||||
tmp_table.grant.privilege= priv;
|
||||
|
|
@ -86,11 +292,11 @@ bool Alter_table_statement::execute(THD *thd)
|
|||
|
||||
/* Don't yet allow changing of symlinks with ALTER TABLE */
|
||||
if (create_info.data_file_name)
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
WARN_OPTION_IGNORED, ER(WARN_OPTION_IGNORED),
|
||||
"DATA DIRECTORY");
|
||||
if (create_info.index_file_name)
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
WARN_OPTION_IGNORED, ER(WARN_OPTION_IGNORED),
|
||||
"INDEX DIRECTORY");
|
||||
create_info.data_file_name= create_info.index_file_name= NULL;
|
||||
|
|
@ -103,7 +309,50 @@ bool Alter_table_statement::execute(THD *thd)
|
|||
&alter_info,
|
||||
select_lex->order_list.elements,
|
||||
select_lex->order_list.first,
|
||||
lex->ignore, lex->online);
|
||||
lex->ignore);
|
||||
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
|
||||
bool Sql_cmd_discard_import_tablespace::execute(THD *thd)
|
||||
{
|
||||
/* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */
|
||||
SELECT_LEX *select_lex= &thd->lex->select_lex;
|
||||
/* first table of first SELECT_LEX */
|
||||
TABLE_LIST *table_list= (TABLE_LIST*) select_lex->table_list.first;
|
||||
|
||||
if (check_access(thd, ALTER_ACL, table_list->db,
|
||||
&table_list->grant.privilege,
|
||||
&table_list->grant.m_internal,
|
||||
0, 0))
|
||||
return true;
|
||||
|
||||
if (check_grant(thd, ALTER_ACL, table_list, false, UINT_MAX, false))
|
||||
return true;
|
||||
|
||||
thd->enable_slow_log= opt_log_slow_admin_statements;
|
||||
|
||||
/*
|
||||
Check if we attempt to alter mysql.slow_log or
|
||||
mysql.general_log table and return an error if
|
||||
it is the case.
|
||||
TODO: this design is obsolete and will be removed.
|
||||
*/
|
||||
int table_kind= check_if_log_table(table_list->db_length, table_list->db,
|
||||
table_list->table_name_length,
|
||||
table_list->table_name, false);
|
||||
|
||||
if (table_kind)
|
||||
{
|
||||
/* Disable alter of enabled log tables */
|
||||
if (logger.is_log_table_enabled(table_kind))
|
||||
{
|
||||
my_error(ER_BAD_LOG_STATEMENT, MYF(0), "ALTER");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
mysql_discard_or_import_tablespace(thd, table_list,
|
||||
m_tablespace_op == DISCARD_TABLESPACE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ void mysql_audit_general(THD *thd, uint event_subtype,
|
|||
query= thd->query_string;
|
||||
user= user_buff;
|
||||
userlen= make_user_name(thd, user_buff);
|
||||
rows= thd->warning_info->current_row_for_warning();
|
||||
rows= thd->get_stmt_da()->current_row_for_warning();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -139,7 +139,7 @@ void mysql_audit_general(THD *thd, uint event_subtype,
|
|||
|
||||
#define MYSQL_AUDIT_NOTIFY_CONNECTION_CONNECT(thd) mysql_audit_notify(\
|
||||
(thd), MYSQL_AUDIT_CONNECTION_CLASS, MYSQL_AUDIT_CONNECTION_CONNECT,\
|
||||
(thd)->stmt_da->is_error() ? (thd)->stmt_da->sql_errno() : 0,\
|
||||
(thd)->get_stmt_da()->is_error() ? (thd)->get_stmt_da()->sql_errno() : 0,\
|
||||
(thd)->thread_id, (thd)->security_ctx->user,\
|
||||
(thd)->security_ctx->user ? strlen((thd)->security_ctx->user) : 0,\
|
||||
(thd)->security_ctx->priv_user, strlen((thd)->security_ctx->priv_user),\
|
||||
|
|
@ -160,7 +160,7 @@ void mysql_audit_general(THD *thd, uint event_subtype,
|
|||
|
||||
#define MYSQL_AUDIT_NOTIFY_CONNECTION_CHANGE_USER(thd) mysql_audit_notify(\
|
||||
(thd), MYSQL_AUDIT_CONNECTION_CLASS, MYSQL_AUDIT_CONNECTION_CHANGE_USER,\
|
||||
(thd)->stmt_da->is_error() ? (thd)->stmt_da->sql_errno() : 0,\
|
||||
(thd)->get_stmt_da()->is_error() ? (thd)->get_stmt_da()->sql_errno() : 0,\
|
||||
(thd)->thread_id, (thd)->security_ctx->user,\
|
||||
(thd)->security_ctx->user ? strlen((thd)->security_ctx->user) : 0,\
|
||||
(thd)->security_ctx->priv_user, strlen((thd)->security_ctx->priv_user),\
|
||||
|
|
|
|||
826
sql/sql_base.cc
826
sql/sql_base.cc
File diff suppressed because it is too large
Load diff
|
|
@ -60,7 +60,8 @@ enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND,
|
|||
IGNORE_EXCEPT_NON_UNIQUE};
|
||||
|
||||
enum enum_tdc_remove_table_type {TDC_RT_REMOVE_ALL, TDC_RT_REMOVE_NOT_OWN,
|
||||
TDC_RT_REMOVE_UNUSED};
|
||||
TDC_RT_REMOVE_UNUSED,
|
||||
TDC_RT_REMOVE_NOT_OWN_KEEP_SHARE};
|
||||
|
||||
/* bits for last argument to remove_table_from_cache() */
|
||||
#define RTFC_NO_FLAG 0x0000
|
||||
|
|
@ -76,13 +77,12 @@ bool table_def_init(void);
|
|||
void table_def_free(void);
|
||||
void table_def_start_shutdown(void);
|
||||
void assign_new_table_id(TABLE_SHARE *share);
|
||||
uint cached_open_tables(void);
|
||||
uint cached_table_definitions(void);
|
||||
uint create_table_def_key(THD *thd, char *key,
|
||||
const TABLE_LIST *table_list,
|
||||
bool tmp_table);
|
||||
TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key,
|
||||
uint key_length, uint db_flags, int *error,
|
||||
uint cached_open_tables(void);
|
||||
uint get_table_def_key(const TABLE_LIST *table_list, const char **key);
|
||||
TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list,
|
||||
const char *key, uint key_length,
|
||||
uint db_flags, int *error,
|
||||
my_hash_value_type hash_value);
|
||||
void release_table_share(TABLE_SHARE *share);
|
||||
TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name);
|
||||
|
|
@ -128,6 +128,11 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update,
|
|||
*/
|
||||
#define MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK 0x1000
|
||||
#define MYSQL_LOCK_NOT_TEMPORARY 0x2000
|
||||
/**
|
||||
Only check THD::killed if waits happen (e.g. wait on MDL, wait on
|
||||
table flush, wait on thr_lock.c locks) while opening and locking table.
|
||||
*/
|
||||
#define MYSQL_OPEN_IGNORE_KILLED 0x4000
|
||||
|
||||
/** Please refer to the internals manual. */
|
||||
#define MYSQL_OPEN_REOPEN (MYSQL_OPEN_IGNORE_FLUSH |\
|
||||
|
|
@ -140,6 +145,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update,
|
|||
|
||||
bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
||||
Open_table_context *ot_ctx);
|
||||
|
||||
bool open_new_frm(THD *thd, TABLE_SHARE *share, const char *alias,
|
||||
uint db_stat, uint prgflag,
|
||||
uint ha_open_flags, TABLE *outparam, TABLE_LIST *table_desc,
|
||||
|
|
@ -149,7 +155,8 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table,
|
|||
List<String> *index_list);
|
||||
TABLE *open_table_uncached(THD *thd, const char *path, const char *db,
|
||||
const char *table_name,
|
||||
bool add_to_temporary_tables_list);
|
||||
bool add_to_temporary_tables_list,
|
||||
bool open_in_engine);
|
||||
TABLE *find_locked_table(TABLE *list, const char *db, const char *table_name);
|
||||
TABLE *find_write_locked_table(TABLE *list, const char *db,
|
||||
const char *table_name);
|
||||
|
|
@ -158,7 +165,7 @@ thr_lock_type read_lock_type_for_table(THD *thd,
|
|||
TABLE_LIST *table_list);
|
||||
|
||||
my_bool mysql_rm_tmp_tables(void);
|
||||
bool rm_temporary_table(handlerton *base, char *path);
|
||||
bool rm_temporary_table(handlerton *base, const char *path);
|
||||
void close_tables_for_reopen(THD *thd, TABLE_LIST **tables,
|
||||
const MDL_savepoint &start_of_statement_svp);
|
||||
TABLE_LIST *find_table_in_list(TABLE_LIST *table,
|
||||
|
|
@ -191,6 +198,8 @@ bool setup_fields(THD *thd, Item** ref_pointer_array,
|
|||
List<Item> &item, enum_mark_columns mark_used_columns,
|
||||
List<Item> *sum_func_list, bool allow_sum_func);
|
||||
void unfix_fields(List<Item> &items);
|
||||
bool fill_record(THD * thd, TABLE *table_arg, List<Item> &fields,
|
||||
List<Item> &values, bool ignore_errors);
|
||||
bool fill_record(THD *thd, TABLE *table, Field **field, List<Item> &values,
|
||||
bool ignore_errors, bool use_value);
|
||||
|
||||
|
|
@ -260,7 +269,7 @@ bool lock_tables(THD *thd, TABLE_LIST *tables, uint counter, uint flags);
|
|||
int decide_logging_format(THD *thd, TABLE_LIST *tables);
|
||||
void free_io_cache(TABLE *entry);
|
||||
void intern_close_table(TABLE *entry);
|
||||
bool close_thread_table(THD *thd, TABLE **table_ptr);
|
||||
void close_thread_table(THD *thd, TABLE **table_ptr);
|
||||
bool close_temporary_tables(THD *thd);
|
||||
TABLE_LIST *unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
|
||||
bool check_alias);
|
||||
|
|
@ -270,6 +279,8 @@ void close_temporary_table(THD *thd, TABLE *table, bool free_share,
|
|||
void close_temporary(TABLE *table, bool free_share, bool delete_table);
|
||||
bool rename_temporary_table(THD* thd, TABLE *table, const char *new_db,
|
||||
const char *table_name);
|
||||
bool open_temporary_tables(THD *thd, TABLE_LIST *tl_list);
|
||||
bool open_temporary_table(THD *thd, TABLE_LIST *tl);
|
||||
bool is_equal(const LEX_STRING *a, const LEX_STRING *b);
|
||||
|
||||
class Open_tables_backup;
|
||||
|
|
@ -290,13 +301,14 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables,
|
|||
bool wait_for_refresh, ulong timeout);
|
||||
bool close_cached_connection_tables(THD *thd, LEX_STRING *connect_string);
|
||||
void close_all_tables_for_name(THD *thd, TABLE_SHARE *share,
|
||||
ha_extra_function extra);
|
||||
ha_extra_function extra,
|
||||
TABLE *skip_table);
|
||||
OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *db, const char *wild);
|
||||
void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
|
||||
const char *db, const char *table_name,
|
||||
bool has_lock);
|
||||
bool tdc_open_view(THD *thd, TABLE_LIST *table_list, const char *alias,
|
||||
char *cache_key, uint cache_key_length,
|
||||
const char *cache_key, uint cache_key_length,
|
||||
MEM_ROOT *mem_root, uint flags);
|
||||
void tdc_flush_unused_tables();
|
||||
TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db,
|
||||
|
|
@ -457,11 +469,6 @@ class Lock_tables_prelocking_strategy : public DML_prelocking_strategy
|
|||
class Alter_table_prelocking_strategy : public Prelocking_strategy
|
||||
{
|
||||
public:
|
||||
|
||||
Alter_table_prelocking_strategy(Alter_info *alter_info)
|
||||
: m_alter_info(alter_info)
|
||||
{}
|
||||
|
||||
virtual bool handle_routine(THD *thd, Query_tables_list *prelocking_ctx,
|
||||
Sroutine_hash_entry *rt, sp_head *sp,
|
||||
bool *need_prelocking);
|
||||
|
|
@ -469,9 +476,6 @@ public:
|
|||
TABLE_LIST *table_list, bool *need_prelocking);
|
||||
virtual bool handle_view(THD *thd, Query_tables_list *prelocking_ctx,
|
||||
TABLE_LIST *table_list, bool *need_prelocking);
|
||||
|
||||
private:
|
||||
Alter_info *m_alter_info;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -592,6 +596,30 @@ private:
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
Check if a TABLE_LIST instance represents a pre-opened temporary table.
|
||||
*/
|
||||
|
||||
inline bool is_temporary_table(TABLE_LIST *tl)
|
||||
{
|
||||
if (tl->view || tl->schema_table)
|
||||
return FALSE;
|
||||
|
||||
if (!tl->table)
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
NOTE: 'table->s' might be NULL for specially constructed TABLE
|
||||
instances. See SHOW TRIGGERS for example.
|
||||
*/
|
||||
|
||||
if (!tl->table->s)
|
||||
return FALSE;
|
||||
|
||||
return tl->table->s->tmp_table != NO_TMP_TABLE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This internal handler is used to trap ER_NO_SUCH_TABLE.
|
||||
*/
|
||||
|
|
@ -606,9 +634,9 @@ public:
|
|||
bool handle_condition(THD *thd,
|
||||
uint sql_errno,
|
||||
const char* sqlstate,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
Sql_condition::enum_warning_level level,
|
||||
const char* msg,
|
||||
MYSQL_ERROR ** cond_hdl);
|
||||
Sql_condition ** cond_hdl);
|
||||
|
||||
/**
|
||||
Returns TRUE if one or more ER_NO_SUCH_TABLE errors have been
|
||||
|
|
|
|||
|
|
@ -1173,7 +1173,7 @@ void Query_cache::end_of_result(THD *thd)
|
|||
DBUG_VOID_RETURN;
|
||||
|
||||
/* Ensure that only complete results are cached. */
|
||||
DBUG_ASSERT(thd->stmt_da->is_eof());
|
||||
DBUG_ASSERT(thd->get_stmt_da()->is_eof());
|
||||
|
||||
if (thd->killed)
|
||||
{
|
||||
|
|
@ -2089,8 +2089,8 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
|
|||
response, we can't handle it anyway.
|
||||
*/
|
||||
(void) trans_commit_stmt(thd);
|
||||
if (!thd->stmt_da->is_set())
|
||||
thd->stmt_da->disable_status();
|
||||
if (!thd->get_stmt_da()->is_set())
|
||||
thd->get_stmt_da()->disable_status();
|
||||
|
||||
BLOCK_UNLOCK_RD(query_block);
|
||||
MYSQL_QUERY_CACHE_HIT(thd->query(), (ulong) thd->limit_found_rows);
|
||||
|
|
|
|||
143
sql/sql_class.cc
143
sql/sql_class.cc
|
|
@ -691,7 +691,7 @@ int thd_tx_is_read_only(const THD *thd)
|
|||
extern "C"
|
||||
void thd_inc_row_count(THD *thd)
|
||||
{
|
||||
thd->warning_info->inc_current_row_for_warning();
|
||||
thd->get_stmt_da()->inc_current_row_for_warning();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -810,9 +810,9 @@ char *thd_security_context(THD *thd, char *buffer, unsigned int length,
|
|||
bool Drop_table_error_handler::handle_condition(THD *thd,
|
||||
uint sql_errno,
|
||||
const char* sqlstate,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
Sql_condition::enum_warning_level level,
|
||||
const char* msg,
|
||||
MYSQL_ERROR ** cond_hdl)
|
||||
Sql_condition ** cond_hdl)
|
||||
{
|
||||
*cond_hdl= NULL;
|
||||
return ((sql_errno == EE_DELETE && my_errno == ENOENT) ||
|
||||
|
|
@ -835,8 +835,6 @@ THD::THD()
|
|||
stmt_depends_on_first_successful_insert_id_in_prev_stmt(FALSE),
|
||||
m_examined_row_count(0),
|
||||
accessed_rows_and_keys(0),
|
||||
warning_info(&main_warning_info),
|
||||
stmt_da(&main_da),
|
||||
m_statement_psi(NULL),
|
||||
m_idle_psi(NULL),
|
||||
m_server_idle(false),
|
||||
|
|
@ -856,7 +854,8 @@ THD::THD()
|
|||
#if defined(ENABLED_DEBUG_SYNC)
|
||||
debug_sync_control(0),
|
||||
#endif /* defined(ENABLED_DEBUG_SYNC) */
|
||||
main_warning_info(0, false, false)
|
||||
main_da(0, false),
|
||||
m_stmt_da(&main_da)
|
||||
{
|
||||
ulong tmp;
|
||||
|
||||
|
|
@ -868,8 +867,8 @@ THD::THD()
|
|||
THD *old_THR_THD= current_thd;
|
||||
set_current_thd(this);
|
||||
status_var.memory_used= 0;
|
||||
main_da.init();
|
||||
|
||||
main_warning_info.init();
|
||||
/*
|
||||
Pass nominal parameters to init_alloc_root only to ensure that
|
||||
the destructor works OK in case of an error. The main_mem_root
|
||||
|
|
@ -1029,9 +1028,9 @@ void THD::push_internal_handler(Internal_error_handler *handler)
|
|||
|
||||
bool THD::handle_condition(uint sql_errno,
|
||||
const char* sqlstate,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
Sql_condition::enum_warning_level level,
|
||||
const char* msg,
|
||||
MYSQL_ERROR ** cond_hdl)
|
||||
Sql_condition ** cond_hdl)
|
||||
{
|
||||
if (!m_internal_handler)
|
||||
{
|
||||
|
|
@ -1068,7 +1067,7 @@ void THD::raise_error(uint sql_errno)
|
|||
const char* msg= ER(sql_errno);
|
||||
(void) raise_condition(sql_errno,
|
||||
NULL,
|
||||
MYSQL_ERROR::WARN_LEVEL_ERROR,
|
||||
Sql_condition::WARN_LEVEL_ERROR,
|
||||
msg);
|
||||
}
|
||||
|
||||
|
|
@ -1084,7 +1083,7 @@ void THD::raise_error_printf(uint sql_errno, ...)
|
|||
va_end(args);
|
||||
(void) raise_condition(sql_errno,
|
||||
NULL,
|
||||
MYSQL_ERROR::WARN_LEVEL_ERROR,
|
||||
Sql_condition::WARN_LEVEL_ERROR,
|
||||
ebuff);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
|
@ -1094,7 +1093,7 @@ void THD::raise_warning(uint sql_errno)
|
|||
const char* msg= ER(sql_errno);
|
||||
(void) raise_condition(sql_errno,
|
||||
NULL,
|
||||
MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
Sql_condition::WARN_LEVEL_WARN,
|
||||
msg);
|
||||
}
|
||||
|
||||
|
|
@ -1110,7 +1109,7 @@ void THD::raise_warning_printf(uint sql_errno, ...)
|
|||
va_end(args);
|
||||
(void) raise_condition(sql_errno,
|
||||
NULL,
|
||||
MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
Sql_condition::WARN_LEVEL_WARN,
|
||||
ebuff);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
|
@ -1124,7 +1123,7 @@ void THD::raise_note(uint sql_errno)
|
|||
const char* msg= ER(sql_errno);
|
||||
(void) raise_condition(sql_errno,
|
||||
NULL,
|
||||
MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
Sql_condition::WARN_LEVEL_NOTE,
|
||||
msg);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
|
@ -1143,24 +1142,25 @@ void THD::raise_note_printf(uint sql_errno, ...)
|
|||
va_end(args);
|
||||
(void) raise_condition(sql_errno,
|
||||
NULL,
|
||||
MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
Sql_condition::WARN_LEVEL_NOTE,
|
||||
ebuff);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
MYSQL_ERROR* THD::raise_condition(uint sql_errno,
|
||||
Sql_condition* THD::raise_condition(uint sql_errno,
|
||||
const char* sqlstate,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
Sql_condition::enum_warning_level level,
|
||||
const char* msg)
|
||||
{
|
||||
MYSQL_ERROR *cond= NULL;
|
||||
Diagnostics_area *da= get_stmt_da();
|
||||
Sql_condition *cond= NULL;
|
||||
DBUG_ENTER("THD::raise_condition");
|
||||
|
||||
if (!(variables.option_bits & OPTION_SQL_NOTES) &&
|
||||
(level == MYSQL_ERROR::WARN_LEVEL_NOTE))
|
||||
(level == Sql_condition::WARN_LEVEL_NOTE))
|
||||
DBUG_RETURN(NULL);
|
||||
|
||||
warning_info->opt_clear_warning_info(query_id);
|
||||
da->opt_clear_warning_info(query_id);
|
||||
|
||||
/*
|
||||
TODO: replace by DBUG_ASSERT(sql_errno != 0) once all bugs similar to
|
||||
|
|
@ -1174,24 +1174,24 @@ MYSQL_ERROR* THD::raise_condition(uint sql_errno,
|
|||
if (sqlstate == NULL)
|
||||
sqlstate= mysql_errno_to_sqlstate(sql_errno);
|
||||
|
||||
if ((level == MYSQL_ERROR::WARN_LEVEL_WARN) &&
|
||||
if ((level == Sql_condition::WARN_LEVEL_WARN) &&
|
||||
really_abort_on_warning())
|
||||
{
|
||||
/*
|
||||
FIXME:
|
||||
push_warning and strict SQL_MODE case.
|
||||
*/
|
||||
level= MYSQL_ERROR::WARN_LEVEL_ERROR;
|
||||
level= Sql_condition::WARN_LEVEL_ERROR;
|
||||
killed= KILL_BAD_DATA;
|
||||
}
|
||||
|
||||
switch (level)
|
||||
{
|
||||
case MYSQL_ERROR::WARN_LEVEL_NOTE:
|
||||
case MYSQL_ERROR::WARN_LEVEL_WARN:
|
||||
case Sql_condition::WARN_LEVEL_NOTE:
|
||||
case Sql_condition::WARN_LEVEL_WARN:
|
||||
got_warning= 1;
|
||||
break;
|
||||
case MYSQL_ERROR::WARN_LEVEL_ERROR:
|
||||
case Sql_condition::WARN_LEVEL_ERROR:
|
||||
break;
|
||||
default:
|
||||
DBUG_ASSERT(FALSE);
|
||||
|
|
@ -1200,14 +1200,14 @@ MYSQL_ERROR* THD::raise_condition(uint sql_errno,
|
|||
if (handle_condition(sql_errno, sqlstate, level, msg, &cond))
|
||||
DBUG_RETURN(cond);
|
||||
|
||||
if (level == MYSQL_ERROR::WARN_LEVEL_ERROR)
|
||||
if (level == Sql_condition::WARN_LEVEL_ERROR)
|
||||
{
|
||||
is_slave_error= 1; // needed to catch query errors during replication
|
||||
|
||||
if (! stmt_da->is_error())
|
||||
if (!da->is_error())
|
||||
{
|
||||
set_row_count_func(-1);
|
||||
stmt_da->set_error_status(this, sql_errno, msg, sqlstate);
|
||||
da->set_error_status(sql_errno, msg, sqlstate, cond);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1216,7 +1216,7 @@ MYSQL_ERROR* THD::raise_condition(uint sql_errno,
|
|||
/* When simulating OOM, skip writing to error log to avoid mtr errors */
|
||||
DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_RETURN(NULL););
|
||||
|
||||
cond= warning_info->push_warning(this, sql_errno, sqlstate, level, msg);
|
||||
da->push_warning(this, sql_errno, sqlstate, level, msg);
|
||||
DBUG_RETURN(cond);
|
||||
}
|
||||
|
||||
|
|
@ -1553,7 +1553,7 @@ THD::~THD()
|
|||
#endif
|
||||
|
||||
free_root(&main_mem_root, MYF(0));
|
||||
main_warning_info.free_memory();
|
||||
main_da.free_memory();
|
||||
if (status_var.memory_used != 0)
|
||||
{
|
||||
DBUG_PRINT("error", ("memory_used: %lld", status_var.memory_used));
|
||||
|
|
@ -1942,42 +1942,6 @@ void THD::cleanup_after_query()
|
|||
table_map_for_update= 0;
|
||||
m_binlog_invoker= FALSE;
|
||||
|
||||
extern "C" enum durability_properties thd_get_durability_property(const MYSQL_THD thd)
|
||||
{
|
||||
enum durability_properties ret= HA_REGULAR_DURABILITY;
|
||||
|
||||
if (thd != NULL)
|
||||
ret= thd->durability_property;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Get the auto_increment_offset auto_increment_increment.
|
||||
Needed by InnoDB.
|
||||
@param thd Thread object
|
||||
@param off auto_increment_offset
|
||||
@param inc auto_increment_increment */
|
||||
extern "C" void thd_get_autoinc(const MYSQL_THD thd, ulong* off, ulong* inc)
|
||||
{
|
||||
*off = thd->variables.auto_increment_offset;
|
||||
*inc = thd->variables.auto_increment_increment;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Is strict sql_mode set.
|
||||
Needed by InnoDB.
|
||||
@param thd Thread object
|
||||
@return True if sql_mode has strict mode (all or trans).
|
||||
@retval true sql_mode has strict mode (all or trans).
|
||||
@retval false sql_mode has not strict mode (all or trans).
|
||||
*/
|
||||
extern "C" bool thd_is_strict_mode(const MYSQL_THD thd)
|
||||
{
|
||||
return thd->is_strict_mode();
|
||||
}
|
||||
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
if (rli_slave)
|
||||
rli_slave->cleanup_after_query();
|
||||
|
|
@ -2691,7 +2655,7 @@ select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
|
|||
|
||||
Non-ASCII separator arguments are not fully supported
|
||||
*/
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
WARN_NON_ASCII_SEPARATOR_NOT_IMPLEMENTED,
|
||||
ER(WARN_NON_ASCII_SEPARATOR_NOT_IMPLEMENTED));
|
||||
}
|
||||
|
|
@ -2722,7 +2686,7 @@ select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
|
|||
(exchange->opt_enclosed && non_string_results &&
|
||||
field_term_length && strchr(NUMERIC_CHARS, field_term_char)))
|
||||
{
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_AMBIGUOUS_FIELD_TERM, ER(ER_AMBIGUOUS_FIELD_TERM));
|
||||
is_ambiguous_field_term= TRUE;
|
||||
}
|
||||
|
|
@ -2805,7 +2769,7 @@ int select_export::send_data(List<Item> &items)
|
|||
convert_to_printable(printable_buff, sizeof(printable_buff),
|
||||
error_pos, res->ptr() + res->length() - error_pos,
|
||||
res->charset(), 6);
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
|
||||
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
|
||||
"string", printable_buff,
|
||||
|
|
@ -2816,7 +2780,7 @@ int select_export::send_data(List<Item> &items)
|
|||
/*
|
||||
result is longer than UINT_MAX32 and doesn't fit into String
|
||||
*/
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
WARN_DATA_TRUNCATED, ER(WARN_DATA_TRUNCATED),
|
||||
item->full_name(), static_cast<long>(row_count));
|
||||
}
|
||||
|
|
@ -3621,7 +3585,7 @@ int select_dumpvar::send_data(List<Item> &items)
|
|||
bool select_dumpvar::send_eof()
|
||||
{
|
||||
if (! row_count)
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_SP_FETCH_NO_DATA, ER(ER_SP_FETCH_NO_DATA));
|
||||
/*
|
||||
Don't send EOF if we're in error condition (which implies we've already
|
||||
|
|
@ -4202,6 +4166,41 @@ extern "C" bool thd_sqlcom_can_generate_row_events(const MYSQL_THD thd)
|
|||
}
|
||||
|
||||
|
||||
extern "C" enum durability_properties thd_get_durability_property(const MYSQL_THD thd)
|
||||
{
|
||||
enum durability_properties ret= HA_REGULAR_DURABILITY;
|
||||
|
||||
if (thd != NULL)
|
||||
ret= thd->durability_property;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Get the auto_increment_offset auto_increment_increment.
|
||||
Needed by InnoDB.
|
||||
@param thd Thread object
|
||||
@param off auto_increment_offset
|
||||
@param inc auto_increment_increment */
|
||||
extern "C" void thd_get_autoinc(const MYSQL_THD thd, ulong* off, ulong* inc)
|
||||
{
|
||||
*off = thd->variables.auto_increment_offset;
|
||||
*inc = thd->variables.auto_increment_increment;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Is strict sql_mode set.
|
||||
Needed by InnoDB.
|
||||
@param thd Thread object
|
||||
@return True if sql_mode has strict mode (all or trans).
|
||||
@retval true sql_mode has strict mode (all or trans).
|
||||
@retval false sql_mode has not strict mode (all or trans).
|
||||
*/
|
||||
extern "C" bool thd_is_strict_mode(const MYSQL_THD thd)
|
||||
{
|
||||
return thd->is_strict_mode();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Interface for MySQL Server, plugins and storage engines to report
|
||||
|
|
@ -5691,7 +5690,7 @@ void THD::issue_unsafe_warnings()
|
|||
{
|
||||
if ((unsafe_type_flags & (1 << unsafe_type)) != 0)
|
||||
{
|
||||
push_warning_printf(this, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
push_warning_printf(this, Sql_condition::WARN_LEVEL_NOTE,
|
||||
ER_BINLOG_UNSAFE_STATEMENT,
|
||||
ER(ER_BINLOG_UNSAFE_STATEMENT),
|
||||
ER(LEX::binlog_stmt_unsafe_errcode[unsafe_type]));
|
||||
|
|
|
|||
|
|
@ -72,7 +72,6 @@ class Sroutine_hash_entry;
|
|||
class User_level_lock;
|
||||
class user_var_entry;
|
||||
|
||||
enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE };
|
||||
enum enum_ha_read_modes { RFIRST, RNEXT, RPREV, RLAST, RKEY, RNEXT_SAME };
|
||||
enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_UPDATE };
|
||||
enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON,
|
||||
|
|
@ -235,6 +234,7 @@ public:
|
|||
enum drop_type {KEY, COLUMN, FOREIGN_KEY };
|
||||
const char *name;
|
||||
enum drop_type type;
|
||||
bool drop_if_exists;
|
||||
Alter_drop(enum drop_type par_type,const char *par_name)
|
||||
:name(par_name), type(par_type)
|
||||
{
|
||||
|
|
@ -303,7 +303,6 @@ public:
|
|||
{ return new (mem_root) Key(*this, mem_root); }
|
||||
};
|
||||
|
||||
class Table_ident;
|
||||
|
||||
class Foreign_key: public Key {
|
||||
public:
|
||||
|
|
@ -318,23 +317,25 @@ public:
|
|||
uint delete_opt, update_opt, match_opt;
|
||||
Foreign_key(const LEX_STRING &name_arg, List<Key_part_spec> &cols,
|
||||
const LEX_STRING &ref_db_arg, const LEX_STRING &ref_table_arg,
|
||||
List<Key_part_spec> &ref_cols,
|
||||
List<Key_part_spec> &ref_cols,
|
||||
uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg)
|
||||
:Key(FOREIGN_KEY, name_arg, &default_key_create_info, 0, cols, NULL),
|
||||
ref_db(ref_db_arg), ref_table(ref_table_arg), ref_columns(ref_cols),
|
||||
delete_opt(delete_opt_arg), update_opt(update_opt_arg),
|
||||
match_opt(match_opt_arg)
|
||||
{
|
||||
{
|
||||
// We don't check for duplicate FKs.
|
||||
key_create_info.check_for_duplicate_indexes= false;
|
||||
}
|
||||
Foreign_key(const Foreign_key &rhs, MEM_ROOT *mem_root);
|
||||
Foreign_key(const Foreign_key &rhs, MEM_ROOT *mem_root);
|
||||
/**
|
||||
Used to make a clone of this object for ALTER/CREATE TABLE
|
||||
@sa comment for Key_part_spec::clone
|
||||
*/
|
||||
virtual Key *clone(MEM_ROOT *mem_root) const
|
||||
{ return new (mem_root) Foreign_key(*this, mem_root); }
|
||||
/* Used to validate foreign key options */
|
||||
bool validate(List<Create_field> &table_fields);
|
||||
};
|
||||
|
||||
typedef struct st_mysql_lock
|
||||
|
|
@ -1348,9 +1349,9 @@ public:
|
|||
virtual bool handle_condition(THD *thd,
|
||||
uint sql_errno,
|
||||
const char* sqlstate,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
Sql_condition::enum_warning_level level,
|
||||
const char* msg,
|
||||
MYSQL_ERROR ** cond_hdl) = 0;
|
||||
Sql_condition ** cond_hdl) = 0;
|
||||
|
||||
private:
|
||||
Internal_error_handler *m_prev_internal_handler;
|
||||
|
|
@ -1369,9 +1370,9 @@ public:
|
|||
bool handle_condition(THD *thd,
|
||||
uint sql_errno,
|
||||
const char* sqlstate,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
Sql_condition::enum_warning_level level,
|
||||
const char* msg,
|
||||
MYSQL_ERROR ** cond_hdl)
|
||||
Sql_condition ** cond_hdl)
|
||||
{
|
||||
/* Ignore error */
|
||||
return TRUE;
|
||||
|
|
@ -1396,9 +1397,9 @@ public:
|
|||
bool handle_condition(THD *thd,
|
||||
uint sql_errno,
|
||||
const char* sqlstate,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
Sql_condition::enum_warning_level level,
|
||||
const char* msg,
|
||||
MYSQL_ERROR ** cond_hdl);
|
||||
Sql_condition ** cond_hdl);
|
||||
|
||||
private:
|
||||
};
|
||||
|
|
@ -2216,8 +2217,6 @@ public:
|
|||
|
||||
USER_CONN *user_connect;
|
||||
CHARSET_INFO *db_charset;
|
||||
Warning_info *warning_info;
|
||||
Diagnostics_area *stmt_da;
|
||||
#if defined(ENABLED_PROFILING)
|
||||
PROFILING profiling;
|
||||
#endif
|
||||
|
|
@ -2756,8 +2755,8 @@ public:
|
|||
inline void clear_error()
|
||||
{
|
||||
DBUG_ENTER("clear_error");
|
||||
if (stmt_da->is_error())
|
||||
stmt_da->reset_diagnostics_area();
|
||||
if (get_stmt_da()->is_error())
|
||||
get_stmt_da()->reset_diagnostics_area();
|
||||
is_slave_error= 0;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
|
@ -2784,7 +2783,7 @@ public:
|
|||
*/
|
||||
inline void fatal_error()
|
||||
{
|
||||
DBUG_ASSERT(stmt_da->is_error() || killed);
|
||||
DBUG_ASSERT(get_stmt_da()->is_error() || killed);
|
||||
is_fatal_error= 1;
|
||||
DBUG_PRINT("error",("Fatal error set"));
|
||||
}
|
||||
|
|
@ -2801,11 +2800,19 @@ public:
|
|||
|
||||
To raise this flag, use my_error().
|
||||
*/
|
||||
inline bool is_error() const { return stmt_da->is_error(); }
|
||||
inline bool is_error() const { return m_stmt_da->is_error(); }
|
||||
|
||||
/// Returns Diagnostics-area for the current statement.
|
||||
Diagnostics_area *get_stmt_da()
|
||||
{ return stmt_da; }
|
||||
{ return m_stmt_da; }
|
||||
|
||||
/// Returns Diagnostics-area for the current statement.
|
||||
const Diagnostics_area *get_stmt_da() const
|
||||
{ return m_stmt_da; }
|
||||
|
||||
/// Sets Diagnostics-area for the current statement.
|
||||
void set_stmt_da(Diagnostics_area *da)
|
||||
{ m_stmt_da= da; }
|
||||
|
||||
inline CHARSET_INFO *charset() { return variables.character_set_client; }
|
||||
void update_charset();
|
||||
|
|
@ -3096,6 +3103,7 @@ public:
|
|||
*/
|
||||
void push_internal_handler(Internal_error_handler *handler);
|
||||
|
||||
private:
|
||||
/**
|
||||
Handle a sql condition.
|
||||
@param sql_errno the condition error number
|
||||
|
|
@ -3105,12 +3113,13 @@ public:
|
|||
@param[out] cond_hdl the sql condition raised, if any
|
||||
@return true if the condition is handled
|
||||
*/
|
||||
virtual bool handle_condition(uint sql_errno,
|
||||
const char* sqlstate,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
const char* msg,
|
||||
MYSQL_ERROR ** cond_hdl);
|
||||
bool handle_condition(uint sql_errno,
|
||||
const char* sqlstate,
|
||||
Sql_condition::enum_warning_level level,
|
||||
const char* msg,
|
||||
Sql_condition ** cond_hdl);
|
||||
|
||||
public:
|
||||
/**
|
||||
Remove the error handler last pushed.
|
||||
*/
|
||||
|
|
@ -3160,10 +3169,10 @@ private:
|
|||
To raise a SQL condition, the code should use the public
|
||||
raise_error() or raise_warning() methods provided by class THD.
|
||||
*/
|
||||
friend class Signal_common;
|
||||
friend class Signal_statement;
|
||||
friend class Resignal_statement;
|
||||
friend void push_warning(THD*, MYSQL_ERROR::enum_warning_level, uint, const char*);
|
||||
friend class Sql_cmd_common_signal;
|
||||
friend class Sql_cmd_signal;
|
||||
friend class Sql_cmd_resignal;
|
||||
friend void push_warning(THD*, Sql_condition::enum_warning_level, uint, const char*);
|
||||
friend void my_message_sql(uint, const char *, myf);
|
||||
|
||||
/**
|
||||
|
|
@ -3174,10 +3183,10 @@ private:
|
|||
@param msg the condition message text
|
||||
@return The condition raised, or NULL
|
||||
*/
|
||||
MYSQL_ERROR*
|
||||
Sql_condition*
|
||||
raise_condition(uint sql_errno,
|
||||
const char* sqlstate,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
Sql_condition::enum_warning_level level,
|
||||
const char* msg);
|
||||
|
||||
public:
|
||||
|
|
@ -3307,8 +3316,8 @@ private:
|
|||
tree itself is reused between executions and thus is stored elsewhere.
|
||||
*/
|
||||
MEM_ROOT main_mem_root;
|
||||
Warning_info main_warning_info;
|
||||
Diagnostics_area main_da;
|
||||
Diagnostics_area *m_stmt_da;
|
||||
|
||||
/**
|
||||
It will be set TURE if CURRENT_USER() is called in account management
|
||||
|
|
@ -3341,24 +3350,24 @@ private:
|
|||
};
|
||||
|
||||
|
||||
/** A short cut for thd->stmt_da->set_ok_status(). */
|
||||
/** A short cut for thd->get_stmt_da()->set_ok_status(). */
|
||||
|
||||
inline void
|
||||
my_ok(THD *thd, ulonglong affected_rows= 0, ulonglong id= 0,
|
||||
const char *message= NULL)
|
||||
{
|
||||
thd->set_row_count_func(affected_rows);
|
||||
thd->stmt_da->set_ok_status(thd, affected_rows, id, message);
|
||||
thd->get_stmt_da()->set_ok_status(affected_rows, id, message);
|
||||
}
|
||||
|
||||
|
||||
/** A short cut for thd->stmt_da->set_eof_status(). */
|
||||
/** A short cut for thd->get_stmt_da()->set_eof_status(). */
|
||||
|
||||
inline void
|
||||
my_eof(THD *thd)
|
||||
{
|
||||
thd->set_row_count_func(-1);
|
||||
thd->stmt_da->set_eof_status(thd);
|
||||
thd->get_stmt_da()->set_eof_status(thd);
|
||||
}
|
||||
|
||||
#define tmp_disable_binlog(A) \
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ enum enum_sql_command {
|
|||
SQLCOM_SHOW_PROFILE, SQLCOM_SHOW_PROFILES,
|
||||
SQLCOM_SIGNAL, SQLCOM_RESIGNAL,
|
||||
SQLCOM_SHOW_RELAYLOG_EVENTS,
|
||||
SQLCOM_GET_DIAGNOSTICS,
|
||||
SQLCOM_SHOW_USER_STATS, SQLCOM_SHOW_TABLE_STATS, SQLCOM_SHOW_INDEX_STATS,
|
||||
SQLCOM_SHOW_CLIENT_STATS,
|
||||
SQLCOM_SLAVE_ALL_START, SQLCOM_SLAVE_ALL_STOP,
|
||||
|
|
|
|||
|
|
@ -1120,7 +1120,7 @@ void prepare_new_connection_state(THD* thd)
|
|||
{
|
||||
thd->killed= KILL_CONNECTION;
|
||||
thd->print_aborted_warning(0, "init_connect command failed");
|
||||
sql_print_warning("%s", thd->stmt_da->message());
|
||||
sql_print_warning("%s", thd->get_stmt_da()->message());
|
||||
|
||||
/*
|
||||
now let client to send its first command,
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#endif
|
||||
|
||||
#include "sql_list.h" /* Sql_alloc */
|
||||
#include "mysql_com.h" /* rand_struct */
|
||||
#include "my_rnd.h" /* rand_struct */
|
||||
|
||||
class SQL_CRYPT :public Sql_alloc
|
||||
{
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "log_event.h" // Query_log_event
|
||||
#include "sql_base.h" // lock_table_names, tdc_remove_table
|
||||
#include "sql_handler.h" // mysql_ha_rm_tables
|
||||
#include "sql_class.h"
|
||||
#include <mysys_err.h>
|
||||
#include "sp_head.h"
|
||||
#include "sp.h"
|
||||
|
|
@ -575,7 +576,7 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
|
|||
error= -1;
|
||||
goto exit;
|
||||
}
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
|
||||
ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), db);
|
||||
error= 0;
|
||||
goto not_silent;
|
||||
|
|
@ -784,7 +785,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
|
|||
}
|
||||
else
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
|
||||
ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS), db);
|
||||
error= false;
|
||||
goto update_binlog;
|
||||
|
|
@ -1537,7 +1538,7 @@ bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch)
|
|||
{
|
||||
/* Throw a warning and free new_db_file_name. */
|
||||
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
|
||||
ER_BAD_DB_ERROR, ER(ER_BAD_DB_ERROR),
|
||||
new_db_file_name.str);
|
||||
|
||||
|
|
|
|||
|
|
@ -666,9 +666,9 @@ exit:
|
|||
if (derived->view)
|
||||
{
|
||||
if (thd->is_error() &&
|
||||
(thd->stmt_da->sql_errno() == ER_BAD_FIELD_ERROR ||
|
||||
thd->stmt_da->sql_errno() == ER_FUNC_INEXISTENT_NAME_COLLISION ||
|
||||
thd->stmt_da->sql_errno() == ER_SP_DOES_NOT_EXIST))
|
||||
(thd->get_stmt_da()->sql_errno() == ER_BAD_FIELD_ERROR ||
|
||||
thd->get_stmt_da()->sql_errno() == ER_FUNC_INEXISTENT_NAME_COLLISION ||
|
||||
thd->get_stmt_da()->sql_errno() == ER_SP_DOES_NOT_EXIST))
|
||||
{
|
||||
thd->clear_error();
|
||||
my_error(ER_VIEW_INVALID, MYF(0), derived->db,
|
||||
|
|
|
|||
357
sql/sql_error.cc
357
sql/sql_error.cc
|
|
@ -47,12 +47,12 @@ This file contains the implementation of error and warnings related
|
|||
#include "sp_rcontext.h"
|
||||
|
||||
/*
|
||||
Design notes about MYSQL_ERROR::m_message_text.
|
||||
Design notes about Sql_condition::m_message_text.
|
||||
|
||||
The member MYSQL_ERROR::m_message_text contains the text associated with
|
||||
The member Sql_condition::m_message_text contains the text associated with
|
||||
an error, warning or note (which are all SQL 'conditions')
|
||||
|
||||
Producer of MYSQL_ERROR::m_message_text:
|
||||
Producer of Sql_condition::m_message_text:
|
||||
----------------------------------------
|
||||
|
||||
(#1) the server implementation itself, when invoking functions like
|
||||
|
|
@ -78,16 +78,16 @@ This file contains the implementation of error and warnings related
|
|||
- a RESIGNAL statement,
|
||||
the message text is provided by the user logic, and is expressed in UTF8.
|
||||
|
||||
Storage of MYSQL_ERROR::m_message_text:
|
||||
Storage of Sql_condition::m_message_text:
|
||||
---------------------------------------
|
||||
|
||||
(#4) The class MYSQL_ERROR is used to hold the message text member.
|
||||
(#4) The class Sql_condition is used to hold the message text member.
|
||||
This class represents a single SQL condition.
|
||||
|
||||
(#5) The class Warning_info represents a SQL condition area, and contains
|
||||
a collection of SQL conditions in the Warning_info::m_warn_list
|
||||
|
||||
Consumer of MYSQL_ERROR::m_message_text:
|
||||
Consumer of Sql_condition::m_message_text:
|
||||
----------------------------------------
|
||||
|
||||
(#6) The statements SHOW WARNINGS and SHOW ERRORS display the content of
|
||||
|
|
@ -97,9 +97,9 @@ This file contains the implementation of error and warnings related
|
|||
also read the content of:
|
||||
- the top level statement condition area (when executed in a query),
|
||||
- a sub statement (when executed in a stored program)
|
||||
and return the data stored in a MYSQL_ERROR.
|
||||
and return the data stored in a Sql_condition.
|
||||
|
||||
(#8) The RESIGNAL statement reads the MYSQL_ERROR caught by an exception
|
||||
(#8) The RESIGNAL statement reads the Sql_condition caught by an exception
|
||||
handler, to raise a new or modified condition (in #3).
|
||||
|
||||
The big picture
|
||||
|
|
@ -113,7 +113,7 @@ This file contains the implementation of error and warnings related
|
|||
----------------------------|---------------------------- |
|
||||
| |
|
||||
V |
|
||||
MYSQL_ERROR(#4) |
|
||||
Sql_condition(#4) |
|
||||
| |
|
||||
| |
|
||||
V |
|
||||
|
|
@ -151,10 +151,10 @@ This file contains the implementation of error and warnings related
|
|||
|
||||
As a result, the design choice for (#4) and (#5) is to store data in
|
||||
the 'error_message_charset_info' CHARSET, to minimize impact on the code base.
|
||||
This is implemented by using 'String MYSQL_ERROR::m_message_text'.
|
||||
This is implemented by using 'String Sql_condition::m_message_text'.
|
||||
|
||||
The UTF8 -> error_message_charset_info conversion is implemented in
|
||||
Signal_common::eval_signal_informations() (for path #B and #C).
|
||||
Sql_cmd_common_signal::eval_signal_informations() (for path #B and #C).
|
||||
|
||||
Future work
|
||||
-----------
|
||||
|
|
@ -164,14 +164,14 @@ This file contains the implementation of error and warnings related
|
|||
|
||||
- Change (#4 and #5) to store message text in UTF8 natively.
|
||||
In practice, this means changing the type of the message text to
|
||||
'<UTF8 String 128 class> MYSQL_ERROR::m_message_text', and is a direct
|
||||
'<UTF8 String 128 class> Sql_condition::m_message_text', and is a direct
|
||||
consequence of WL#751.
|
||||
|
||||
- Implement (#9) (GET DIAGNOSTICS).
|
||||
See WL#2111 (Stored Procedures: Implement GET DIAGNOSTICS)
|
||||
*/
|
||||
|
||||
MYSQL_ERROR::MYSQL_ERROR()
|
||||
Sql_condition::Sql_condition()
|
||||
: Sql_alloc(),
|
||||
m_class_origin((const char*) NULL, 0, & my_charset_utf8_bin),
|
||||
m_subclass_origin((const char*) NULL, 0, & my_charset_utf8_bin),
|
||||
|
|
@ -185,20 +185,20 @@ MYSQL_ERROR::MYSQL_ERROR()
|
|||
m_cursor_name((const char*) NULL, 0, & my_charset_utf8_bin),
|
||||
m_message_text(),
|
||||
m_sql_errno(0),
|
||||
m_level(MYSQL_ERROR::WARN_LEVEL_ERROR),
|
||||
m_level(Sql_condition::WARN_LEVEL_ERROR),
|
||||
m_mem_root(NULL)
|
||||
{
|
||||
memset(m_returned_sqlstate, 0, sizeof(m_returned_sqlstate));
|
||||
}
|
||||
|
||||
void MYSQL_ERROR::init(MEM_ROOT *mem_root)
|
||||
void Sql_condition::init(MEM_ROOT *mem_root)
|
||||
{
|
||||
DBUG_ASSERT(mem_root != NULL);
|
||||
DBUG_ASSERT(m_mem_root == NULL);
|
||||
m_mem_root= mem_root;
|
||||
}
|
||||
|
||||
void MYSQL_ERROR::clear()
|
||||
void Sql_condition::clear()
|
||||
{
|
||||
m_class_origin.length(0);
|
||||
m_subclass_origin.length(0);
|
||||
|
|
@ -212,10 +212,10 @@ void MYSQL_ERROR::clear()
|
|||
m_cursor_name.length(0);
|
||||
m_message_text.length(0);
|
||||
m_sql_errno= 0;
|
||||
m_level= MYSQL_ERROR::WARN_LEVEL_ERROR;
|
||||
m_level= Sql_condition::WARN_LEVEL_ERROR;
|
||||
}
|
||||
|
||||
MYSQL_ERROR::MYSQL_ERROR(MEM_ROOT *mem_root)
|
||||
Sql_condition::Sql_condition(MEM_ROOT *mem_root)
|
||||
: Sql_alloc(),
|
||||
m_class_origin((const char*) NULL, 0, & my_charset_utf8_bin),
|
||||
m_subclass_origin((const char*) NULL, 0, & my_charset_utf8_bin),
|
||||
|
|
@ -229,7 +229,7 @@ MYSQL_ERROR::MYSQL_ERROR(MEM_ROOT *mem_root)
|
|||
m_cursor_name((const char*) NULL, 0, & my_charset_utf8_bin),
|
||||
m_message_text(),
|
||||
m_sql_errno(0),
|
||||
m_level(MYSQL_ERROR::WARN_LEVEL_ERROR),
|
||||
m_level(Sql_condition::WARN_LEVEL_ERROR),
|
||||
m_mem_root(mem_root)
|
||||
{
|
||||
DBUG_ASSERT(mem_root != NULL);
|
||||
|
|
@ -254,7 +254,7 @@ static void copy_string(MEM_ROOT *mem_root, String* dst, const String* src)
|
|||
}
|
||||
|
||||
void
|
||||
MYSQL_ERROR::copy_opt_attributes(const MYSQL_ERROR *cond)
|
||||
Sql_condition::copy_opt_attributes(const Sql_condition *cond)
|
||||
{
|
||||
DBUG_ASSERT(this != cond);
|
||||
copy_string(m_mem_root, & m_class_origin, & cond->m_class_origin);
|
||||
|
|
@ -270,8 +270,8 @@ MYSQL_ERROR::copy_opt_attributes(const MYSQL_ERROR *cond)
|
|||
}
|
||||
|
||||
void
|
||||
MYSQL_ERROR::set(uint sql_errno, const char* sqlstate,
|
||||
MYSQL_ERROR::enum_warning_level level, const char* msg)
|
||||
Sql_condition::set(uint sql_errno, const char* sqlstate,
|
||||
Sql_condition::enum_warning_level level, const char* msg)
|
||||
{
|
||||
DBUG_ASSERT(sql_errno != 0);
|
||||
DBUG_ASSERT(sqlstate != NULL);
|
||||
|
|
@ -286,11 +286,11 @@ MYSQL_ERROR::set(uint sql_errno, const char* sqlstate,
|
|||
}
|
||||
|
||||
void
|
||||
MYSQL_ERROR::set_builtin_message_text(const char* str)
|
||||
Sql_condition::set_builtin_message_text(const char* str)
|
||||
{
|
||||
/*
|
||||
See the comments
|
||||
"Design notes about MYSQL_ERROR::m_message_text."
|
||||
"Design notes about Sql_condition::m_message_text."
|
||||
*/
|
||||
const char* copy;
|
||||
|
||||
|
|
@ -300,24 +300,41 @@ MYSQL_ERROR::set_builtin_message_text(const char* str)
|
|||
}
|
||||
|
||||
const char*
|
||||
MYSQL_ERROR::get_message_text() const
|
||||
Sql_condition::get_message_text() const
|
||||
{
|
||||
return m_message_text.ptr();
|
||||
}
|
||||
|
||||
int
|
||||
MYSQL_ERROR::get_message_octet_length() const
|
||||
Sql_condition::get_message_octet_length() const
|
||||
{
|
||||
return m_message_text.length();
|
||||
}
|
||||
|
||||
void
|
||||
MYSQL_ERROR::set_sqlstate(const char* sqlstate)
|
||||
Sql_condition::set_sqlstate(const char* sqlstate)
|
||||
{
|
||||
memcpy(m_returned_sqlstate, sqlstate, SQLSTATE_LENGTH);
|
||||
m_returned_sqlstate[SQLSTATE_LENGTH]= '\0';
|
||||
}
|
||||
|
||||
Diagnostics_area::Diagnostics_area(bool initialize)
|
||||
: m_main_wi(0, false, initialize)
|
||||
{
|
||||
push_warning_info(&m_main_wi);
|
||||
|
||||
reset_diagnostics_area();
|
||||
}
|
||||
|
||||
Diagnostics_area::Diagnostics_area(ulonglong warning_info_id,
|
||||
bool allow_unlimited_warnings)
|
||||
: m_main_wi(warning_info_id, allow_unlimited_warnings, true)
|
||||
{
|
||||
push_warning_info(&m_main_wi);
|
||||
|
||||
reset_diagnostics_area();
|
||||
}
|
||||
|
||||
/**
|
||||
Clear this diagnostics area.
|
||||
|
||||
|
|
@ -337,7 +354,8 @@ Diagnostics_area::reset_diagnostics_area()
|
|||
m_last_insert_id= 0;
|
||||
m_statement_warn_count= 0;
|
||||
#endif
|
||||
is_sent= FALSE;
|
||||
get_warning_info()->clear_error_condition();
|
||||
set_is_sent(false);
|
||||
/** Tiny reset in debug mode to see garbage right away */
|
||||
m_status= DA_EMPTY;
|
||||
DBUG_VOID_RETURN;
|
||||
|
|
@ -350,9 +368,9 @@ Diagnostics_area::reset_diagnostics_area()
|
|||
*/
|
||||
|
||||
void
|
||||
Diagnostics_area::set_ok_status(THD *thd, ulonglong affected_rows_arg,
|
||||
ulonglong last_insert_id_arg,
|
||||
const char *message_arg)
|
||||
Diagnostics_area::set_ok_status(ulonglong affected_rows,
|
||||
ulonglong last_insert_id,
|
||||
const char *message)
|
||||
{
|
||||
DBUG_ENTER("set_ok_status");
|
||||
DBUG_ASSERT(! is_set());
|
||||
|
|
@ -363,11 +381,11 @@ Diagnostics_area::set_ok_status(THD *thd, ulonglong affected_rows_arg,
|
|||
if (is_error() || is_disabled())
|
||||
return;
|
||||
|
||||
m_statement_warn_count= thd->warning_info->statement_warn_count();
|
||||
m_affected_rows= affected_rows_arg;
|
||||
m_last_insert_id= last_insert_id_arg;
|
||||
if (message_arg)
|
||||
strmake(m_message, message_arg, sizeof(m_message) - 1);
|
||||
m_statement_warn_count= current_statement_warn_count();
|
||||
m_affected_rows= affected_rows;
|
||||
m_last_insert_id= last_insert_id;
|
||||
if (message)
|
||||
strmake(m_message, message, sizeof(m_message) - 1);
|
||||
else
|
||||
m_message[0]= '\0';
|
||||
m_status= DA_OK;
|
||||
|
|
@ -398,20 +416,48 @@ Diagnostics_area::set_eof_status(THD *thd)
|
|||
anyway.
|
||||
*/
|
||||
m_statement_warn_count= (thd->spcont ?
|
||||
0 : thd->warning_info->statement_warn_count());
|
||||
0 :
|
||||
current_statement_warn_count());
|
||||
|
||||
m_status= DA_EOF;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/**
|
||||
Set ERROR status.
|
||||
Set ERROR status in the Diagnostics Area. This function should be used to
|
||||
report fatal errors (such as out-of-memory errors) when no further
|
||||
processing is possible.
|
||||
|
||||
@param sql_errno SQL-condition error number
|
||||
*/
|
||||
|
||||
void
|
||||
Diagnostics_area::set_error_status(THD *thd, uint sql_errno_arg,
|
||||
const char *message_arg,
|
||||
const char *sqlstate)
|
||||
Diagnostics_area::set_error_status(uint sql_errno)
|
||||
{
|
||||
set_error_status(sql_errno,
|
||||
ER(sql_errno),
|
||||
mysql_errno_to_sqlstate(sql_errno),
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Set ERROR status in the Diagnostics Area.
|
||||
|
||||
@note error_condition may be NULL. It happens if a) OOM error is being
|
||||
reported; or b) when Warning_info is full.
|
||||
|
||||
@param sql_errno SQL-condition error number
|
||||
@param message SQL-condition message
|
||||
@param sqlstate SQL-condition state
|
||||
@param error_condition SQL-condition object representing the error state
|
||||
*/
|
||||
|
||||
void
|
||||
Diagnostics_area::set_error_status(uint sql_errno,
|
||||
const char *message,
|
||||
const char *sqlstate,
|
||||
const Sql_condition *error_condition)
|
||||
{
|
||||
DBUG_ENTER("set_error_status");
|
||||
/*
|
||||
|
|
@ -419,7 +465,14 @@ Diagnostics_area::set_error_status(THD *thd, uint sql_errno_arg,
|
|||
The only exception is when we flush the message to the client,
|
||||
an error can happen during the flush.
|
||||
*/
|
||||
DBUG_ASSERT(! is_set() || can_overwrite_status);
|
||||
DBUG_ASSERT(! is_set() || m_can_overwrite_status);
|
||||
|
||||
// message must be set properly by the caller.
|
||||
DBUG_ASSERT(message);
|
||||
|
||||
// sqlstate must be set properly by the caller.
|
||||
DBUG_ASSERT(sqlstate);
|
||||
|
||||
#ifdef DBUG_OFF
|
||||
/*
|
||||
In production, refuse to overwrite a custom response with an
|
||||
|
|
@ -429,19 +482,17 @@ Diagnostics_area::set_error_status(THD *thd, uint sql_errno_arg,
|
|||
return;
|
||||
#endif
|
||||
|
||||
if (sqlstate == NULL)
|
||||
sqlstate= mysql_errno_to_sqlstate(sql_errno_arg);
|
||||
|
||||
m_sql_errno= sql_errno_arg;
|
||||
m_sql_errno= sql_errno;
|
||||
memcpy(m_sqlstate, sqlstate, SQLSTATE_LENGTH);
|
||||
m_sqlstate[SQLSTATE_LENGTH]= '\0';
|
||||
strmake(m_message, message_arg, sizeof(m_message)-1);
|
||||
strmake(m_message, message, sizeof(m_message)-1);
|
||||
|
||||
get_warning_info()->set_error_condition(error_condition);
|
||||
|
||||
m_status= DA_ERROR;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Mark the diagnostics area as 'DISABLED'.
|
||||
|
||||
|
|
@ -459,15 +510,16 @@ Diagnostics_area::disable_status()
|
|||
|
||||
Warning_info::Warning_info(ulonglong warn_id_arg,
|
||||
bool allow_unlimited_warnings, bool initialize)
|
||||
:m_statement_warn_count(0),
|
||||
:m_current_statement_warn_count(0),
|
||||
m_current_row_for_warning(1),
|
||||
m_warn_id(warn_id_arg),
|
||||
m_error_condition(NULL),
|
||||
m_allow_unlimited_warnings(allow_unlimited_warnings),
|
||||
initialized(0),
|
||||
m_read_only(FALSE)
|
||||
{
|
||||
m_warn_list.empty();
|
||||
bzero((char*) m_warn_count, sizeof(m_warn_count));
|
||||
memset(m_warn_count, 0, sizeof(m_warn_count));
|
||||
if (initialize)
|
||||
init();
|
||||
}
|
||||
|
|
@ -492,92 +544,164 @@ Warning_info::~Warning_info()
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
Reset the warning information of this connection.
|
||||
*/
|
||||
|
||||
void Warning_info::clear_warning_info(ulonglong warn_id_arg)
|
||||
bool Warning_info::has_sql_condition(const char *message_str,
|
||||
ulong message_length) const
|
||||
{
|
||||
m_warn_id= warn_id_arg;
|
||||
free_memory();
|
||||
bzero((char*) m_warn_count, sizeof(m_warn_count));
|
||||
m_warn_list.empty();
|
||||
m_statement_warn_count= 0;
|
||||
m_current_row_for_warning= 1; /* Start counting from the first row */
|
||||
Diagnostics_area::Sql_condition_iterator it(m_warn_list);
|
||||
const Sql_condition *err;
|
||||
|
||||
while ((err= it++))
|
||||
{
|
||||
if (strncmp(message_str, err->get_message_text(), message_length) == 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
Append warnings only if the original contents of the routine
|
||||
warning info was replaced.
|
||||
*/
|
||||
void Warning_info::merge_with_routine_info(THD *thd, Warning_info *source)
|
||||
|
||||
void Warning_info::clear(ulonglong new_id)
|
||||
{
|
||||
/*
|
||||
If a routine body is empty or if a routine did not
|
||||
generate any warnings (thus m_warn_id didn't change),
|
||||
do not duplicate our own contents by appending the
|
||||
contents of the called routine. We know that the called
|
||||
routine did not change its warning info.
|
||||
id(new_id);
|
||||
m_warn_list.empty();
|
||||
m_marked_sql_conditions.empty();
|
||||
free_memory();
|
||||
memset(m_warn_count, 0, sizeof(m_warn_count));
|
||||
m_current_statement_warn_count= 0;
|
||||
m_current_row_for_warning= 1; /* Start counting from the first row */
|
||||
clear_error_condition();
|
||||
}
|
||||
|
||||
On the other hand, if the routine body is not empty and
|
||||
some statement in the routine generates a warning or
|
||||
uses tables, m_warn_id is guaranteed to have changed.
|
||||
In this case we know that the routine warning info
|
||||
contains only new warnings, and thus we perform a copy.
|
||||
*/
|
||||
if (m_warn_id != source->m_warn_id)
|
||||
void Warning_info::append_warning_info(THD *thd, const Warning_info *source)
|
||||
{
|
||||
const Sql_condition *err;
|
||||
Diagnostics_area::Sql_condition_iterator it(source->m_warn_list);
|
||||
const Sql_condition *src_error_condition = source->get_error_condition();
|
||||
|
||||
while ((err= it++))
|
||||
{
|
||||
/*
|
||||
If the invocation of the routine was a standalone statement,
|
||||
rather than a sub-statement, in other words, if it's a CALL
|
||||
of a procedure, rather than invocation of a function or a
|
||||
trigger, we need to clear the current contents of the caller's
|
||||
warning info.
|
||||
// Do not use ::push_warning() to avoid invocation of THD-internal-handlers.
|
||||
Sql_condition *new_error= Warning_info::push_warning(thd, err);
|
||||
|
||||
This is per MySQL rules: if a statement generates a warning,
|
||||
warnings from the previous statement are flushed. Normally
|
||||
it's done in push_warning(). However, here we don't use
|
||||
push_warning() to avoid invocation of condition handlers or
|
||||
escalation of warnings to errors.
|
||||
*/
|
||||
opt_clear_warning_info(thd->query_id);
|
||||
append_warning_info(thd, source);
|
||||
if (src_error_condition && src_error_condition == err)
|
||||
set_error_condition(new_error);
|
||||
|
||||
if (source->is_marked_for_removal(err))
|
||||
mark_condition_for_removal(new_error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Add a warning to the list of warnings. Increment the respective
|
||||
counters.
|
||||
Copy Sql_conditions that are not WARN_LEVEL_ERROR from the source
|
||||
Warning_info to the current Warning_info.
|
||||
|
||||
@param thd Thread context.
|
||||
@param sp_wi Stored-program Warning_info
|
||||
@param thd Thread context.
|
||||
@param src_wi Warning_info to copy from.
|
||||
*/
|
||||
MYSQL_ERROR *Warning_info::push_warning(THD *thd,
|
||||
uint sql_errno, const char* sqlstate,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
const char *msg)
|
||||
void Diagnostics_area::copy_non_errors_from_wi(THD *thd,
|
||||
const Warning_info *src_wi)
|
||||
{
|
||||
MYSQL_ERROR *cond= NULL;
|
||||
Sql_condition_iterator it(src_wi->m_warn_list);
|
||||
const Sql_condition *cond;
|
||||
Warning_info *wi= get_warning_info();
|
||||
|
||||
while ((cond= it++))
|
||||
{
|
||||
if (cond->get_level() == Sql_condition::WARN_LEVEL_ERROR)
|
||||
continue;
|
||||
|
||||
Sql_condition *new_condition= wi->push_warning(thd, cond);
|
||||
|
||||
if (src_wi->is_marked_for_removal(cond))
|
||||
wi->mark_condition_for_removal(new_condition);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Warning_info::mark_sql_conditions_for_removal()
|
||||
{
|
||||
Sql_condition_list::Iterator it(m_warn_list);
|
||||
Sql_condition *cond;
|
||||
|
||||
while ((cond= it++))
|
||||
mark_condition_for_removal(cond);
|
||||
}
|
||||
|
||||
|
||||
void Warning_info::remove_marked_sql_conditions()
|
||||
{
|
||||
List_iterator_fast<Sql_condition> it(m_marked_sql_conditions);
|
||||
Sql_condition *cond;
|
||||
|
||||
while ((cond= it++))
|
||||
{
|
||||
m_warn_list.remove(cond);
|
||||
m_warn_count[cond->get_level()]--;
|
||||
m_current_statement_warn_count--;
|
||||
if (cond == m_error_condition)
|
||||
m_error_condition= NULL;
|
||||
}
|
||||
|
||||
m_marked_sql_conditions.empty();
|
||||
}
|
||||
|
||||
|
||||
bool Warning_info::is_marked_for_removal(const Sql_condition *cond) const
|
||||
{
|
||||
List_iterator_fast<Sql_condition> it(
|
||||
const_cast<List<Sql_condition>&> (m_marked_sql_conditions));
|
||||
Sql_condition *c;
|
||||
|
||||
while ((c= it++))
|
||||
{
|
||||
if (c == cond)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Warning_info::reserve_space(THD *thd, uint count)
|
||||
{
|
||||
while (m_warn_list.elements() &&
|
||||
(m_warn_list.elements() + count) > thd->variables.max_error_count)
|
||||
m_warn_list.remove(m_warn_list.front());
|
||||
}
|
||||
|
||||
Sql_condition *Warning_info::push_warning(THD *thd,
|
||||
uint sql_errno, const char* sqlstate,
|
||||
Sql_condition::enum_warning_level level,
|
||||
const char *msg)
|
||||
{
|
||||
Sql_condition *cond= NULL;
|
||||
|
||||
if (! m_read_only)
|
||||
{
|
||||
if (m_allow_unlimited_warnings ||
|
||||
m_warn_list.elements < thd->variables.max_error_count)
|
||||
m_warn_list.elements() < thd->variables.max_error_count)
|
||||
{
|
||||
cond= new (& m_warn_root) MYSQL_ERROR(& m_warn_root);
|
||||
cond= new (& m_warn_root) Sql_condition(& m_warn_root);
|
||||
if (cond)
|
||||
{
|
||||
cond->set(sql_errno, sqlstate, level, msg);
|
||||
m_warn_list.push_back(cond, &m_warn_root);
|
||||
m_warn_list.push_back(cond);
|
||||
}
|
||||
}
|
||||
m_warn_count[(uint) level]++;
|
||||
}
|
||||
|
||||
m_statement_warn_count++;
|
||||
m_current_statement_warn_count++;
|
||||
return cond;
|
||||
}
|
||||
|
||||
MYSQL_ERROR *Warning_info::push_warning(THD *thd, const MYSQL_ERROR *sql_condition)
|
||||
|
||||
Sql_condition *Warning_info::push_warning(THD *thd, const Sql_condition *sql_condition)
|
||||
{
|
||||
MYSQL_ERROR *new_condition= push_warning(thd,
|
||||
Sql_condition *new_condition= push_warning(thd,
|
||||
sql_condition->get_sql_errno(),
|
||||
sql_condition->get_sqlstate(),
|
||||
sql_condition->get_level(),
|
||||
|
|
@ -600,7 +724,7 @@ MYSQL_ERROR *Warning_info::push_warning(THD *thd, const MYSQL_ERROR *sql_conditi
|
|||
msg Clear error message
|
||||
*/
|
||||
|
||||
void push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
|
||||
void push_warning(THD *thd, Sql_condition::enum_warning_level level,
|
||||
uint code, const char *msg)
|
||||
{
|
||||
DBUG_ENTER("push_warning");
|
||||
|
|
@ -611,15 +735,15 @@ void push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
|
|||
WARN_LEVEL_ERROR *is* a bug. Either use my_printf_error(),
|
||||
my_error(), or WARN_LEVEL_WARN.
|
||||
*/
|
||||
DBUG_ASSERT(level != MYSQL_ERROR::WARN_LEVEL_ERROR);
|
||||
DBUG_ASSERT(level != Sql_condition::WARN_LEVEL_ERROR);
|
||||
|
||||
if (level == MYSQL_ERROR::WARN_LEVEL_ERROR)
|
||||
level= MYSQL_ERROR::WARN_LEVEL_WARN;
|
||||
if (level == Sql_condition::WARN_LEVEL_ERROR)
|
||||
level= Sql_condition::WARN_LEVEL_WARN;
|
||||
|
||||
(void) thd->raise_condition(code, NULL, level, msg);
|
||||
|
||||
/* Make sure we also count warnings pushed after calling set_ok_status(). */
|
||||
thd->stmt_da->increment_warning();
|
||||
thd->get_stmt_da()->increment_warning();
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
|
@ -636,7 +760,7 @@ void push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
|
|||
msg Clear error message
|
||||
*/
|
||||
|
||||
void push_warning_printf(THD *thd, MYSQL_ERROR::enum_warning_level level,
|
||||
void push_warning_printf(THD *thd, Sql_condition::enum_warning_level level,
|
||||
uint code, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
|
@ -685,7 +809,7 @@ bool mysqld_show_warnings(THD *thd, ulong levels_to_show)
|
|||
List<Item> field_list;
|
||||
DBUG_ENTER("mysqld_show_warnings");
|
||||
|
||||
DBUG_ASSERT(thd->warning_info->is_read_only());
|
||||
DBUG_ASSERT(thd->get_stmt_da()->is_warning_info_read_only());
|
||||
|
||||
field_list.push_back(new Item_empty_string("Level", 7));
|
||||
field_list.push_back(new Item_return_int("Code",4, MYSQL_TYPE_LONG));
|
||||
|
|
@ -695,7 +819,7 @@ bool mysqld_show_warnings(THD *thd, ulong levels_to_show)
|
|||
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
MYSQL_ERROR *err;
|
||||
const Sql_condition *err;
|
||||
SELECT_LEX *sel= &thd->lex->select_lex;
|
||||
SELECT_LEX_UNIT *unit= &thd->lex->unit;
|
||||
ulonglong idx= 0;
|
||||
|
|
@ -703,7 +827,8 @@ bool mysqld_show_warnings(THD *thd, ulong levels_to_show)
|
|||
|
||||
unit->set_limit(sel);
|
||||
|
||||
List_iterator_fast<MYSQL_ERROR> it(thd->warning_info->warn_list());
|
||||
Diagnostics_area::Sql_condition_iterator it=
|
||||
thd->get_stmt_da()->sql_conditions();
|
||||
while ((err= it++))
|
||||
{
|
||||
/* Skip levels that the user is not interested in */
|
||||
|
|
@ -726,7 +851,7 @@ bool mysqld_show_warnings(THD *thd, ulong levels_to_show)
|
|||
}
|
||||
my_eof(thd);
|
||||
|
||||
thd->warning_info->set_read_only(FALSE);
|
||||
thd->get_stmt_da()->set_warning_info_read_only(FALSE);
|
||||
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
|
|
|||
776
sql/sql_error.h
776
sql/sql_error.h
|
|
@ -19,126 +19,13 @@
|
|||
#include "sql_list.h" /* Sql_alloc, MEM_ROOT */
|
||||
#include "m_string.h" /* LEX_STRING */
|
||||
#include "sql_string.h" /* String */
|
||||
#include "sql_plist.h" /* I_P_List */
|
||||
#include "mysql_com.h" /* MYSQL_ERRMSG_SIZE */
|
||||
#include "my_time.h" /* MYSQL_TIME */
|
||||
#include "decimal.h"
|
||||
|
||||
class THD;
|
||||
|
||||
/**
|
||||
Stores status of the currently executed statement.
|
||||
Cleared at the beginning of the statement, and then
|
||||
can hold either OK, ERROR, or EOF status.
|
||||
Can not be assigned twice per statement.
|
||||
*/
|
||||
|
||||
class Diagnostics_area
|
||||
{
|
||||
public:
|
||||
enum enum_diagnostics_status
|
||||
{
|
||||
/** The area is cleared at start of a statement. */
|
||||
DA_EMPTY= 0,
|
||||
/** Set whenever one calls my_ok(). */
|
||||
DA_OK,
|
||||
/** Set whenever one calls my_eof(). */
|
||||
DA_EOF,
|
||||
/** Set whenever one calls my_error() or my_message(). */
|
||||
DA_ERROR,
|
||||
/** Set in case of a custom response, such as one from COM_STMT_PREPARE. */
|
||||
DA_DISABLED
|
||||
};
|
||||
/** True if status information is sent to the client. */
|
||||
bool is_sent;
|
||||
/** Set to make set_error_status after set_{ok,eof}_status possible. */
|
||||
bool can_overwrite_status;
|
||||
|
||||
void set_ok_status(THD *thd, ulonglong affected_rows_arg,
|
||||
ulonglong last_insert_id_arg,
|
||||
const char *message);
|
||||
void set_eof_status(THD *thd);
|
||||
void set_error_status(THD *thd, uint sql_errno_arg, const char *message_arg,
|
||||
const char *sqlstate);
|
||||
|
||||
void disable_status();
|
||||
|
||||
void reset_diagnostics_area();
|
||||
|
||||
bool is_set() const { return m_status != DA_EMPTY; }
|
||||
bool is_error() const { return m_status == DA_ERROR; }
|
||||
bool is_eof() const { return m_status == DA_EOF; }
|
||||
bool is_ok() const { return m_status == DA_OK; }
|
||||
bool is_disabled() const { return m_status == DA_DISABLED; }
|
||||
enum_diagnostics_status status() const { return m_status; }
|
||||
|
||||
const char *message() const
|
||||
{ DBUG_ASSERT(m_status == DA_ERROR || m_status == DA_OK); return m_message; }
|
||||
|
||||
uint sql_errno() const
|
||||
{ DBUG_ASSERT(m_status == DA_ERROR); return m_sql_errno; }
|
||||
|
||||
const char* get_sqlstate() const
|
||||
{ DBUG_ASSERT(m_status == DA_ERROR); return m_sqlstate; }
|
||||
|
||||
ulonglong affected_rows() const
|
||||
{ DBUG_ASSERT(m_status == DA_OK); return m_affected_rows; }
|
||||
|
||||
ulonglong last_insert_id() const
|
||||
{ DBUG_ASSERT(m_status == DA_OK); return m_last_insert_id; }
|
||||
|
||||
uint statement_warn_count() const
|
||||
{
|
||||
DBUG_ASSERT(m_status == DA_OK || m_status == DA_EOF);
|
||||
return m_statement_warn_count;
|
||||
}
|
||||
|
||||
/* Used to count any warnings pushed after calling set_ok_status(). */
|
||||
void increment_warning()
|
||||
{
|
||||
if (m_status != DA_EMPTY)
|
||||
m_statement_warn_count++;
|
||||
}
|
||||
|
||||
Diagnostics_area() { reset_diagnostics_area(); }
|
||||
|
||||
private:
|
||||
/** Message buffer. Can be used by OK or ERROR status. */
|
||||
char m_message[MYSQL_ERRMSG_SIZE];
|
||||
/**
|
||||
SQL error number. One of ER_ codes from share/errmsg.txt.
|
||||
Set by set_error_status.
|
||||
*/
|
||||
uint m_sql_errno;
|
||||
|
||||
char m_sqlstate[SQLSTATE_LENGTH+1];
|
||||
|
||||
/**
|
||||
The number of rows affected by the last statement. This is
|
||||
semantically close to thd->row_count_func, but has a different
|
||||
life cycle. thd->row_count_func stores the value returned by
|
||||
function ROW_COUNT() and is cleared only by statements that
|
||||
update its value, such as INSERT, UPDATE, DELETE and few others.
|
||||
This member is cleared at the beginning of the next statement.
|
||||
|
||||
We could possibly merge the two, but life cycle of thd->row_count_func
|
||||
can not be changed.
|
||||
*/
|
||||
ulonglong m_affected_rows;
|
||||
/**
|
||||
Similarly to the previous member, this is a replacement of
|
||||
thd->first_successful_insert_id_in_prev_stmt, which is used
|
||||
to implement LAST_INSERT_ID().
|
||||
*/
|
||||
ulonglong m_last_insert_id;
|
||||
/**
|
||||
Number of warnings of this last statement. May differ from
|
||||
the number of warnings returned by SHOW WARNINGS e.g. in case
|
||||
the statement doesn't clear the warnings, and doesn't generate
|
||||
them.
|
||||
*/
|
||||
uint m_statement_warn_count;
|
||||
enum_diagnostics_status m_status;
|
||||
};
|
||||
class my_decimal;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -146,10 +33,8 @@ private:
|
|||
Representation of a SQL condition.
|
||||
A SQL condition can be a completion condition (note, warning),
|
||||
or an exception condition (error, not found).
|
||||
@note This class is named MYSQL_ERROR instead of SQL_condition for
|
||||
historical reasons, to facilitate merging code with previous releases.
|
||||
*/
|
||||
class MYSQL_ERROR : public Sql_alloc
|
||||
class Sql_condition : public Sql_alloc
|
||||
{
|
||||
public:
|
||||
/*
|
||||
|
|
@ -160,6 +45,7 @@ public:
|
|||
*/
|
||||
enum enum_warning_level
|
||||
{ WARN_LEVEL_NOTE, WARN_LEVEL_WARN, WARN_LEVEL_ERROR, WARN_LEVEL_END};
|
||||
|
||||
/**
|
||||
Get the MESSAGE_TEXT of this condition.
|
||||
@return the message text.
|
||||
|
|
@ -190,19 +76,15 @@ public:
|
|||
Get the error level of this condition.
|
||||
@return the error level condition item.
|
||||
*/
|
||||
MYSQL_ERROR::enum_warning_level get_level() const
|
||||
Sql_condition::enum_warning_level get_level() const
|
||||
{ return m_level; }
|
||||
|
||||
/** Destructor. */
|
||||
~MYSQL_ERROR()
|
||||
{}
|
||||
|
||||
private:
|
||||
/*
|
||||
The interface of MYSQL_ERROR is mostly private, by design,
|
||||
The interface of Sql_condition is mostly private, by design,
|
||||
so that only the following code:
|
||||
- various raise_error() or raise_warning() methods in class THD,
|
||||
- the implementation of SIGNAL / RESIGNAL
|
||||
- the implementation of SIGNAL / RESIGNAL / GET DIAGNOSTICS
|
||||
- catch / re-throw of SQL conditions in stored procedures (sp_rcontext)
|
||||
is allowed to create / modify a SQL condition.
|
||||
Enforcing this policy prevents confusion, since the only public
|
||||
|
|
@ -212,20 +94,21 @@ private:
|
|||
*/
|
||||
friend class THD;
|
||||
friend class Warning_info;
|
||||
friend class Signal_common;
|
||||
friend class Signal_statement;
|
||||
friend class Resignal_statement;
|
||||
friend class Sql_cmd_common_signal;
|
||||
friend class Sql_cmd_signal;
|
||||
friend class Sql_cmd_resignal;
|
||||
friend class sp_rcontext;
|
||||
friend class Condition_information_item;
|
||||
|
||||
/**
|
||||
Default constructor.
|
||||
This constructor is usefull when allocating arrays.
|
||||
Note that the init() method should be called to complete the MYSQL_ERROR.
|
||||
Note that the init() method should be called to complete the Sql_condition.
|
||||
*/
|
||||
MYSQL_ERROR();
|
||||
Sql_condition();
|
||||
|
||||
/**
|
||||
Complete the MYSQL_ERROR initialisation.
|
||||
Complete the Sql_condition initialisation.
|
||||
@param mem_root The memory root to use for the condition items
|
||||
of this condition
|
||||
*/
|
||||
|
|
@ -236,15 +119,17 @@ private:
|
|||
@param mem_root The memory root to use for the condition items
|
||||
of this condition
|
||||
*/
|
||||
MYSQL_ERROR(MEM_ROOT *mem_root);
|
||||
|
||||
Sql_condition(MEM_ROOT *mem_root);
|
||||
|
||||
/** Destructor. */
|
||||
~Sql_condition()
|
||||
{}
|
||||
|
||||
/**
|
||||
Copy optional condition items attributes.
|
||||
@param cond the condition to copy.
|
||||
*/
|
||||
void copy_opt_attributes(const MYSQL_ERROR *cond);
|
||||
void copy_opt_attributes(const Sql_condition *cond);
|
||||
|
||||
/**
|
||||
Set this condition area with a fixed message text.
|
||||
|
|
@ -255,7 +140,7 @@ private:
|
|||
@param MyFlags additional flags.
|
||||
*/
|
||||
void set(uint sql_errno, const char* sqlstate,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
Sql_condition::enum_warning_level level,
|
||||
const char* msg);
|
||||
|
||||
/**
|
||||
|
|
@ -268,6 +153,12 @@ private:
|
|||
/** Set the SQLSTATE of this condition. */
|
||||
void set_sqlstate(const char* sqlstate);
|
||||
|
||||
/** Set the CLASS_ORIGIN of this condition. */
|
||||
void set_class_origin();
|
||||
|
||||
/** Set the SUBCLASS_ORIGIN of this condition. */
|
||||
void set_subclass_origin();
|
||||
|
||||
/**
|
||||
Clear this SQL condition.
|
||||
*/
|
||||
|
|
@ -317,44 +208,48 @@ private:
|
|||
char m_returned_sqlstate[SQLSTATE_LENGTH+1];
|
||||
|
||||
/** Severity (error, warning, note) of this condition. */
|
||||
MYSQL_ERROR::enum_warning_level m_level;
|
||||
Sql_condition::enum_warning_level m_level;
|
||||
|
||||
/** Pointers for participating in the list of conditions. */
|
||||
Sql_condition *next_in_wi;
|
||||
Sql_condition **prev_in_wi;
|
||||
|
||||
/** Memory root to use to hold condition item values. */
|
||||
MEM_ROOT *m_mem_root;
|
||||
};
|
||||
|
||||
class Sql_condition : public MYSQL_ERROR
|
||||
{
|
||||
/*
|
||||
Wrapper class to allow one to use Sql_condition in handlers instead of
|
||||
MYSQL_ERROR
|
||||
*/
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
Information about warnings of the current connection.
|
||||
*/
|
||||
|
||||
class Warning_info
|
||||
{
|
||||
/** The type of the counted and doubly linked list of conditions. */
|
||||
typedef I_P_List<Sql_condition,
|
||||
I_P_List_adapter<Sql_condition,
|
||||
&Sql_condition::next_in_wi,
|
||||
&Sql_condition::prev_in_wi>,
|
||||
I_P_List_counter,
|
||||
I_P_List_fast_push_back<Sql_condition> >
|
||||
Sql_condition_list;
|
||||
|
||||
/** A memory root to allocate warnings and errors */
|
||||
MEM_ROOT m_warn_root;
|
||||
|
||||
/** List of warnings of all severities (levels). */
|
||||
List <MYSQL_ERROR> m_warn_list;
|
||||
Sql_condition_list m_warn_list;
|
||||
|
||||
/** A break down of the number of warnings per severity (level). */
|
||||
uint m_warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_END];
|
||||
uint m_warn_count[(uint) Sql_condition::WARN_LEVEL_END];
|
||||
|
||||
/**
|
||||
The number of warnings of the current statement. Warning_info
|
||||
life cycle differs from statement life cycle -- it may span
|
||||
multiple statements. In that case we get
|
||||
m_statement_warn_count 0, whereas m_warn_list is not empty.
|
||||
m_current_statement_warn_count 0, whereas m_warn_list is not empty.
|
||||
*/
|
||||
uint m_statement_warn_count;
|
||||
uint m_current_statement_warn_count;
|
||||
|
||||
/*
|
||||
Row counter, to print in errors and warnings. Not increased in
|
||||
|
|
@ -365,29 +260,67 @@ class Warning_info
|
|||
/** Used to optionally clear warnings only once per statement. */
|
||||
ulonglong m_warn_id;
|
||||
|
||||
/**
|
||||
A pointer to an element of m_warn_list. It determines SQL-condition
|
||||
instance which corresponds to the error state in Diagnostics_area.
|
||||
|
||||
This is needed for properly processing SQL-conditions in SQL-handlers.
|
||||
When an SQL-handler is found for the current error state in Diagnostics_area,
|
||||
this pointer is needed to remove the corresponding SQL-condition from the
|
||||
Warning_info list.
|
||||
|
||||
@note m_error_condition might be NULL in the following cases:
|
||||
- Diagnostics_area set to fatal error state (like OOM);
|
||||
- Max number of Warning_info elements has been reached (thus, there is
|
||||
no corresponding SQL-condition object in Warning_info).
|
||||
*/
|
||||
const Sql_condition *m_error_condition;
|
||||
|
||||
/** Indicates if push_warning() allows unlimited number of warnings. */
|
||||
bool m_allow_unlimited_warnings;
|
||||
bool initialized; /* Set to 1 if init() has been called */
|
||||
|
||||
private:
|
||||
Warning_info(const Warning_info &rhs); /* Not implemented */
|
||||
Warning_info& operator=(const Warning_info &rhs); /* Not implemented */
|
||||
/** Read only status. */
|
||||
bool m_read_only;
|
||||
|
||||
/** Pointers for participating in the stack of Warning_info objects. */
|
||||
Warning_info *m_next_in_da;
|
||||
Warning_info **m_prev_in_da;
|
||||
|
||||
List<Sql_condition> m_marked_sql_conditions;
|
||||
|
||||
public:
|
||||
|
||||
Warning_info(ulonglong warn_id_arg, bool allow_unlimited_warnings,
|
||||
bool initialize=true);
|
||||
bool initialized);
|
||||
~Warning_info();
|
||||
|
||||
/* Allocate memory for structures */
|
||||
void init();
|
||||
void free_memory();
|
||||
|
||||
private:
|
||||
Warning_info(const Warning_info &rhs); /* Not implemented */
|
||||
Warning_info& operator=(const Warning_info &rhs); /* Not implemented */
|
||||
|
||||
/**
|
||||
Checks if Warning_info contains SQL-condition with the given message.
|
||||
|
||||
@param message_str Message string.
|
||||
@param message_length Length of message string.
|
||||
|
||||
@return true if the Warning_info contains an SQL-condition with the given
|
||||
message.
|
||||
*/
|
||||
bool has_sql_condition(const char *message_str, ulong message_length) const;
|
||||
|
||||
/**
|
||||
Reset the warning information. Clear all warnings,
|
||||
the number of warnings, reset current row counter
|
||||
to point to the first row.
|
||||
|
||||
@param new_id new Warning_info id.
|
||||
*/
|
||||
void clear_warning_info(ulonglong warn_id_arg);
|
||||
void clear(ulonglong new_id);
|
||||
|
||||
/**
|
||||
Only clear warning info if haven't yet done that already
|
||||
for the current query. Allows to be issued at any time
|
||||
|
|
@ -396,46 +329,72 @@ public:
|
|||
|
||||
@todo: This is a sign of sloppy coding. Instead we need to
|
||||
designate one place in a statement life cycle where we call
|
||||
clear_warning_info().
|
||||
Warning_info::clear().
|
||||
|
||||
@param query_id Current query id.
|
||||
*/
|
||||
void opt_clear_warning_info(ulonglong query_id)
|
||||
void opt_clear(ulonglong query_id)
|
||||
{
|
||||
if (query_id != m_warn_id)
|
||||
clear_warning_info(query_id);
|
||||
}
|
||||
|
||||
void append_warning_info(THD *thd, Warning_info *source)
|
||||
{
|
||||
append_warnings(thd, & source->warn_list());
|
||||
clear(query_id);
|
||||
}
|
||||
|
||||
/**
|
||||
Concatenate the list of warnings.
|
||||
It's considered tolerable to lose a warning.
|
||||
*/
|
||||
void append_warnings(THD *thd, List<MYSQL_ERROR> *src)
|
||||
{
|
||||
MYSQL_ERROR *err;
|
||||
List_iterator_fast<MYSQL_ERROR> it(*src);
|
||||
/*
|
||||
Don't use ::push_warning() to avoid invocation of condition
|
||||
handlers or escalation of warnings to errors.
|
||||
*/
|
||||
while ((err= it++))
|
||||
Warning_info::push_warning(thd, err);
|
||||
}
|
||||
|
||||
/**
|
||||
Conditional merge of related warning information areas.
|
||||
It's considered tolerable to lose an SQL-condition in case of OOM-error,
|
||||
or if the number of SQL-conditions in the Warning_info reached top limit.
|
||||
|
||||
@param thd Thread context.
|
||||
@param source Warning_info object to copy SQL-conditions from.
|
||||
*/
|
||||
void merge_with_routine_info(THD *thd, Warning_info *source);
|
||||
void append_warning_info(THD *thd, const Warning_info *source);
|
||||
|
||||
/**
|
||||
Reset between two COM_ commands. Warnings are preserved
|
||||
between commands, but statement_warn_count indicates
|
||||
the number of warnings of this particular statement only.
|
||||
*/
|
||||
void reset_for_next_command() { m_statement_warn_count= 0; }
|
||||
void reset_for_next_command()
|
||||
{ m_current_statement_warn_count= 0; }
|
||||
|
||||
/**
|
||||
Mark active SQL-conditions for later removal.
|
||||
This is done to simulate stacked DAs for HANDLER statements.
|
||||
*/
|
||||
void mark_sql_conditions_for_removal();
|
||||
|
||||
/**
|
||||
Unmark SQL-conditions, which were marked for later removal.
|
||||
This is done to simulate stacked DAs for HANDLER statements.
|
||||
*/
|
||||
void unmark_sql_conditions_from_removal()
|
||||
{ m_marked_sql_conditions.empty(); }
|
||||
|
||||
/**
|
||||
Remove SQL-conditions that are marked for deletion.
|
||||
This is done to simulate stacked DAs for HANDLER statements.
|
||||
*/
|
||||
void remove_marked_sql_conditions();
|
||||
|
||||
/**
|
||||
Check if the given SQL-condition is marked for removal in this Warning_info
|
||||
instance.
|
||||
|
||||
@param cond the SQL-condition.
|
||||
|
||||
@retval true if the given SQL-condition is marked for removal in this
|
||||
Warning_info instance.
|
||||
@retval false otherwise.
|
||||
*/
|
||||
bool is_marked_for_removal(const Sql_condition *cond) const;
|
||||
|
||||
/**
|
||||
Mark a single SQL-condition for removal (add the given SQL-condition to the
|
||||
removal list of this Warning_info instance).
|
||||
*/
|
||||
void mark_condition_for_removal(Sql_condition *cond)
|
||||
{ m_marked_sql_conditions.push_back(cond, &m_warn_root); }
|
||||
|
||||
/**
|
||||
Used for @@warning_count system variable, which prints
|
||||
|
|
@ -444,52 +403,82 @@ public:
|
|||
ulong warn_count() const
|
||||
{
|
||||
/*
|
||||
This may be higher than warn_list.elements if we have
|
||||
This may be higher than warn_list.elements() if we have
|
||||
had more warnings than thd->variables.max_error_count.
|
||||
*/
|
||||
return (m_warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_NOTE] +
|
||||
m_warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_ERROR] +
|
||||
m_warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_WARN]);
|
||||
return (m_warn_count[(uint) Sql_condition::WARN_LEVEL_NOTE] +
|
||||
m_warn_count[(uint) Sql_condition::WARN_LEVEL_ERROR] +
|
||||
m_warn_count[(uint) Sql_condition::WARN_LEVEL_WARN]);
|
||||
}
|
||||
|
||||
/**
|
||||
This is for iteration purposes. We return a non-constant reference
|
||||
since List doesn't have constant iterators.
|
||||
*/
|
||||
List<MYSQL_ERROR> &warn_list() { return m_warn_list; }
|
||||
|
||||
/**
|
||||
The number of errors, or number of rows returned by SHOW ERRORS,
|
||||
also the value of session variable @@error_count.
|
||||
*/
|
||||
ulong error_count() const
|
||||
{ return m_warn_count[(uint) Sql_condition::WARN_LEVEL_ERROR]; }
|
||||
|
||||
/**
|
||||
The number of conditions (errors, warnings and notes) in the list.
|
||||
*/
|
||||
uint cond_count() const
|
||||
{
|
||||
return m_warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_ERROR];
|
||||
return m_warn_list.elements();
|
||||
}
|
||||
|
||||
/** Id of the warning information area. */
|
||||
ulonglong warn_id() const { return m_warn_id; }
|
||||
ulonglong id() const { return m_warn_id; }
|
||||
|
||||
/** Set id of the warning information area. */
|
||||
void id(ulonglong id) { m_warn_id= id; }
|
||||
|
||||
/** Do we have any errors and warnings that we can *show*? */
|
||||
bool is_empty() const { return m_warn_list.elements == 0; }
|
||||
bool is_empty() const { return m_warn_list.is_empty(); }
|
||||
|
||||
/** Increment the current row counter to point at the next row. */
|
||||
void inc_current_row_for_warning() { m_current_row_for_warning++; }
|
||||
|
||||
/** Reset the current row counter. Start counting from the first row. */
|
||||
void reset_current_row_for_warning() { m_current_row_for_warning= 1; }
|
||||
|
||||
/** Return the current counter value. */
|
||||
ulong current_row_for_warning() const { return m_current_row_for_warning; }
|
||||
|
||||
ulong statement_warn_count() const { return m_statement_warn_count; }
|
||||
/** Return the number of warnings thrown by the current statement. */
|
||||
ulong current_statement_warn_count() const
|
||||
{ return m_current_statement_warn_count; }
|
||||
|
||||
/** Add a new condition to the current list. */
|
||||
MYSQL_ERROR *push_warning(THD *thd,
|
||||
uint sql_errno, const char* sqlstate,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
const char* msg);
|
||||
/** Make sure there is room for the given number of conditions. */
|
||||
void reserve_space(THD *thd, uint count);
|
||||
|
||||
/** Add a new condition to the current list. */
|
||||
MYSQL_ERROR *push_warning(THD *thd, const MYSQL_ERROR *sql_condition);
|
||||
/**
|
||||
Add a new SQL-condition to the current list and increment the respective
|
||||
counters.
|
||||
|
||||
@param thd Thread context.
|
||||
@param sql_errno SQL-condition error number.
|
||||
@param sqlstate SQL-condition state.
|
||||
@param level SQL-condition level.
|
||||
@param msg SQL-condition message.
|
||||
|
||||
@return a pointer to the added SQL-condition.
|
||||
*/
|
||||
Sql_condition *push_warning(THD *thd,
|
||||
uint sql_errno,
|
||||
const char* sqlstate,
|
||||
Sql_condition::enum_warning_level level,
|
||||
const char* msg);
|
||||
|
||||
/**
|
||||
Add a new SQL-condition to the current list and increment the respective
|
||||
counters.
|
||||
|
||||
@param thd Thread context.
|
||||
@param sql_condition SQL-condition to copy values from.
|
||||
|
||||
@return a pointer to the added SQL-condition.
|
||||
*/
|
||||
Sql_condition *push_warning(THD *thd, const Sql_condition *sql_condition);
|
||||
|
||||
/**
|
||||
Set the read only status for this statement area.
|
||||
|
|
@ -500,25 +489,51 @@ public:
|
|||
- SHOW WARNINGS
|
||||
- SHOW ERRORS
|
||||
- GET DIAGNOSTICS
|
||||
@param read_only the read only property to set
|
||||
@param read_only the read only property to set.
|
||||
*/
|
||||
void set_read_only(bool read_only)
|
||||
{ m_read_only= read_only; }
|
||||
|
||||
/**
|
||||
Read only status.
|
||||
@return the read only property
|
||||
@return the read only property.
|
||||
*/
|
||||
bool is_read_only() const
|
||||
{ return m_read_only; }
|
||||
|
||||
private:
|
||||
/** Read only status. */
|
||||
bool m_read_only;
|
||||
/**
|
||||
@return SQL-condition, which corresponds to the error state in
|
||||
Diagnostics_area.
|
||||
|
||||
friend class Resignal_statement;
|
||||
@see m_error_condition.
|
||||
*/
|
||||
const Sql_condition *get_error_condition() const
|
||||
{ return m_error_condition; }
|
||||
|
||||
/**
|
||||
Set SQL-condition, which corresponds to the error state in Diagnostics_area.
|
||||
|
||||
@see m_error_condition.
|
||||
*/
|
||||
void set_error_condition(const Sql_condition *error_condition)
|
||||
{ m_error_condition= error_condition; }
|
||||
|
||||
/**
|
||||
Reset SQL-condition, which corresponds to the error state in
|
||||
Diagnostics_area.
|
||||
|
||||
@see m_error_condition.
|
||||
*/
|
||||
void clear_error_condition()
|
||||
{ m_error_condition= NULL; }
|
||||
|
||||
// for:
|
||||
// - m_next_in_da / m_prev_in_da
|
||||
// - is_marked_for_removal()
|
||||
friend class Diagnostics_area;
|
||||
};
|
||||
|
||||
|
||||
extern char *err_conv(char *buff, uint to_length, const char *from,
|
||||
uint from_length, CHARSET_INFO *from_cs);
|
||||
|
||||
|
|
@ -592,15 +607,352 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
void push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
Stores status of the currently executed statement.
|
||||
Cleared at the beginning of the statement, and then
|
||||
can hold either OK, ERROR, or EOF status.
|
||||
Can not be assigned twice per statement.
|
||||
*/
|
||||
|
||||
class Diagnostics_area
|
||||
{
|
||||
private:
|
||||
/** The type of the counted and doubly linked list of conditions. */
|
||||
typedef I_P_List<Warning_info,
|
||||
I_P_List_adapter<Warning_info,
|
||||
&Warning_info::m_next_in_da,
|
||||
&Warning_info::m_prev_in_da>,
|
||||
I_P_List_counter,
|
||||
I_P_List_fast_push_back<Warning_info> >
|
||||
Warning_info_list;
|
||||
|
||||
public:
|
||||
/** Const iterator used to iterate through the warning list. */
|
||||
typedef Warning_info::Sql_condition_list::Const_Iterator
|
||||
Sql_condition_iterator;
|
||||
|
||||
enum enum_diagnostics_status
|
||||
{
|
||||
/** The area is cleared at start of a statement. */
|
||||
DA_EMPTY= 0,
|
||||
/** Set whenever one calls my_ok(). */
|
||||
DA_OK,
|
||||
/** Set whenever one calls my_eof(). */
|
||||
DA_EOF,
|
||||
/** Set whenever one calls my_error() or my_message(). */
|
||||
DA_ERROR,
|
||||
/** Set in case of a custom response, such as one from COM_STMT_PREPARE. */
|
||||
DA_DISABLED
|
||||
};
|
||||
|
||||
void set_overwrite_status(bool can_overwrite_status)
|
||||
{ m_can_overwrite_status= can_overwrite_status; }
|
||||
|
||||
/** True if status information is sent to the client. */
|
||||
bool is_sent() const { return m_is_sent; }
|
||||
|
||||
void set_is_sent(bool is_sent) { m_is_sent= is_sent; }
|
||||
|
||||
void set_ok_status(ulonglong affected_rows,
|
||||
ulonglong last_insert_id,
|
||||
const char *message);
|
||||
|
||||
void set_eof_status(THD *thd);
|
||||
|
||||
void set_error_status(uint sql_errno);
|
||||
|
||||
void set_error_status(uint sql_errno,
|
||||
const char *message,
|
||||
const char *sqlstate,
|
||||
const Sql_condition *error_condition);
|
||||
|
||||
void disable_status();
|
||||
|
||||
void reset_diagnostics_area();
|
||||
|
||||
bool is_set() const { return m_status != DA_EMPTY; }
|
||||
|
||||
bool is_error() const { return m_status == DA_ERROR; }
|
||||
|
||||
bool is_eof() const { return m_status == DA_EOF; }
|
||||
|
||||
bool is_ok() const { return m_status == DA_OK; }
|
||||
|
||||
bool is_disabled() const { return m_status == DA_DISABLED; }
|
||||
|
||||
enum_diagnostics_status status() const { return m_status; }
|
||||
|
||||
const char *message() const
|
||||
{ DBUG_ASSERT(m_status == DA_ERROR || m_status == DA_OK); return m_message; }
|
||||
|
||||
uint sql_errno() const
|
||||
{ DBUG_ASSERT(m_status == DA_ERROR); return m_sql_errno; }
|
||||
|
||||
const char* get_sqlstate() const
|
||||
{ DBUG_ASSERT(m_status == DA_ERROR); return m_sqlstate; }
|
||||
|
||||
ulonglong affected_rows() const
|
||||
{ DBUG_ASSERT(m_status == DA_OK); return m_affected_rows; }
|
||||
|
||||
ulonglong last_insert_id() const
|
||||
{ DBUG_ASSERT(m_status == DA_OK); return m_last_insert_id; }
|
||||
|
||||
uint statement_warn_count() const
|
||||
{
|
||||
DBUG_ASSERT(m_status == DA_OK || m_status == DA_EOF);
|
||||
return m_statement_warn_count;
|
||||
}
|
||||
|
||||
/* Used to count any warnings pushed after calling set_ok_status(). */
|
||||
void increment_warning()
|
||||
{
|
||||
if (m_status != DA_EMPTY)
|
||||
m_statement_warn_count++;
|
||||
}
|
||||
|
||||
Diagnostics_area(bool initialize);
|
||||
Diagnostics_area(ulonglong warning_info_id, bool allow_unlimited_warnings);
|
||||
void init() { m_main_wi.init() ; }
|
||||
void free_memory() { m_main_wi.free_memory() ; }
|
||||
|
||||
void push_warning_info(Warning_info *wi)
|
||||
{ m_wi_stack.push_front(wi); }
|
||||
|
||||
void pop_warning_info()
|
||||
{
|
||||
DBUG_ASSERT(m_wi_stack.elements() > 0);
|
||||
m_wi_stack.remove(m_wi_stack.front());
|
||||
}
|
||||
|
||||
void set_warning_info_id(ulonglong id)
|
||||
{ get_warning_info()->id(id); }
|
||||
|
||||
ulonglong warning_info_id() const
|
||||
{ return get_warning_info()->id(); }
|
||||
|
||||
/**
|
||||
Compare given current warning info and current warning info
|
||||
and see if they are different. They will be different if
|
||||
warnings have been generated or statements that use tables
|
||||
have been executed. This is checked by comparing m_warn_id.
|
||||
|
||||
@param wi Warning info to compare with current Warning info.
|
||||
|
||||
@return false if they are equal, true if they are not.
|
||||
*/
|
||||
bool warning_info_changed(const Warning_info *wi) const
|
||||
{ return get_warning_info()->id() != wi->id(); }
|
||||
|
||||
bool is_warning_info_empty() const
|
||||
{ return get_warning_info()->is_empty(); }
|
||||
|
||||
ulong current_statement_warn_count() const
|
||||
{ return get_warning_info()->current_statement_warn_count(); }
|
||||
|
||||
bool has_sql_condition(const char *message_str, ulong message_length) const
|
||||
{ return get_warning_info()->has_sql_condition(message_str, message_length); }
|
||||
|
||||
void reset_for_next_command()
|
||||
{ get_warning_info()->reset_for_next_command(); }
|
||||
|
||||
void clear_warning_info(ulonglong id)
|
||||
{ get_warning_info()->clear(id); }
|
||||
|
||||
void opt_clear_warning_info(ulonglong query_id)
|
||||
{ get_warning_info()->opt_clear(query_id); }
|
||||
|
||||
ulong current_row_for_warning() const
|
||||
{ return get_warning_info()->current_row_for_warning(); }
|
||||
|
||||
void inc_current_row_for_warning()
|
||||
{ get_warning_info()->inc_current_row_for_warning(); }
|
||||
|
||||
void reset_current_row_for_warning()
|
||||
{ get_warning_info()->reset_current_row_for_warning(); }
|
||||
|
||||
bool is_warning_info_read_only() const
|
||||
{ return get_warning_info()->is_read_only(); }
|
||||
|
||||
void set_warning_info_read_only(bool read_only)
|
||||
{ get_warning_info()->set_read_only(read_only); }
|
||||
|
||||
ulong error_count() const
|
||||
{ return get_warning_info()->error_count(); }
|
||||
|
||||
ulong warn_count() const
|
||||
{ return get_warning_info()->warn_count(); }
|
||||
|
||||
uint cond_count() const
|
||||
{ return get_warning_info()->cond_count(); }
|
||||
|
||||
Sql_condition_iterator sql_conditions() const
|
||||
{ return get_warning_info()->m_warn_list; }
|
||||
|
||||
void reserve_space(THD *thd, uint count)
|
||||
{ get_warning_info()->reserve_space(thd, count); }
|
||||
|
||||
Sql_condition *push_warning(THD *thd, const Sql_condition *sql_condition)
|
||||
{ return get_warning_info()->push_warning(thd, sql_condition); }
|
||||
|
||||
Sql_condition *push_warning(THD *thd,
|
||||
uint sql_errno,
|
||||
const char* sqlstate,
|
||||
Sql_condition::enum_warning_level level,
|
||||
const char* msg)
|
||||
{
|
||||
return get_warning_info()->push_warning(thd,
|
||||
sql_errno, sqlstate, level, msg);
|
||||
}
|
||||
|
||||
void mark_sql_conditions_for_removal()
|
||||
{ get_warning_info()->mark_sql_conditions_for_removal(); }
|
||||
|
||||
void unmark_sql_conditions_from_removal()
|
||||
{ get_warning_info()->unmark_sql_conditions_from_removal(); }
|
||||
|
||||
void remove_marked_sql_conditions()
|
||||
{ get_warning_info()->remove_marked_sql_conditions(); }
|
||||
|
||||
const Sql_condition *get_error_condition() const
|
||||
{ return get_warning_info()->get_error_condition(); }
|
||||
|
||||
void copy_sql_conditions_to_wi(THD *thd, Warning_info *dst_wi) const
|
||||
{ dst_wi->append_warning_info(thd, get_warning_info()); }
|
||||
|
||||
void copy_sql_conditions_from_wi(THD *thd, const Warning_info *src_wi)
|
||||
{ get_warning_info()->append_warning_info(thd, src_wi); }
|
||||
|
||||
void copy_non_errors_from_wi(THD *thd, const Warning_info *src_wi);
|
||||
|
||||
private:
|
||||
Warning_info *get_warning_info() { return m_wi_stack.front(); }
|
||||
|
||||
const Warning_info *get_warning_info() const { return m_wi_stack.front(); }
|
||||
|
||||
private:
|
||||
/** True if status information is sent to the client. */
|
||||
bool m_is_sent;
|
||||
|
||||
/** Set to make set_error_status after set_{ok,eof}_status possible. */
|
||||
bool m_can_overwrite_status;
|
||||
|
||||
/** Message buffer. Can be used by OK or ERROR status. */
|
||||
char m_message[MYSQL_ERRMSG_SIZE];
|
||||
|
||||
/**
|
||||
SQL error number. One of ER_ codes from share/errmsg.txt.
|
||||
Set by set_error_status.
|
||||
*/
|
||||
uint m_sql_errno;
|
||||
|
||||
char m_sqlstate[SQLSTATE_LENGTH+1];
|
||||
|
||||
/**
|
||||
The number of rows affected by the last statement. This is
|
||||
semantically close to thd->row_count_func, but has a different
|
||||
life cycle. thd->row_count_func stores the value returned by
|
||||
function ROW_COUNT() and is cleared only by statements that
|
||||
update its value, such as INSERT, UPDATE, DELETE and few others.
|
||||
This member is cleared at the beginning of the next statement.
|
||||
|
||||
We could possibly merge the two, but life cycle of thd->row_count_func
|
||||
can not be changed.
|
||||
*/
|
||||
ulonglong m_affected_rows;
|
||||
|
||||
/**
|
||||
Similarly to the previous member, this is a replacement of
|
||||
thd->first_successful_insert_id_in_prev_stmt, which is used
|
||||
to implement LAST_INSERT_ID().
|
||||
*/
|
||||
|
||||
ulonglong m_last_insert_id;
|
||||
/**
|
||||
Number of warnings of this last statement. May differ from
|
||||
the number of warnings returned by SHOW WARNINGS e.g. in case
|
||||
the statement doesn't clear the warnings, and doesn't generate
|
||||
them.
|
||||
*/
|
||||
uint m_statement_warn_count;
|
||||
|
||||
enum_diagnostics_status m_status;
|
||||
|
||||
Warning_info m_main_wi;
|
||||
|
||||
Warning_info_list m_wi_stack;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void push_warning(THD *thd, Sql_condition::enum_warning_level level,
|
||||
uint code, const char *msg);
|
||||
void push_warning_printf(THD *thd, MYSQL_ERROR::enum_warning_level level,
|
||||
uint code, const char *format, ...);
|
||||
|
||||
void push_warning_printf(THD *thd, Sql_condition::enum_warning_level level,
|
||||
uint code, const char *format, ...);
|
||||
|
||||
bool mysqld_show_warnings(THD *thd, ulong levels_to_show);
|
||||
uint32 convert_error_message(char *to, uint32 to_length, CHARSET_INFO *to_cs,
|
||||
|
||||
uint32 convert_error_message(char *to, uint32 to_length,
|
||||
CHARSET_INFO *to_cs,
|
||||
const char *from, uint32 from_length,
|
||||
CHARSET_INFO *from_cs, uint *errors);
|
||||
|
||||
extern const LEX_STRING warning_level_names[];
|
||||
|
||||
bool is_sqlstate_valid(const LEX_STRING *sqlstate);
|
||||
/**
|
||||
Checks if the specified SQL-state-string defines COMPLETION condition.
|
||||
This function assumes that the given string contains a valid SQL-state.
|
||||
|
||||
@param s the condition SQLSTATE.
|
||||
|
||||
@retval true if the given string defines COMPLETION condition.
|
||||
@retval false otherwise.
|
||||
*/
|
||||
inline bool is_sqlstate_completion(const char *s)
|
||||
{ return s[0] == '0' && s[1] == '0'; }
|
||||
|
||||
|
||||
/**
|
||||
Checks if the specified SQL-state-string defines WARNING condition.
|
||||
This function assumes that the given string contains a valid SQL-state.
|
||||
|
||||
@param s the condition SQLSTATE.
|
||||
|
||||
@retval true if the given string defines WARNING condition.
|
||||
@retval false otherwise.
|
||||
*/
|
||||
inline bool is_sqlstate_warning(const char *s)
|
||||
{ return s[0] == '0' && s[1] == '1'; }
|
||||
|
||||
|
||||
/**
|
||||
Checks if the specified SQL-state-string defines NOT FOUND condition.
|
||||
This function assumes that the given string contains a valid SQL-state.
|
||||
|
||||
@param s the condition SQLSTATE.
|
||||
|
||||
@retval true if the given string defines NOT FOUND condition.
|
||||
@retval false otherwise.
|
||||
*/
|
||||
inline bool is_sqlstate_not_found(const char *s)
|
||||
{ return s[0] == '0' && s[1] == '2'; }
|
||||
|
||||
|
||||
/**
|
||||
Checks if the specified SQL-state-string defines EXCEPTION condition.
|
||||
This function assumes that the given string contains a valid SQL-state.
|
||||
|
||||
@param s the condition SQLSTATE.
|
||||
|
||||
@retval true if the given string defines EXCEPTION condition.
|
||||
@retval false otherwise.
|
||||
*/
|
||||
inline bool is_sqlstate_exception(const char *s)
|
||||
{ return s[0] != '0' || s[1] > '2'; }
|
||||
|
||||
|
||||
#endif // SQL_ERROR_H
|
||||
|
|
|
|||
340
sql/sql_get_diagnostics.cc
Normal file
340
sql/sql_get_diagnostics.cc
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
/* Copyright (c) 2011, 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
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include "sql_list.h" // Sql_alloc, List, List_iterator
|
||||
#include "sql_cmd.h" // Sql_cmd
|
||||
#include "sql_class.h" // Diagnostics_area
|
||||
#include "sql_get_diagnostics.h" // Sql_cmd_get_diagnostics
|
||||
|
||||
/**
|
||||
Execute this GET DIAGNOSTICS statement.
|
||||
|
||||
@param thd The current thread.
|
||||
|
||||
@remark Errors or warnings occurring during the execution of the GET
|
||||
DIAGNOSTICS statement should not affect the diagnostics area
|
||||
of a previous statement as the diagnostics information there
|
||||
would be wiped out. Thus, in order to preserve the contents
|
||||
of the diagnostics area from which information is being
|
||||
retrieved, the GET DIAGNOSTICS statement is executed under
|
||||
a separate diagnostics area. If any errors or warnings occur
|
||||
during the execution of the GET DIAGNOSTICS statement, these
|
||||
error or warnings (conditions) are appended to the list of
|
||||
the original diagnostics area. The only exception to this is
|
||||
fatal errors, which must always cause the statement to fail.
|
||||
|
||||
@retval false on success.
|
||||
@retval true on error
|
||||
*/
|
||||
|
||||
bool
|
||||
Sql_cmd_get_diagnostics::execute(THD *thd)
|
||||
{
|
||||
bool rv;
|
||||
Diagnostics_area new_stmt_da(thd->query_id, false);
|
||||
Diagnostics_area *save_stmt_da= thd->get_stmt_da();
|
||||
DBUG_ENTER("Sql_cmd_get_diagnostics::execute");
|
||||
|
||||
/* Disable the unneeded read-only mode of the original DA. */
|
||||
save_stmt_da->set_warning_info_read_only(false);
|
||||
|
||||
/* Set new diagnostics area, execute statement and restore. */
|
||||
thd->set_stmt_da(&new_stmt_da);
|
||||
rv= m_info->aggregate(thd, save_stmt_da);
|
||||
thd->set_stmt_da(save_stmt_da);
|
||||
|
||||
/* Bail out early if statement succeeded. */
|
||||
if (! rv)
|
||||
{
|
||||
thd->get_stmt_da()->set_ok_status(0, 0, NULL);
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
|
||||
/* Statement failed, retrieve the error information for propagation. */
|
||||
uint sql_errno= new_stmt_da.sql_errno();
|
||||
const char *message= new_stmt_da.message();
|
||||
const char *sqlstate= new_stmt_da.get_sqlstate();
|
||||
|
||||
/* In case of a fatal error, set it into the original DA.*/
|
||||
if (thd->is_fatal_error)
|
||||
{
|
||||
save_stmt_da->set_error_status(sql_errno, message, sqlstate, NULL);
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
|
||||
/* Otherwise, just append the new error as a exception condition. */
|
||||
save_stmt_da->push_warning(thd, sql_errno, sqlstate,
|
||||
Sql_condition::WARN_LEVEL_ERROR,
|
||||
message);
|
||||
|
||||
/* Appending might have failed. */
|
||||
if (! (rv= thd->is_error()))
|
||||
thd->get_stmt_da()->set_ok_status(0, 0, NULL);
|
||||
|
||||
DBUG_RETURN(rv);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Set a value for this item.
|
||||
|
||||
@param thd The current thread.
|
||||
@param value The obtained value.
|
||||
|
||||
@retval false on success.
|
||||
@retval true on error.
|
||||
*/
|
||||
|
||||
bool
|
||||
Diagnostics_information_item::set_value(THD *thd, Item **value)
|
||||
{
|
||||
bool rv;
|
||||
Settable_routine_parameter *srp;
|
||||
DBUG_ENTER("Diagnostics_information_item::set_value");
|
||||
|
||||
/* Get a settable reference to the target. */
|
||||
srp= m_target->get_settable_routine_parameter();
|
||||
|
||||
DBUG_ASSERT(srp);
|
||||
|
||||
/* Set variable/parameter value. */
|
||||
rv= srp->set_value(thd, thd->spcont, value);
|
||||
|
||||
DBUG_RETURN(rv);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Obtain statement information in the context of a given diagnostics area.
|
||||
|
||||
@param thd The current thread.
|
||||
@param da The diagnostics area.
|
||||
|
||||
@retval false on success.
|
||||
@retval true on error
|
||||
*/
|
||||
|
||||
bool
|
||||
Statement_information::aggregate(THD *thd, const Diagnostics_area *da)
|
||||
{
|
||||
bool rv= false;
|
||||
Statement_information_item *stmt_info_item;
|
||||
List_iterator<Statement_information_item> it(*m_items);
|
||||
DBUG_ENTER("Statement_information::aggregate");
|
||||
|
||||
/*
|
||||
Each specified target gets the value of each given
|
||||
information item obtained from the diagnostics area.
|
||||
*/
|
||||
while ((stmt_info_item= it++))
|
||||
{
|
||||
if ((rv= evaluate(thd, stmt_info_item, da)))
|
||||
break;
|
||||
}
|
||||
|
||||
DBUG_RETURN(rv);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Obtain the value of this statement information item in the context of
|
||||
a given diagnostics area.
|
||||
|
||||
@param thd The current thread.
|
||||
@param da The diagnostics area.
|
||||
|
||||
@retval Item representing the value.
|
||||
@retval NULL on error.
|
||||
*/
|
||||
|
||||
Item *
|
||||
Statement_information_item::get_value(THD *thd, const Diagnostics_area *da)
|
||||
{
|
||||
Item *value= NULL;
|
||||
DBUG_ENTER("Statement_information_item::get_value");
|
||||
|
||||
switch (m_name)
|
||||
{
|
||||
/*
|
||||
The number of condition areas that have information. That is,
|
||||
the number of errors and warnings within the diagnostics area.
|
||||
*/
|
||||
case NUMBER:
|
||||
{
|
||||
ulong count= da->cond_count();
|
||||
value= new (thd->mem_root) Item_uint(count);
|
||||
break;
|
||||
}
|
||||
/*
|
||||
Number that shows how many rows were directly affected by
|
||||
a data-change statement (INSERT, UPDATE, DELETE, MERGE,
|
||||
REPLACE, LOAD).
|
||||
*/
|
||||
case ROW_COUNT:
|
||||
value= new (thd->mem_root) Item_int(thd->get_row_count_func());
|
||||
break;
|
||||
}
|
||||
|
||||
DBUG_RETURN(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Obtain condition information in the context of a given diagnostics area.
|
||||
|
||||
@param thd The current thread.
|
||||
@param da The diagnostics area.
|
||||
|
||||
@retval false on success.
|
||||
@retval true on error
|
||||
*/
|
||||
|
||||
bool
|
||||
Condition_information::aggregate(THD *thd, const Diagnostics_area *da)
|
||||
{
|
||||
bool rv= false;
|
||||
longlong cond_number;
|
||||
const Sql_condition *cond= NULL;
|
||||
Condition_information_item *cond_info_item;
|
||||
Diagnostics_area::Sql_condition_iterator it_conds= da->sql_conditions();
|
||||
List_iterator_fast<Condition_information_item> it_items(*m_items);
|
||||
DBUG_ENTER("Condition_information::aggregate");
|
||||
|
||||
/* Prepare the expression for evaluation. */
|
||||
if (!m_cond_number_expr->fixed &&
|
||||
m_cond_number_expr->fix_fields(thd, &m_cond_number_expr))
|
||||
DBUG_RETURN(true);
|
||||
|
||||
cond_number= m_cond_number_expr->val_int();
|
||||
|
||||
/*
|
||||
Limit to the number of available conditions. Warning_info::warn_count()
|
||||
is not used because it indicates the number of condition regardless of
|
||||
@@max_error_count, which prevents conditions from being pushed, but not
|
||||
counted.
|
||||
*/
|
||||
if (cond_number < 1 || (ulonglong) cond_number > da->cond_count())
|
||||
{
|
||||
my_error(ER_DA_INVALID_CONDITION_NUMBER, MYF(0));
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
|
||||
/* Advance to the requested condition. */
|
||||
while (cond_number--)
|
||||
cond= it_conds++;
|
||||
|
||||
DBUG_ASSERT(cond);
|
||||
|
||||
/* Evaluate the requested information in the context of the condition. */
|
||||
while ((cond_info_item= it_items++))
|
||||
{
|
||||
if ((rv= evaluate(thd, cond_info_item, cond)))
|
||||
break;
|
||||
}
|
||||
|
||||
DBUG_RETURN(rv);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Create an UTF-8 string item to represent a condition item string.
|
||||
|
||||
@remark The string might not have a associated charset. For example,
|
||||
this can be the case if the server does not or fails to process
|
||||
the error message file.
|
||||
|
||||
@remark See "Design notes about Sql_condition::m_message_text." in sql_error.cc
|
||||
|
||||
@return Pointer to an string item, NULL on failure.
|
||||
*/
|
||||
|
||||
Item *
|
||||
Condition_information_item::make_utf8_string_item(THD *thd, const String *str)
|
||||
{
|
||||
/* Default is utf8 character set and utf8_general_ci collation. */
|
||||
CHARSET_INFO *to_cs= &my_charset_utf8_general_ci;
|
||||
/* If a charset was not set, assume that no conversion is needed. */
|
||||
CHARSET_INFO *from_cs= str->charset() ? str->charset() : to_cs;
|
||||
Item_string *item= new Item_string(str->ptr(), str->length(), from_cs);
|
||||
/* If necessary, convert the string (ignoring errors), then copy it over. */
|
||||
return item ? item->charset_converter(to_cs, false) : NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Obtain the value of this condition information item in the context of
|
||||
a given condition.
|
||||
|
||||
@param thd The current thread.
|
||||
@param da The diagnostics area.
|
||||
|
||||
@retval Item representing the value.
|
||||
@retval NULL on error.
|
||||
*/
|
||||
|
||||
Item *
|
||||
Condition_information_item::get_value(THD *thd, const Sql_condition *cond)
|
||||
{
|
||||
String str;
|
||||
Item *value= NULL;
|
||||
DBUG_ENTER("Condition_information_item::get_value");
|
||||
|
||||
switch (m_name)
|
||||
{
|
||||
case CLASS_ORIGIN:
|
||||
value= make_utf8_string_item(thd, &(cond->m_class_origin));
|
||||
break;
|
||||
case SUBCLASS_ORIGIN:
|
||||
value= make_utf8_string_item(thd, &(cond->m_subclass_origin));
|
||||
break;
|
||||
case CONSTRAINT_CATALOG:
|
||||
value= make_utf8_string_item(thd, &(cond->m_constraint_catalog));
|
||||
break;
|
||||
case CONSTRAINT_SCHEMA:
|
||||
value= make_utf8_string_item(thd, &(cond->m_constraint_schema));
|
||||
break;
|
||||
case CONSTRAINT_NAME:
|
||||
value= make_utf8_string_item(thd, &(cond->m_constraint_name));
|
||||
break;
|
||||
case CATALOG_NAME:
|
||||
value= make_utf8_string_item(thd, &(cond->m_catalog_name));
|
||||
break;
|
||||
case SCHEMA_NAME:
|
||||
value= make_utf8_string_item(thd, &(cond->m_schema_name));
|
||||
break;
|
||||
case TABLE_NAME:
|
||||
value= make_utf8_string_item(thd, &(cond->m_table_name));
|
||||
break;
|
||||
case COLUMN_NAME:
|
||||
value= make_utf8_string_item(thd, &(cond->m_column_name));
|
||||
break;
|
||||
case CURSOR_NAME:
|
||||
value= make_utf8_string_item(thd, &(cond->m_cursor_name));
|
||||
break;
|
||||
case MESSAGE_TEXT:
|
||||
value= make_utf8_string_item(thd, &(cond->m_message_text));
|
||||
break;
|
||||
case MYSQL_ERRNO:
|
||||
value= new (thd->mem_root) Item_uint(cond->m_sql_errno);
|
||||
break;
|
||||
case RETURNED_SQLSTATE:
|
||||
str.set_ascii(cond->get_sqlstate(), strlen(cond->get_sqlstate()));
|
||||
value= make_utf8_string_item(thd, &str);
|
||||
break;
|
||||
}
|
||||
|
||||
DBUG_RETURN(value);
|
||||
}
|
||||
|
||||
318
sql/sql_get_diagnostics.h
Normal file
318
sql/sql_get_diagnostics.h
Normal file
|
|
@ -0,0 +1,318 @@
|
|||
/* Copyright (c) 2011, 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
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef SQL_GET_DIAGNOSTICS_H
|
||||
#define SQL_GET_DIAGNOSTICS_H
|
||||
|
||||
/** Diagnostics information forward reference. */
|
||||
class Diagnostics_information;
|
||||
|
||||
|
||||
/**
|
||||
Sql_cmd_get_diagnostics represents a GET DIAGNOSTICS statement.
|
||||
|
||||
The GET DIAGNOSTICS statement retrieves exception or completion
|
||||
condition information from a diagnostics area, usually pertaining
|
||||
to the last non-diagnostic SQL statement that was executed.
|
||||
*/
|
||||
class Sql_cmd_get_diagnostics : public Sql_cmd
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Constructor, used to represent a GET DIAGNOSTICS statement.
|
||||
|
||||
@param info Diagnostics information to be obtained.
|
||||
*/
|
||||
Sql_cmd_get_diagnostics(Diagnostics_information *info)
|
||||
: m_info(info)
|
||||
{}
|
||||
|
||||
virtual enum_sql_command sql_command_code() const
|
||||
{
|
||||
return SQLCOM_GET_DIAGNOSTICS;
|
||||
}
|
||||
|
||||
virtual bool execute(THD *thd);
|
||||
|
||||
private:
|
||||
/** The information to be obtained. */
|
||||
Diagnostics_information *m_info;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Represents the diagnostics information to be obtained.
|
||||
|
||||
Diagnostic information is made available through statement
|
||||
information and condition information items.
|
||||
*/
|
||||
class Diagnostics_information : public Sql_alloc
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Which diagnostics area to access.
|
||||
Only CURRENT is supported for now.
|
||||
*/
|
||||
enum Which_area
|
||||
{
|
||||
/** Access the first diagnostics area. */
|
||||
CURRENT_AREA
|
||||
};
|
||||
|
||||
/** Set which diagnostics area to access. */
|
||||
void set_which_da(Which_area area)
|
||||
{ m_area= area; }
|
||||
|
||||
/** Get which diagnostics area to access. */
|
||||
Which_area get_which_da(void) const
|
||||
{ return m_area; }
|
||||
|
||||
/**
|
||||
Aggregate diagnostics information.
|
||||
|
||||
@param thd The current thread.
|
||||
@param da The diagnostics area.
|
||||
|
||||
@retval false on success.
|
||||
@retval true on error
|
||||
*/
|
||||
virtual bool aggregate(THD *thd, const Diagnostics_area *da) = 0;
|
||||
|
||||
protected:
|
||||
/**
|
||||
Diagnostics_information objects are allocated in thd->mem_root.
|
||||
Do not rely on the destructor for any cleanup.
|
||||
*/
|
||||
virtual ~Diagnostics_information()
|
||||
{
|
||||
DBUG_ASSERT(false);
|
||||
}
|
||||
|
||||
/**
|
||||
Evaluate a diagnostics information item in a specific context.
|
||||
|
||||
@param thd The current thread.
|
||||
@param diag_item The diagnostics information item.
|
||||
@param ctx The context to evaluate the item.
|
||||
|
||||
@retval false on success.
|
||||
@retval true on error.
|
||||
*/
|
||||
template <typename Diag_item, typename Context>
|
||||
bool evaluate(THD *thd, Diag_item *diag_item, Context ctx)
|
||||
{
|
||||
Item *value;
|
||||
|
||||
/* Get this item's value. */
|
||||
if (! (value= diag_item->get_value(thd, ctx)))
|
||||
return true;
|
||||
|
||||
/* Set variable/parameter value. */
|
||||
return diag_item->set_value(thd, &value);
|
||||
}
|
||||
|
||||
private:
|
||||
/** Which diagnostics area to access. */
|
||||
Which_area m_area;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
A diagnostics information item. Used to associate a specific
|
||||
diagnostics information item to a target variable.
|
||||
*/
|
||||
class Diagnostics_information_item : public Sql_alloc
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Set a value for this item.
|
||||
|
||||
@param thd The current thread.
|
||||
@param value The obtained value.
|
||||
|
||||
@retval false on success.
|
||||
@retval true on error.
|
||||
*/
|
||||
bool set_value(THD *thd, Item **value);
|
||||
|
||||
protected:
|
||||
/**
|
||||
Constructor, used to represent a diagnostics information item.
|
||||
|
||||
@param target A target that gets the value of this item.
|
||||
*/
|
||||
Diagnostics_information_item(Item *target)
|
||||
: m_target(target)
|
||||
{}
|
||||
|
||||
/**
|
||||
Diagnostics_information_item objects are allocated in thd->mem_root.
|
||||
Do not rely on the destructor for any cleanup.
|
||||
*/
|
||||
virtual ~Diagnostics_information_item()
|
||||
{
|
||||
DBUG_ASSERT(false);
|
||||
}
|
||||
|
||||
private:
|
||||
/** The target variable that will receive the value of this item. */
|
||||
Item *m_target;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
A statement information item.
|
||||
*/
|
||||
class Statement_information_item : public Diagnostics_information_item
|
||||
{
|
||||
public:
|
||||
/** The name of a statement information item. */
|
||||
enum Name
|
||||
{
|
||||
NUMBER,
|
||||
ROW_COUNT
|
||||
};
|
||||
|
||||
/**
|
||||
Constructor, used to represent a statement information item.
|
||||
|
||||
@param name The name of this item.
|
||||
@param target A target that gets the value of this item.
|
||||
*/
|
||||
Statement_information_item(Name name, Item *target)
|
||||
: Diagnostics_information_item(target), m_name(name)
|
||||
{}
|
||||
|
||||
/** Obtain value of this statement information item. */
|
||||
Item *get_value(THD *thd, const Diagnostics_area *da);
|
||||
|
||||
private:
|
||||
/** The name of this statement information item. */
|
||||
Name m_name;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Statement information.
|
||||
|
||||
@remark Provides information about the execution of a statement.
|
||||
*/
|
||||
class Statement_information : public Diagnostics_information
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Constructor, used to represent the statement information of a
|
||||
GET DIAGNOSTICS statement.
|
||||
|
||||
@param items List of requested statement information items.
|
||||
*/
|
||||
Statement_information(List<Statement_information_item> *items)
|
||||
: m_items(items)
|
||||
{}
|
||||
|
||||
/** Obtain statement information in the context of a diagnostics area. */
|
||||
bool aggregate(THD *thd, const Diagnostics_area *da);
|
||||
|
||||
private:
|
||||
/* List of statement information items. */
|
||||
List<Statement_information_item> *m_items;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
A condition information item.
|
||||
*/
|
||||
class Condition_information_item : public Diagnostics_information_item
|
||||
{
|
||||
public:
|
||||
/**
|
||||
The name of a condition information item.
|
||||
*/
|
||||
enum Name
|
||||
{
|
||||
CLASS_ORIGIN,
|
||||
SUBCLASS_ORIGIN,
|
||||
CONSTRAINT_CATALOG,
|
||||
CONSTRAINT_SCHEMA,
|
||||
CONSTRAINT_NAME,
|
||||
CATALOG_NAME,
|
||||
SCHEMA_NAME,
|
||||
TABLE_NAME,
|
||||
COLUMN_NAME,
|
||||
CURSOR_NAME,
|
||||
MESSAGE_TEXT,
|
||||
MYSQL_ERRNO,
|
||||
RETURNED_SQLSTATE
|
||||
};
|
||||
|
||||
/**
|
||||
Constructor, used to represent a condition information item.
|
||||
|
||||
@param name The name of this item.
|
||||
@param target A target that gets the value of this item.
|
||||
*/
|
||||
Condition_information_item(Name name, Item *target)
|
||||
: Diagnostics_information_item(target), m_name(name)
|
||||
{}
|
||||
|
||||
/** Obtain value of this condition information item. */
|
||||
Item *get_value(THD *thd, const Sql_condition *cond);
|
||||
|
||||
private:
|
||||
/** The name of this condition information item. */
|
||||
Name m_name;
|
||||
|
||||
/** Create an string item to represent a condition item string. */
|
||||
Item *make_utf8_string_item(THD *thd, const String *str);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Condition information.
|
||||
|
||||
@remark Provides information about conditions raised during the
|
||||
execution of a statement.
|
||||
*/
|
||||
class Condition_information : public Diagnostics_information
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Constructor, used to represent the condition information of a
|
||||
GET DIAGNOSTICS statement.
|
||||
|
||||
@param cond_number_expr Number that identifies the diagnostic condition.
|
||||
@param items List of requested condition information items.
|
||||
*/
|
||||
Condition_information(Item *cond_number_expr,
|
||||
List<Condition_information_item> *items)
|
||||
: m_cond_number_expr(cond_number_expr), m_items(items)
|
||||
{}
|
||||
|
||||
/** Obtain condition information in the context of a diagnostics area. */
|
||||
bool aggregate(THD *thd, const Diagnostics_area *da);
|
||||
|
||||
private:
|
||||
/**
|
||||
Number that identifies the diagnostic condition for which
|
||||
information is to be obtained.
|
||||
*/
|
||||
Item *m_cond_number_expr;
|
||||
|
||||
/** List of condition information items. */
|
||||
List<Condition_information_item> *m_items;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -171,7 +171,7 @@ static void mysql_ha_close_table(SQL_HANDLER *handler)
|
|||
|
||||
table->file->ha_index_or_rnd_end();
|
||||
table->open_by_handler= 0;
|
||||
(void) close_thread_table(thd, &table);
|
||||
close_thread_table(thd, &table);
|
||||
thd->mdl_context.release_lock(handler->mdl_request.ticket);
|
||||
}
|
||||
else
|
||||
|
|
@ -501,9 +501,9 @@ public:
|
|||
bool handle_condition(THD *thd,
|
||||
uint sql_errno,
|
||||
const char *sqlstate,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
Sql_condition::enum_warning_level level,
|
||||
const char* msg,
|
||||
MYSQL_ERROR **cond_hdl);
|
||||
Sql_condition **cond_hdl);
|
||||
|
||||
bool need_reopen() const { return m_need_reopen; };
|
||||
void init() { m_need_reopen= FALSE; };
|
||||
|
|
@ -522,9 +522,9 @@ Sql_handler_lock_error_handler::
|
|||
handle_condition(THD *thd,
|
||||
uint sql_errno,
|
||||
const char *sqlstate,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
Sql_condition::enum_warning_level level,
|
||||
const char* msg,
|
||||
MYSQL_ERROR **cond_hdl)
|
||||
Sql_condition **cond_hdl)
|
||||
{
|
||||
*cond_hdl= NULL;
|
||||
if (sql_errno == ER_LOCK_ABORTED)
|
||||
|
|
@ -639,9 +639,10 @@ mysql_ha_fix_cond_and_key(SQL_HANDLER *handler,
|
|||
key_part_map keypart_map;
|
||||
uint key_len;
|
||||
|
||||
if (key_expr->elements > keyinfo->key_parts)
|
||||
if (key_expr->elements > keyinfo->user_defined_key_parts)
|
||||
{
|
||||
my_error(ER_TOO_MANY_KEY_PARTS, MYF(0), keyinfo->key_parts);
|
||||
my_error(ER_TOO_MANY_KEY_PARTS, MYF(0),
|
||||
keyinfo->user_defined_key_parts);
|
||||
return 1;
|
||||
}
|
||||
for (keypart_map= key_len=0 ; (item=it_ke++) ; key_part++)
|
||||
|
|
|
|||
|
|
@ -963,7 +963,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||
error=write_record(thd, table ,&info);
|
||||
if (error)
|
||||
break;
|
||||
thd->warning_info->inc_current_row_for_warning();
|
||||
thd->get_stmt_da()->inc_current_row_for_warning();
|
||||
}
|
||||
|
||||
free_underlaid_joins(thd, &thd->lex->select_lex);
|
||||
|
|
@ -1120,11 +1120,11 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
|
||||
(lock_type == TL_WRITE_DELAYED) ? (ulong) 0 :
|
||||
(ulong) (info.records - info.copied),
|
||||
(ulong) thd->warning_info->statement_warn_count());
|
||||
(long) thd->get_stmt_da()->current_statement_warn_count());
|
||||
else
|
||||
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
|
||||
(ulong) (info.deleted + updated),
|
||||
(ulong) thd->warning_info->statement_warn_count());
|
||||
(long) thd->get_stmt_da()->current_statement_warn_count());
|
||||
::my_ok(thd, info.copied + info.deleted + updated, id, buff);
|
||||
}
|
||||
thd->abort_on_warning= 0;
|
||||
|
|
@ -1209,7 +1209,7 @@ static bool check_view_insertability(THD * thd, TABLE_LIST *view)
|
|||
}
|
||||
Item_field *field;
|
||||
/* simple SELECT list entry (field without expression) */
|
||||
if (!(field= trans->item->filed_for_view_update()))
|
||||
if (!(field= trans->item->field_for_view_update()))
|
||||
{
|
||||
thd->mark_used_columns= save_mark_used_columns;
|
||||
DBUG_RETURN(TRUE);
|
||||
|
|
@ -1645,7 +1645,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
|
|||
}
|
||||
}
|
||||
key_copy((uchar*) key,table->record[0],table->key_info+key_nr,0);
|
||||
key_part_map keypart_map= (1 << table->key_info[key_nr].key_parts) - 1;
|
||||
key_part_map keypart_map= (1 << table->key_info[key_nr].user_defined_key_parts) - 1;
|
||||
if ((error= (table->file->ha_index_read_idx_map(table->record[1],
|
||||
key_nr, (uchar*) key,
|
||||
keypart_map,
|
||||
|
|
@ -1894,7 +1894,7 @@ int check_that_all_fields_are_given_values(THD *thd, TABLE *entry,
|
|||
}
|
||||
if (view)
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_NO_DEFAULT_FOR_VIEW_FIELD,
|
||||
ER(ER_NO_DEFAULT_FOR_VIEW_FIELD),
|
||||
table_list->view_db.str,
|
||||
|
|
@ -1902,7 +1902,7 @@ int check_that_all_fields_are_given_values(THD *thd, TABLE *entry,
|
|||
}
|
||||
else
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_NO_DEFAULT_FOR_FIELD,
|
||||
ER(ER_NO_DEFAULT_FOR_FIELD),
|
||||
(*field)->field_name);
|
||||
|
|
@ -2253,7 +2253,8 @@ bool delayed_get_table(THD *thd, MDL_request *grl_protection_request,
|
|||
want to send "Server shutdown in progress" in the
|
||||
INSERT THREAD.
|
||||
*/
|
||||
my_message(di->thd.stmt_da->sql_errno(), di->thd.stmt_da->message(),
|
||||
my_message(di->thd.get_stmt_da()->sql_errno(),
|
||||
di->thd.get_stmt_da()->message(),
|
||||
MYF(0));
|
||||
}
|
||||
di->unlock();
|
||||
|
|
@ -2343,7 +2344,8 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
|
|||
if (!thd.is_error())
|
||||
my_message(ER_QUERY_INTERRUPTED, ER(ER_QUERY_INTERRUPTED), MYF(0));
|
||||
else
|
||||
my_message(thd.stmt_da->sql_errno(), thd.stmt_da->message(), MYF(0));
|
||||
my_message(thd.get_stmt_da()->sql_errno(),
|
||||
thd.get_stmt_da()->message(), MYF(0));
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
|
@ -2765,8 +2767,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
|
|||
if (my_thread_init())
|
||||
{
|
||||
/* Can't use my_error since store_globals has not yet been called */
|
||||
thd->stmt_da->set_error_status(thd, ER_OUT_OF_RESOURCES,
|
||||
ER(ER_OUT_OF_RESOURCES), NULL);
|
||||
thd->get_stmt_da()->set_error_status(ER_OUT_OF_RESOURCES);
|
||||
di->handler_thread_initialized= TRUE;
|
||||
}
|
||||
else
|
||||
|
|
@ -2776,8 +2777,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
|
|||
if (init_thr_lock() || thd->store_globals())
|
||||
{
|
||||
/* Can't use my_error since store_globals has perhaps failed */
|
||||
thd->stmt_da->set_error_status(thd, ER_OUT_OF_RESOURCES,
|
||||
ER(ER_OUT_OF_RESOURCES), NULL);
|
||||
thd->get_stmt_da()->set_error_status(ER_OUT_OF_RESOURCES);
|
||||
di->handler_thread_initialized= TRUE;
|
||||
thd->fatal_error();
|
||||
goto err;
|
||||
|
|
@ -3167,7 +3167,7 @@ bool Delayed_insert::handle_inserts(void)
|
|||
{
|
||||
/* This should never happen */
|
||||
table->file->print_error(error,MYF(0));
|
||||
sql_print_error("%s", thd.stmt_da->message());
|
||||
sql_print_error("%s", thd.get_stmt_da()->message());
|
||||
DBUG_PRINT("error", ("HA_EXTRA_NO_CACHE failed in loop"));
|
||||
goto err;
|
||||
}
|
||||
|
|
@ -3213,7 +3213,7 @@ bool Delayed_insert::handle_inserts(void)
|
|||
if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))
|
||||
{ // This shouldn't happen
|
||||
table->file->print_error(error,MYF(0));
|
||||
sql_print_error("%s", thd.stmt_da->message());
|
||||
sql_print_error("%s", thd.get_stmt_da()->message());
|
||||
DBUG_PRINT("error", ("HA_EXTRA_NO_CACHE failed after loop"));
|
||||
goto err;
|
||||
}
|
||||
|
|
@ -3644,7 +3644,7 @@ bool select_insert::send_eof()
|
|||
error= (thd->locked_tables_mode <= LTM_LOCK_TABLES ?
|
||||
table->file->ha_end_bulk_insert() : 0);
|
||||
if (!error && thd->is_error())
|
||||
error= thd->stmt_da->sql_errno();
|
||||
error= thd->get_stmt_da()->sql_errno();
|
||||
|
||||
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
|
||||
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
|
||||
|
|
@ -3697,11 +3697,11 @@ bool select_insert::send_eof()
|
|||
if (info.ignore)
|
||||
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
|
||||
(ulong) (info.records - info.copied),
|
||||
(ulong) thd->warning_info->statement_warn_count());
|
||||
(long) thd->get_stmt_da()->current_statement_warn_count());
|
||||
else
|
||||
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
|
||||
(ulong) (info.deleted+info.updated),
|
||||
(ulong) thd->warning_info->statement_warn_count());
|
||||
(long) thd->get_stmt_da()->current_statement_warn_count());
|
||||
row_count= info.copied + info.deleted +
|
||||
((thd->client_capabilities & CLIENT_FOUND_ROWS) ?
|
||||
info.touched : info.updated);
|
||||
|
|
@ -3891,8 +3891,8 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
|
|||
{
|
||||
if (!mysql_create_table_no_lock(thd, create_table->db,
|
||||
create_table->table_name,
|
||||
create_info, alter_info, 0,
|
||||
select_field_count, NULL))
|
||||
create_info, alter_info, NULL,
|
||||
select_field_count))
|
||||
{
|
||||
DEBUG_SYNC(thd,"create_table_select_before_open");
|
||||
|
||||
|
|
@ -3905,7 +3905,7 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
|
|||
*/
|
||||
if (open_table(thd, create_table, thd->mem_root, &ot_ctx))
|
||||
{
|
||||
quick_rm_table(create_info->db_type, create_table->db,
|
||||
quick_rm_table(thd, create_info->db_type, create_table->db,
|
||||
table_case_name(create_info, create_table->table_name),
|
||||
0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -494,12 +494,13 @@ void lex_start(THD *thd)
|
|||
lex->select_lex.ftfunc_list= &lex->select_lex.ftfunc_list_alloc;
|
||||
lex->select_lex.group_list.empty();
|
||||
lex->select_lex.order_list.empty();
|
||||
lex->m_sql_cmd= NULL;
|
||||
lex->duplicates= DUP_ERROR;
|
||||
lex->ignore= 0;
|
||||
lex->spname= NULL;
|
||||
lex->sphead= NULL;
|
||||
lex->spcont= NULL;
|
||||
lex->m_stmt= NULL;
|
||||
lex->m_sql_cmd= NULL;
|
||||
lex->proc_list.first= 0;
|
||||
lex->escape_used= FALSE;
|
||||
lex->query_tables= 0;
|
||||
|
|
@ -1746,50 +1747,6 @@ int lex_one_token(void *arg, void *yythd)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
Construct a copy of this object to be used for mysql_alter_table
|
||||
and mysql_create_table.
|
||||
|
||||
Historically, these two functions modify their Alter_info
|
||||
arguments. This behaviour breaks re-execution of prepared
|
||||
statements and stored procedures and is compensated by always
|
||||
supplying a copy of Alter_info to these functions.
|
||||
|
||||
@return You need to use check the error in THD for out
|
||||
of memory condition after calling this function.
|
||||
*/
|
||||
|
||||
Alter_info::Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root)
|
||||
:drop_list(rhs.drop_list, mem_root),
|
||||
alter_list(rhs.alter_list, mem_root),
|
||||
key_list(rhs.key_list, mem_root),
|
||||
create_list(rhs.create_list, mem_root),
|
||||
flags(rhs.flags),
|
||||
keys_onoff(rhs.keys_onoff),
|
||||
tablespace_op(rhs.tablespace_op),
|
||||
partition_names(rhs.partition_names, mem_root),
|
||||
num_parts(rhs.num_parts),
|
||||
change_level(rhs.change_level),
|
||||
datetime_field(rhs.datetime_field),
|
||||
error_if_not_empty(rhs.error_if_not_empty)
|
||||
{
|
||||
/*
|
||||
Make deep copies of used objects.
|
||||
This is not a fully deep copy - clone() implementations
|
||||
of Alter_drop, Alter_column, Key, foreign_key, Key_part_spec
|
||||
do not copy string constants. At the same length the only
|
||||
reason we make a copy currently is that ALTER/CREATE TABLE
|
||||
code changes input Alter_info definitions, but string
|
||||
constants never change.
|
||||
*/
|
||||
list_copy_and_replace_each_value(drop_list, mem_root);
|
||||
list_copy_and_replace_each_value(alter_list, mem_root);
|
||||
list_copy_and_replace_each_value(key_list, mem_root);
|
||||
list_copy_and_replace_each_value(create_list, mem_root);
|
||||
/* partition_names are not deeply copied currently */
|
||||
}
|
||||
|
||||
|
||||
void trim_whitespace(CHARSET_INFO *cs, LEX_STRING *str)
|
||||
{
|
||||
/*
|
||||
|
|
@ -2195,12 +2152,13 @@ bool st_select_lex_node::inc_in_sum_expr() { return 1; }
|
|||
uint st_select_lex_node::get_in_sum_expr() { return 0; }
|
||||
TABLE_LIST* st_select_lex_node::get_table_list() { return 0; }
|
||||
List<Item>* st_select_lex_node::get_item_list() { return 0; }
|
||||
TABLE_LIST *st_select_lex_node::add_table_to_list (THD *thd, Table_ident *table,
|
||||
TABLE_LIST *st_select_lex_node::add_table_to_list(THD *thd, Table_ident *table,
|
||||
LEX_STRING *alias,
|
||||
ulong table_join_options,
|
||||
thr_lock_type flags,
|
||||
enum_mdl_type mdl_type,
|
||||
List<Index_hint> *hints,
|
||||
List<String> *partition_names,
|
||||
LEX_STRING *option)
|
||||
{
|
||||
return 0;
|
||||
|
|
@ -4299,8 +4257,8 @@ int st_select_lex_unit::print_explain(select_result_sink *output,
|
|||
bool LEX::is_partition_management() const
|
||||
{
|
||||
return (sql_command == SQLCOM_ALTER_TABLE &&
|
||||
(alter_info.flags == ALTER_ADD_PARTITION ||
|
||||
alter_info.flags == ALTER_REORGANIZE_PARTITION));
|
||||
(alter_info.flags == Alter_info::ALTER_ADD_PARTITION ||
|
||||
alter_info.flags == Alter_info::ALTER_REORGANIZE_PARTITION));
|
||||
}
|
||||
|
||||
#ifdef MYSQL_SERVER
|
||||
|
|
|
|||
|
|
@ -44,9 +44,6 @@ class Event_parse_data;
|
|||
class set_var_base;
|
||||
class sys_var;
|
||||
class Item_func_match;
|
||||
class Alter_drop;
|
||||
class Alter_column;
|
||||
class Key;
|
||||
class File_parser;
|
||||
class Key_part_spec;
|
||||
|
||||
|
|
@ -117,6 +114,7 @@ struct sys_var_with_base
|
|||
#include "lex_symbol.h"
|
||||
#if MYSQL_LEX
|
||||
#include "item_func.h" /* Cast_target used in sql_yacc.h */
|
||||
#include "sql_get_diagnostics.h" /* Types used in sql_yacc.h */
|
||||
#include "sql_yacc.h"
|
||||
#define LEX_YYSTYPE YYSTYPE *
|
||||
#else
|
||||
|
|
@ -257,11 +255,6 @@ enum olap_type
|
|||
UNSPECIFIED_OLAP_TYPE, CUBE_TYPE, ROLLUP_TYPE
|
||||
};
|
||||
|
||||
enum tablespace_op_type
|
||||
{
|
||||
NO_TABLESPACE_OP, DISCARD_TABLESPACE, IMPORT_TABLESPACE
|
||||
};
|
||||
|
||||
/*
|
||||
String names used to print a statement with index hints.
|
||||
Keep in sync with index_hint_type.
|
||||
|
|
@ -505,6 +498,7 @@ public:
|
|||
thr_lock_type flags= TL_UNLOCK,
|
||||
enum_mdl_type mdl_type= MDL_SHARED_READ,
|
||||
List<Index_hint> *hints= 0,
|
||||
List<String> *partition_names= 0,
|
||||
LEX_STRING *option= 0);
|
||||
virtual void set_lock_for_tables(thr_lock_type lock_type) {}
|
||||
|
||||
|
|
@ -861,6 +855,7 @@ public:
|
|||
thr_lock_type flags= TL_UNLOCK,
|
||||
enum_mdl_type mdl_type= MDL_SHARED_READ,
|
||||
List<Index_hint> *hints= 0,
|
||||
List<String> *partition_names= 0,
|
||||
LEX_STRING *option= 0);
|
||||
TABLE_LIST* get_table_list();
|
||||
bool init_nested_join(THD *thd);
|
||||
|
|
@ -1074,7 +1069,38 @@ public:
|
|||
Sroutine_hash_entry **sroutines_list_own_last;
|
||||
uint sroutines_list_own_elements;
|
||||
|
||||
/*
|
||||
/**
|
||||
Locking state of tables in this particular statement.
|
||||
|
||||
If we under LOCK TABLES or in prelocked mode we consider tables
|
||||
for the statement to be "locked" if there was a call to lock_tables()
|
||||
(which called handler::start_stmt()) for tables of this statement
|
||||
and there was no matching close_thread_tables() call.
|
||||
|
||||
As result this state may differ significantly from one represented
|
||||
by Open_tables_state::lock/locked_tables_mode more, which are always
|
||||
"on" under LOCK TABLES or in prelocked mode.
|
||||
*/
|
||||
enum enum_lock_tables_state {
|
||||
LTS_NOT_LOCKED = 0,
|
||||
LTS_LOCKED
|
||||
};
|
||||
enum_lock_tables_state lock_tables_state;
|
||||
bool is_query_tables_locked()
|
||||
{
|
||||
return (lock_tables_state == LTS_LOCKED);
|
||||
}
|
||||
|
||||
/**
|
||||
Number of tables which were open by open_tables() and to be locked
|
||||
by lock_tables().
|
||||
Note that we set this member only in some cases, when this value
|
||||
needs to be passed from open_tables() to lock_tables() which are
|
||||
separated by some amount of code.
|
||||
*/
|
||||
uint table_count;
|
||||
|
||||
/*
|
||||
These constructor and destructor serve for creation/destruction
|
||||
of Query_tables_list instances which are used as backup storage.
|
||||
*/
|
||||
|
|
@ -2274,7 +2300,7 @@ struct LEX: public Query_tables_list
|
|||
*/
|
||||
nesting_map allow_sum_func;
|
||||
|
||||
Sql_statement *m_stmt;
|
||||
Sql_cmd *m_sql_cmd;
|
||||
|
||||
/*
|
||||
Usually `expr` rule of yacc is quite reused but some commands better
|
||||
|
|
@ -2331,6 +2357,7 @@ struct LEX: public Query_tables_list
|
|||
uint8 create_view_check;
|
||||
uint8 context_analysis_only;
|
||||
bool drop_if_exists, drop_temporary, local_file, one_shot_set;
|
||||
bool check_exists;
|
||||
bool autocommit;
|
||||
bool verbose, no_write_to_binlog;
|
||||
|
||||
|
|
|
|||
|
|
@ -218,7 +218,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
|||
!field_term->is_ascii() ||
|
||||
!ex->line_term->is_ascii() || !ex->line_start->is_ascii())
|
||||
{
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
WARN_NON_ASCII_SEPARATOR_NOT_IMPLEMENTED,
|
||||
ER(WARN_NON_ASCII_SEPARATOR_NOT_IMPLEMENTED));
|
||||
}
|
||||
|
|
@ -588,7 +588,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
|||
}
|
||||
sprintf(name, ER(ER_LOAD_INFO), (ulong) info.records, (ulong) info.deleted,
|
||||
(ulong) (info.records - info.copied),
|
||||
(ulong) thd->warning_info->statement_warn_count());
|
||||
(long) thd->get_stmt_da()->current_statement_warn_count());
|
||||
|
||||
if (thd->transaction.stmt.modified_non_trans_table)
|
||||
thd->transaction.all.modified_non_trans_table= TRUE;
|
||||
|
|
@ -829,10 +829,10 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||
if (pos == read_info.row_end)
|
||||
{
|
||||
thd->cuted_fields++; /* Not enough fields */
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_TOO_FEW_RECORDS,
|
||||
ER(ER_WARN_TOO_FEW_RECORDS),
|
||||
thd->warning_info->current_row_for_warning());
|
||||
thd->get_stmt_da()->current_row_for_warning());
|
||||
/*
|
||||
Timestamp fields that are NOT NULL are autoupdated if there is no
|
||||
corresponding value in the data file.
|
||||
|
|
@ -859,10 +859,10 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||
if (pos != read_info.row_end)
|
||||
{
|
||||
thd->cuted_fields++; /* To long row */
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_TOO_MANY_RECORDS,
|
||||
ER(ER_WARN_TOO_MANY_RECORDS),
|
||||
thd->warning_info->current_row_for_warning());
|
||||
thd->get_stmt_da()->current_row_for_warning());
|
||||
}
|
||||
|
||||
if (thd->killed ||
|
||||
|
|
@ -895,12 +895,12 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||
if (read_info.line_cuted)
|
||||
{
|
||||
thd->cuted_fields++; /* To long row */
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_TOO_MANY_RECORDS,
|
||||
ER(ER_WARN_TOO_MANY_RECORDS),
|
||||
thd->warning_info->current_row_for_warning());
|
||||
thd->get_stmt_da()->current_row_for_warning());
|
||||
}
|
||||
thd->warning_info->inc_current_row_for_warning();
|
||||
thd->get_stmt_da()->inc_current_row_for_warning();
|
||||
continue_loop:;
|
||||
}
|
||||
DBUG_RETURN(test(read_info.error));
|
||||
|
|
@ -980,7 +980,7 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||
if (field->reset())
|
||||
{
|
||||
my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0), field->field_name,
|
||||
thd->warning_info->current_row_for_warning());
|
||||
thd->get_stmt_da()->current_row_for_warning());
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
field->set_null();
|
||||
|
|
@ -993,7 +993,7 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||
if (field->type() == MYSQL_TYPE_TIMESTAMP)
|
||||
field->set_time();
|
||||
else if (field != table->next_number_field)
|
||||
field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
field->set_warning(Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_NULL_TO_NOTNULL, 1);
|
||||
}
|
||||
/* Do not auto-update this field. */
|
||||
|
|
@ -1059,7 +1059,7 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||
if (field->reset())
|
||||
{
|
||||
my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0),field->field_name,
|
||||
thd->warning_info->current_row_for_warning());
|
||||
thd->get_stmt_da()->current_row_for_warning());
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (!field->maybe_null() && field->type() == FIELD_TYPE_TIMESTAMP)
|
||||
|
|
@ -1072,10 +1072,10 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||
in the end ?)
|
||||
*/
|
||||
thd->cuted_fields++;
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_TOO_FEW_RECORDS,
|
||||
ER(ER_WARN_TOO_FEW_RECORDS),
|
||||
thd->warning_info->current_row_for_warning());
|
||||
thd->get_stmt_da()->current_row_for_warning());
|
||||
}
|
||||
else if (item->type() == Item::STRING_ITEM)
|
||||
{
|
||||
|
|
@ -1119,13 +1119,13 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||
if (read_info.line_cuted)
|
||||
{
|
||||
thd->cuted_fields++; /* To long row */
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_TOO_MANY_RECORDS, ER(ER_WARN_TOO_MANY_RECORDS),
|
||||
thd->warning_info->current_row_for_warning());
|
||||
thd->get_stmt_da()->current_row_for_warning());
|
||||
if (thd->killed)
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
thd->warning_info->inc_current_row_for_warning();
|
||||
thd->get_stmt_da()->inc_current_row_for_warning();
|
||||
continue_loop:;
|
||||
}
|
||||
DBUG_RETURN(test(read_info.error));
|
||||
|
|
@ -1206,7 +1206,7 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||
if (field->type() == FIELD_TYPE_TIMESTAMP)
|
||||
field->set_time();
|
||||
else if (field != table->next_number_field)
|
||||
field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
field->set_warning(Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_NULL_TO_NOTNULL, 1);
|
||||
}
|
||||
/* Do not auto-update this field. */
|
||||
|
|
@ -1259,10 +1259,10 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||
in the end ?)
|
||||
*/
|
||||
thd->cuted_fields++;
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_TOO_FEW_RECORDS,
|
||||
ER(ER_WARN_TOO_FEW_RECORDS),
|
||||
thd->warning_info->current_row_for_warning());
|
||||
thd->get_stmt_da()->current_row_for_warning());
|
||||
}
|
||||
else
|
||||
((Item_user_var_as_out_param *)item)->set_null_value(cs);
|
||||
|
|
@ -1293,7 +1293,7 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||
its default value at the beginning of each loop iteration.
|
||||
*/
|
||||
thd->transaction.stmt.modified_non_trans_table= no_trans_update_stmt;
|
||||
thd->warning_info->inc_current_row_for_warning();
|
||||
thd->get_stmt_da()->inc_current_row_for_warning();
|
||||
continue_loop:;
|
||||
}
|
||||
DBUG_RETURN(test(read_info.error) || thd->is_error());
|
||||
|
|
|
|||
|
|
@ -3422,7 +3422,7 @@ MY_LOCALE *my_locale_by_name(const char *name)
|
|||
if (thd)
|
||||
{
|
||||
// Send a warning to the client
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_DEPRECATED_SYNTAX, ER(ER_WARN_DEPRECATED_SYNTAX),
|
||||
name, locale->name);
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue