summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2013-09-18 13:07:31 +0200
committerSergei Golubchik <sergii@pisem.net>2013-09-18 13:07:31 +0200
commit4ec2e9d7eda78d409d1b017ef4d8928fe9055438 (patch)
tree6c3a74a740d3c1c5f3a7d1f8154d8a791b435b3f /sql
parent1a2a9d74fe1256554eceb09bbc6752a6376df87d (diff)
parent197bdbae4db78ba65f3668803bebd3c4a4509ae5 (diff)
downloadmariadb-git-4ec2e9d7eda78d409d1b017ef4d8928fe9055438.tar.gz
5.5 merge and fixes for compiler/test errors
Diffstat (limited to 'sql')
-rw-r--r--sql/CMakeLists.txt4
-rw-r--r--sql/datadict.cc81
-rw-r--r--sql/debug_sync.cc4
-rw-r--r--sql/field.cc8
-rw-r--r--sql/field.h28
-rw-r--r--sql/ha_partition.cc124
-rw-r--r--sql/ha_partition.h2
-rw-r--r--sql/handler.cc6
-rw-r--r--sql/handler.h18
-rw-r--r--sql/item.cc38
-rw-r--r--sql/item.h4
-rw-r--r--sql/item_cmpfunc.cc237
-rw-r--r--sql/item_cmpfunc.h57
-rw-r--r--sql/item_func.cc239
-rw-r--r--sql/item_func.h129
-rw-r--r--sql/item_subselect.cc9
-rw-r--r--sql/item_timefunc.cc65
-rw-r--r--sql/item_timefunc.h40
-rw-r--r--sql/log_event.cc12
-rw-r--r--sql/log_event.h1
-rw-r--r--sql/mysqld.cc1
-rw-r--r--sql/mysqld.h1
-rw-r--r--sql/opt_range.cc20
-rw-r--r--sql/opt_subselect.cc48
-rw-r--r--sql/opt_subselect.h1
-rw-r--r--sql/opt_table_elimination.cc9
-rw-r--r--sql/partition_info.cc2
-rw-r--r--sql/records.cc10
-rw-r--r--sql/rpl_utility.cc4
-rw-r--r--sql/signal_handler.cc2
-rw-r--r--sql/spatial.cc91
-rw-r--r--sql/spatial.h5
-rw-r--r--sql/sql_acl.cc49
-rw-r--r--sql/sql_audit.cc4
-rw-r--r--sql/sql_audit.h16
-rw-r--r--sql/sql_bitmap.h1
-rw-r--r--sql/sql_class.cc6
-rw-r--r--sql/sql_class.h6
-rw-r--r--sql/sql_cursor.cc2
-rw-r--r--sql/sql_lex.cc15
-rw-r--r--sql/sql_lex.h2
-rw-r--r--sql/sql_load.cc3
-rw-r--r--sql/sql_parse.cc2
-rw-r--r--sql/sql_partition.cc349
-rw-r--r--sql/sql_plugin.cc77
-rw-r--r--sql/sql_plugin_services.h13
-rw-r--r--sql/sql_rename.cc5
-rw-r--r--sql/sql_select.cc640
-rw-r--r--sql/sql_select.h10
-rw-r--r--sql/sql_table.cc24
-rw-r--r--sql/sql_table.h4
-rw-r--r--sql/sql_union.cc6
-rw-r--r--sql/sql_yacc.yy846
-rw-r--r--sql/sys_vars.h13
-rw-r--r--sql/table.cc385
-rw-r--r--sql/table.h17
56 files changed, 2389 insertions, 1406 deletions
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index 36ab121cadf..bdb9081210f 100644
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -106,8 +106,8 @@ ADD_LIBRARY(sql STATIC ${SQL_SOURCE})
ADD_DEPENDENCIES(sql GenServerSource)
DTRACE_INSTRUMENT(sql)
TARGET_LINK_LIBRARIES(sql ${MYSQLD_STATIC_PLUGIN_LIBS}
- mysys dbug strings vio regex
- ${LIBWRAP} ${LIBCRYPT} ${LIBDL}
+ mysys dbug strings vio regex ${LIBJEMALLOC}
+ ${LIBWRAP} ${LIBCRYPT} ${LIBDL} ${CMAKE_THREAD_LIBS_INIT}
${SSL_LIBRARIES})
IF(WIN32)
diff --git a/sql/datadict.cc b/sql/datadict.cc
index 4bc74af7bdb..deeedcd512d 100644
--- a/sql/datadict.cc
+++ b/sql/datadict.cc
@@ -18,6 +18,22 @@
#include "sql_class.h"
#include "sql_table.h"
+static int read_string(File file, uchar**to, size_t length)
+{
+ DBUG_ENTER("read_string");
+
+ my_free(*to);
+ if (!(*to= (uchar*) my_malloc(length+1,MYF(MY_WME))) ||
+ mysql_file_read(file, *to, length, MYF(MY_NABP)))
+ {
+ my_free(*to);
+ *to= 0;
+ DBUG_RETURN(1);
+ }
+ *((char*) *to+length)= '\0'; // C-style safety
+ DBUG_RETURN (0);
+}
+
/**
Check type of .frm if we are not going to parse it.
@@ -36,6 +52,7 @@ frm_type_enum dd_frm_type(THD *thd, char *path, enum legacy_db_type *dbt)
File file;
uchar header[10]; //"TYPE=VIEW\n" it is 10 characters
size_t error;
+ frm_type_enum type= FRMTYPE_ERROR;
DBUG_ENTER("dd_frm_type");
*dbt= DB_TYPE_UNKNOWN;
@@ -43,12 +60,16 @@ frm_type_enum dd_frm_type(THD *thd, char *path, enum legacy_db_type *dbt)
if ((file= mysql_file_open(key_file_frm, path, O_RDONLY | O_SHARE, MYF(0))) < 0)
DBUG_RETURN(FRMTYPE_ERROR);
error= mysql_file_read(file, (uchar*) header, sizeof(header), MYF(MY_NABP));
- mysql_file_close(file, MYF(MY_WME));
if (error)
- DBUG_RETURN(FRMTYPE_ERROR);
+ goto err;
if (!strncmp((char*) header, "TYPE=VIEW\n", sizeof(header)))
- DBUG_RETURN(FRMTYPE_VIEW);
+ {
+ type= FRMTYPE_VIEW;
+ goto err;
+ }
+
+ type= FRMTYPE_TABLE;
/*
This is just a check for DB_TYPE. We'll return default unknown type
@@ -56,17 +77,57 @@ frm_type_enum dd_frm_type(THD *thd, char *path, enum legacy_db_type *dbt)
on return value from this function (default FRMTYPE_TABLE)
*/
if (!is_binary_frm_header(header))
- DBUG_RETURN(FRMTYPE_TABLE);
+ goto err;
- /*
- XXX this is a bug.
- if header[3] is > DB_TYPE_FIRST_DYNAMIC, then the complete
- storage engine name must be read from the frm
- */
*dbt= (enum legacy_db_type) (uint) *(header + 3);
+ if (*dbt >= DB_TYPE_FIRST_DYNAMIC) /* read the true engine name */
+ {
+ MY_STAT state;
+ uchar *frm_image= 0;
+ uint n_length;
+
+ if (mysql_file_fstat(file, &state, MYF(MY_WME)))
+ goto err;
+
+ if (mysql_file_seek(file, 0, SEEK_SET, MYF(MY_WME)))
+ goto err;
+
+ if (read_string(file, &frm_image, state.st_size))
+ goto err;
+
+ if ((n_length= uint4korr(frm_image+55)))
+ {
+ uint record_offset= uint2korr(frm_image+6)+
+ ((uint2korr(frm_image+14) == 0xffff ?
+ uint4korr(frm_image+47) : uint2korr(frm_image+14)));
+ uint reclength= uint2korr(frm_image+16);
+
+ uchar *next_chunk= frm_image + record_offset + reclength;
+ uchar *buff_end= next_chunk + n_length;
+ uint connect_string_length= uint2korr(next_chunk);
+ next_chunk+= connect_string_length + 2;
+ if (next_chunk + 2 < buff_end)
+ {
+ uint str_db_type_length= uint2korr(next_chunk);
+ LEX_STRING name;
+ name.str= (char*) next_chunk + 2;
+ name.length= str_db_type_length;
+ plugin_ref tmp_plugin= ha_resolve_by_name(thd, &name);
+ if (tmp_plugin)
+ *dbt= plugin_data(tmp_plugin, handlerton *)->db_type;
+ else
+ *dbt= DB_TYPE_UNKNOWN;
+ }
+ }
+
+ my_free(frm_image);
+ }
+
/* Probably a table. */
- DBUG_RETURN(FRMTYPE_TABLE);
+err:
+ mysql_file_close(file, MYF(MY_WME));
+ DBUG_RETURN(type);
}
diff --git a/sql/debug_sync.cc b/sql/debug_sync.cc
index 28d1109a0b4..156296972fc 100644
--- a/sql/debug_sync.cc
+++ b/sql/debug_sync.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2010, Oracle and/or its affiliates.
+/* Copyright (c) 2009, 2013, Oracle and/or its affiliates.
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
@@ -1399,7 +1399,7 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action)
if (action->wait_for.length())
{
mysql_mutex_t *old_mutex;
- mysql_cond_t *UNINIT_VAR(old_cond);
+ mysql_cond_t *old_cond= NULL;
int error= 0;
struct timespec abstime;
diff --git a/sql/field.cc b/sql/field.cc
index 13bc0ef9bb7..64d625cc9cd 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1,6 +1,6 @@
/*
- Copyright (c) 2000, 2012, Oracle and/or its affiliates.
- Copyright (c) 2008, 2013, Monty Program Ab
+ Copyright (c) 2000, 2013, Oracle and/or its affiliates.
+ Copyright (c) 2008, 2013, Monty Program Ab.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -7222,7 +7222,7 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
if (!String::needs_conversion(length, cs, field_charset, &dummy_offset))
{
Field_blob::store_length(length);
- bmove(ptr+packlength,(char*) &from,sizeof(char*));
+ bmove(ptr+packlength, &from, sizeof(char*));
return 0;
}
if (tmpstr.copy(from, length, cs))
@@ -7740,7 +7740,7 @@ int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs)
value.copy(from, length, cs);
from= value.ptr();
}
- bmove(ptr + packlength, (char*) &from, sizeof(char*));
+ bmove(ptr + packlength, &from, sizeof(char*));
}
return 0;
diff --git a/sql/field.h b/sql/field.h
index 48d873beb32..d8630e181fb 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -89,6 +89,34 @@ inline uint get_set_pack_length(int elements)
return len > 4 ? 8 : len;
}
+
+static inline enum enum_mysql_timestamp_type
+mysql_type_to_time_type(enum enum_field_types mysql_type)
+{
+ switch(mysql_type) {
+ case MYSQL_TYPE_TIME: return MYSQL_TIMESTAMP_TIME;
+ case MYSQL_TYPE_TIMESTAMP:
+ case MYSQL_TYPE_DATETIME: return MYSQL_TIMESTAMP_DATETIME;
+ case MYSQL_TYPE_NEWDATE:
+ case MYSQL_TYPE_DATE: return MYSQL_TIMESTAMP_DATE;
+ default: return MYSQL_TIMESTAMP_ERROR;
+ }
+}
+
+
+/**
+ Tests if field type is temporal, i.e. represents
+ DATE, TIME, DATETIME or TIMESTAMP types in SQL.
+
+ @param type Field type, as returned by field->type().
+ @retval true If field type is temporal
+ @retval false If field type is not temporal
+*/
+inline bool is_temporal_type(enum_field_types type)
+{
+ return mysql_type_to_time_type(type) != MYSQL_TIMESTAMP_ERROR;
+}
+
/*
Virtual_column_info is the class to contain additional
characteristics that is specific for a virtual/computed
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index f41df69de27..7392264c460 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -69,7 +69,7 @@
#include "debug_sync.h"
static const char *ha_par_ext= ".par";
-
+#define MI_MAX_MSG_BUF MYSQL_ERRMSG_SIZE
/****************************************************************************
MODULE create/delete handler object
****************************************************************************/
@@ -1099,34 +1099,42 @@ int ha_partition::handle_opt_part(THD *thd, HA_CHECK_OPT *check_opt,
/*
- print a message row formatted for ANALYZE/CHECK/OPTIMIZE/REPAIR TABLE
+ print a message row formatted for ANALYZE/CHECK/OPTIMIZE/REPAIR TABLE
(modelled after mi_check_print_msg)
TODO: move this into the handler, or rewrite mysql_admin_table.
*/
-static bool print_admin_msg(THD* thd, const char* msg_type,
+static bool print_admin_msg(THD* thd, uint len,
+ const char* msg_type,
const char* db_name, String &table_name,
const char* op_name, const char *fmt, ...)
- ATTRIBUTE_FORMAT(printf, 6, 7);
-static bool print_admin_msg(THD* thd, const char* msg_type,
+ ATTRIBUTE_FORMAT(printf, 7, 8);
+static bool print_admin_msg(THD* thd, uint len,
+ const char* msg_type,
const char* db_name, String &table_name,
const char* op_name, const char *fmt, ...)
{
va_list args;
Protocol *protocol= thd->protocol;
- uint length, msg_length;
- char msgbuf[MYSQL_ERRMSG_SIZE];
+ uint length;
+ uint msg_length;
char name[SAFE_NAME_LEN*2+2];
+ char *msgbuf;
+ bool error= true;
+ if (!(msgbuf= (char*) my_malloc(len, MYF(0))))
+ return true;
va_start(args, fmt);
- msg_length= my_vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
+ msg_length= my_vsnprintf(msgbuf, len, fmt, args);
va_end(args);
- msgbuf[sizeof(msgbuf) - 1] = 0; // healthy paranoia
+ if (msg_length >= (len - 1))
+ goto err;
+ msgbuf[len - 1] = 0; // healthy paranoia
if (!thd->vio_ok())
{
- sql_print_error(fmt, args);
- return TRUE;
+ sql_print_error("%s", msgbuf);
+ goto err;
}
length=(uint) (strxmov(name, db_name, ".", table_name.c_ptr_safe(), NullS) - name);
@@ -1149,9 +1157,12 @@ static bool print_admin_msg(THD* thd, const char* msg_type,
{
sql_print_error("Failed on my_net_write, writing to stderr instead: %s\n",
msgbuf);
- return TRUE;
+ goto err;
}
- return FALSE;
+ error= false;
+err:
+ my_free(msgbuf);
+ return error;
}
@@ -1208,7 +1219,8 @@ int ha_partition::handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt,
error != HA_ADMIN_ALREADY_DONE &&
error != HA_ADMIN_TRY_ALTER)
{
- print_admin_msg(thd, "error", table_share->db.str, table->alias,
+ print_admin_msg(thd, MI_MAX_MSG_BUF, "error",
+ table_share->db.str, table->alias,
opt_op_name[flag],
"Subpartition %s returned error",
sub_elem->partition_name);
@@ -1234,8 +1246,9 @@ int ha_partition::handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt,
error != HA_ADMIN_ALREADY_DONE &&
error != HA_ADMIN_TRY_ALTER)
{
- print_admin_msg(thd, "error", table_share->db.str, table->alias,
- opt_op_name[flag], "Partition %s returned error",
+ print_admin_msg(thd, MI_MAX_MSG_BUF, "error",
+ table_share->db.str, table->alias,
+ opt_op_name[flag], "Partition %s returned error",
part_elem->partition_name);
}
/* reset part_state for the remaining partitions */
@@ -1944,15 +1957,15 @@ char *ha_partition::update_table_comment(const char *comment)
names of the partitions and the underlying storage engines.
*/
-uint ha_partition::del_ren_cre_table(const char *from,
+int ha_partition::del_ren_cre_table(const char *from,
const char *to,
TABLE *table_arg,
HA_CREATE_INFO *create_info)
{
int save_error= 0;
- int error;
+ int error= HA_ERR_INTERNAL_ERROR;
char from_buff[FN_REFLEN], to_buff[FN_REFLEN], from_lc_buff[FN_REFLEN],
- to_lc_buff[FN_REFLEN];
+ to_lc_buff[FN_REFLEN], buff[FN_REFLEN];
char *name_buffer_ptr;
const char *from_path;
const char *to_path= NULL;
@@ -1964,24 +1977,28 @@ uint ha_partition::del_ren_cre_table(const char *from,
if (create_info && create_info->options & HA_LEX_CREATE_TMP_TABLE)
{
my_error(ER_PARTITION_NO_TEMPORARY, MYF(0));
- DBUG_RETURN(TRUE);
+ DBUG_RETURN(error);
+ }
+
+ fn_format(buff,from, "", ha_par_ext, MY_APPEND_EXT);
+ /* Check if the par file exists */
+ if (my_access(buff,F_OK))
+ {
+ /*
+ If the .par file does not exist, return HA_ERR_NO_SUCH_TABLE,
+ This will signal to the caller that it can remove the .frm
+ file.
+ */
+ error= HA_ERR_NO_SUCH_TABLE;
+ DBUG_RETURN(error);
}
if (get_from_handler_file(from, ha_thd()->mem_root, false))
- DBUG_RETURN(TRUE);
+ DBUG_RETURN(error);
DBUG_ASSERT(m_file_buffer);
DBUG_PRINT("enter", ("from: (%s) to: (%s)", from, to ? to : "(nil)"));
name_buffer_ptr= m_name_buffer_ptr;
file= m_file;
- if (to == NULL && table_arg == NULL)
- {
- /*
- Delete table, start by delete the .par file. If error, break, otherwise
- delete as much as possible.
- */
- if ((error= handler::delete_table(from)))
- DBUG_RETURN(error);
- }
/*
Since ha_partition has HA_FILE_BASED, it must alter underlying table names
if they do not have HA_FILE_BASED and lower_case_table_names == 2.
@@ -2022,6 +2039,18 @@ uint ha_partition::del_ren_cre_table(const char *from,
save_error= error;
i++;
} while (*(++file));
+
+ if (to == NULL && table_arg == NULL)
+ {
+ DBUG_EXECUTE_IF("crash_before_deleting_par_file", DBUG_SUICIDE(););
+
+ /* Delete the .par file. If error, break.*/
+ if ((error= handler::delete_table(from)))
+ DBUG_RETURN(error);
+
+ DBUG_EXECUTE_IF("crash_after_deleting_par_file", DBUG_SUICIDE(););
+ }
+
if (to != NULL)
{
if ((error= handler::rename_table(from, to)))
@@ -7908,7 +7937,8 @@ int ha_partition::check_misplaced_rows(uint read_part_id, bool repair)
if (num_misplaced_rows > 0)
{
- print_admin_msg(ha_thd(), "warning", table_share->db.str, table->alias,
+ print_admin_msg(ha_thd(), MI_MAX_MSG_BUF, "warning",
+ table_share->db.str, table->alias,
opt_op_name[REPAIR_PARTS],
"Moved %lld misplaced rows",
num_misplaced_rows);
@@ -7929,7 +7959,8 @@ int ha_partition::check_misplaced_rows(uint read_part_id, bool repair)
if (!repair)
{
/* Check. */
- print_admin_msg(ha_thd(), "error", table_share->db.str, table->alias,
+ print_admin_msg(ha_thd(), MI_MAX_MSG_BUF, "error",
+ table_share->db.str, table->alias,
opt_op_name[CHECK_PARTS],
"Found a misplaced row");
/* Break on first misplaced row! */
@@ -7976,7 +8007,8 @@ int ha_partition::check_misplaced_rows(uint read_part_id, bool repair)
correct_part_id,
str.c_ptr_safe());
}
- print_admin_msg(ha_thd(), "error", table_share->db.str, table->alias,
+ print_admin_msg(ha_thd(), MI_MAX_MSG_BUF, "error",
+ table_share->db.str, table->alias,
opt_op_name[REPAIR_PARTS],
"Failed to move/insert a row"
" from part %d into part %d:\n%s",
@@ -8107,12 +8139,18 @@ int ha_partition::check_for_upgrade(HA_CHECK_OPT *check_opt)
NULL,
NULL,
NULL)) ||
- /* Also check that the length is smaller than the output field! */
- (part_buf_len + db_name.length() + table_name.length()) >=
- (SQL_ADMIN_MSG_TEXT_SIZE -
- (strlen(KEY_PARTITIONING_CHANGED_STR) - 3)))
- {
- print_admin_msg(thd, "error", table_share->db.str, table->alias,
+ print_admin_msg(thd, SQL_ADMIN_MSG_TEXT_SIZE + 1, "error",
+ table_share->db.str,
+ table->alias,
+ opt_op_name[CHECK_PARTS],
+ KEY_PARTITIONING_CHANGED_STR,
+ db_name.c_ptr_safe(),
+ table_name.c_ptr_safe(),
+ part_buf))
+ {
+ /* Error creating admin message (too long string?). */
+ print_admin_msg(thd, MI_MAX_MSG_BUF, "error",
+ table_share->db.str, table->alias,
opt_op_name[CHECK_PARTS],
KEY_PARTITIONING_CHANGED_STR,
db_name.c_ptr_safe(), table_name.c_ptr_safe(),
@@ -8120,14 +8158,6 @@ int ha_partition::check_for_upgrade(HA_CHECK_OPT *check_opt)
" between 'KEY' and '(' to change the metadata"
" without the need of a full table rebuild.");
}
- else
- {
- print_admin_msg(thd, "error", table_share->db.str, table->alias,
- opt_op_name[CHECK_PARTS],
- KEY_PARTITIONING_CHANGED_STR,
- db_name.c_ptr_safe(), table_name.c_ptr_safe(),
- part_buf);
- }
m_part_info->key_algorithm= old_algorithm;
DBUG_RETURN(error);
}
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index dce59ee9f2d..56993ae5f32 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -273,7 +273,7 @@ private:
delete_table, rename_table and create uses very similar logic which
is packed into this routine.
*/
- uint del_ren_cre_table(const char *from, const char *to,
+ int del_ren_cre_table(const char *from, const char *to,
TABLE *table_arg, HA_CREATE_INFO *create_info);
/*
One method to create the table_name.par file containing the names of the
diff --git a/sql/handler.cc b/sql/handler.cc
index dcfec241989..01375fa56da 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -528,6 +528,12 @@ int ha_initialize_handlerton(st_plugin_int *plugin)
{
uint tmp;
ulong fslot;
+
+ DBUG_EXECUTE_IF("unstable_db_type", {
+ static int i= (int) DB_TYPE_FIRST_DYNAMIC;
+ hton->db_type= (enum legacy_db_type)++i;
+ });
+
/* now check the db_type for conflict */
if (hton->db_type <= DB_TYPE_UNKNOWN ||
hton->db_type >= DB_TYPE_DEFAULT ||
diff --git a/sql/handler.h b/sql/handler.h
index 7c6f182bb97..4354569e7d0 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -355,7 +355,8 @@ enum legacy_db_type
DB_TYPE_PBXT=23,
DB_TYPE_PERFORMANCE_SCHEMA=28,
DB_TYPE_ARIA=42,
- DB_TYPE_FIRST_DYNAMIC=43,
+ DB_TYPE_TOKUDB=43,
+ DB_TYPE_FIRST_DYNAMIC=44,
DB_TYPE_DEFAULT=127 // Must be last
};
/*
@@ -767,8 +768,8 @@ enum ha_option_type { HA_OPTION_TYPE_ULL, /* unsigned long long */
HA_xOPTION_STRING(name, ha_index_option_struct, field)
#define HA_IOPTION_ENUM(name, field, values, def) \
HA_xOPTION_ENUM(name, ha_index_option_struct, field, values, def)
-#define HA_IOPTION_BOOL(name, field, values, def) \
- HA_xOPTION_BOOL(name, ha_index_option_struct, field, values, def)
+#define HA_IOPTION_BOOL(name, field, def) \
+ HA_xOPTION_BOOL(name, ha_index_option_struct, field, def)
#define HA_IOPTION_SYSVAR(name, field, sysvar) \
HA_xOPTION_SYSVAR(name, ha_index_option_struct, field, sysvar)
#define HA_IOPTION_END HA_xOPTION_END
@@ -1231,6 +1232,7 @@ static inline sys_var *find_hton_sysvar(handlerton *hton, st_mysql_sys_var *var)
#define HTON_TEMPORARY_NOT_SUPPORTED (1 << 6) //Having temporary tables not supported
#define HTON_SUPPORT_LOG_TABLES (1 << 7) //Engine supports log tables
#define HTON_NO_PARTITION (1 << 8) //You can not partition these tables
+#define HTON_EXTENDED_KEYS (1 << 9) //supports extended keys
class Ha_trx_info;
@@ -2024,6 +2026,16 @@ public:
}
/* This is called after index_init() if we need to do a index scan */
virtual int prepare_index_scan() { return 0; }
+ virtual int prepare_index_key_scan_map(const uchar * key, key_part_map keypart_map)
+ {
+ uint key_len= calculate_key_len(table, active_index, key, keypart_map);
+ return prepare_index_key_scan(key, key_len);
+ }
+ virtual int prepare_index_key_scan( const uchar * key, uint key_len )
+ { return 0; }
+ virtual int prepare_range_scan(const key_range *start_key, const key_range *end_key)
+ { return 0; }
+
int ha_rnd_init(bool scan) __attribute__ ((warn_unused_result))
{
DBUG_EXECUTE_IF("ha_rnd_init_fail", return HA_ERR_TABLE_DEF_CHANGED;);
diff --git a/sql/item.cc b/sql/item.cc
index d99f5ff46ea..1caa924f753 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -537,6 +537,44 @@ uint Item::decimal_precision() const
}
+#if MARIADB_VERSION_ID < 1000000
+static uint ms_to_precision(uint ms)
+{
+ uint cut, precision;
+ for (cut= 10, precision= 6 ; precision > 0 ; cut*= 10, precision--)
+ {
+ if (ms % cut)
+ return precision;
+ }
+ return 0;
+}
+#else
+#error Change the code to use MYSQL_TIME_STATUS::precision instead.
+#endif
+
+
+uint Item::temporal_precision(enum_field_types type)
+{
+ if (const_item() && result_type() == STRING_RESULT &&
+ !is_temporal_type(field_type()))
+ {
+ MYSQL_TIME ltime;
+ String buf, *tmp;
+ int was_cut;
+ DBUG_ASSERT(fixed);
+ if ((tmp= val_str(&buf)) &&
+ (type == MYSQL_TYPE_TIME ?
+ str_to_time(tmp->charset(), tmp->ptr(), tmp->length(),
+ &ltime, TIME_TIME_ONLY, &was_cut) :
+ str_to_datetime(tmp->charset(), tmp->ptr(), tmp->length(),
+ &ltime, TIME_FUZZY_DATES, &was_cut)) >
+ MYSQL_TIMESTAMP_ERROR)
+ return min(ms_to_precision(ltime.second_part), TIME_SECOND_PART_DIGITS);
+ }
+ return min(decimals, TIME_SECOND_PART_DIGITS);
+}
+
+
void Item::print_item_w_name(String *str, enum_query_type query_type)
{
print(str, query_type);
diff --git a/sql/item.h b/sql/item.h
index 893d3d30820..9b38f4b8bec 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1019,6 +1019,10 @@ public:
virtual uint decimal_precision() const;
inline int decimal_int_part() const
{ return my_decimal_int_part(decimal_precision(), decimals); }
+ /**
+ TIME or DATETIME precision of the item: 0..6
+ */
+ uint temporal_precision(enum_field_types type);
/*
Returns true if this is constant (during query execution, i.e. its value
will not change until next fix_fields) and its value is known.
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 706b47618da..ffbe06e6c8f 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -2416,12 +2416,13 @@ void
Item_func_ifnull::fix_length_and_dec()
{
uint32 char_length;
- agg_result_type(&hybrid_type, args, 2);
+ agg_result_type(&cached_result_type, args, 2);
+ cached_field_type= agg_field_type(args, 2);
maybe_null=args[1]->maybe_null;
decimals= max(args[0]->decimals, args[1]->decimals);
unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag;
- if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT)
+ if (cached_result_type == DECIMAL_RESULT || cached_result_type == INT_RESULT)
{
int len0= args[0]->max_char_length() - args[0]->decimals
- (args[0]->unsigned_flag ? 0 : 1);
@@ -2434,9 +2435,9 @@ Item_func_ifnull::fix_length_and_dec()
else
char_length= max(args[0]->max_char_length(), args[1]->max_char_length());
- switch (hybrid_type) {
+ switch (cached_result_type) {
case STRING_RESULT:
- if (agg_arg_charsets_for_comparison(collation, args, arg_count))
+ if (count_string_result_length(cached_field_type, args, arg_count))
return;
break;
case DECIMAL_RESULT:
@@ -2451,7 +2452,6 @@ Item_func_ifnull::fix_length_and_dec()
DBUG_ASSERT(0);
}
fix_char_length(char_length);
- cached_field_type= agg_field_type(args, 2);
}
@@ -2465,11 +2465,6 @@ uint Item_func_ifnull::decimal_precision() const
}
-enum_field_types Item_func_ifnull::field_type() const
-{
- return cached_field_type;
-}
-
Field *Item_func_ifnull::tmp_table_field(TABLE *table)
{
return tmp_table_field_from_field_type(table, 0);
@@ -2543,6 +2538,18 @@ Item_func_ifnull::str_op(String *str)
}
+bool Item_func_ifnull::date_op(MYSQL_TIME *ltime, uint fuzzydate)
+{
+ DBUG_ASSERT(fixed == 1);
+ if (!args[0]->get_date(ltime, fuzzydate & ~TIME_FUZZY_DATES))
+ return (null_value= false);
+ if (!args[1]->get_date(ltime, fuzzydate & ~TIME_FUZZY_DATES))
+ return (null_value= false);
+ bzero((char*) ltime,sizeof(*ltime));
+ return null_value= !(fuzzydate & TIME_FUZZY_DATES);
+}
+
+
/**
Perform context analysis of an IF item tree.
@@ -2637,20 +2644,20 @@ Item_func_if::fix_length_and_dec()
}
agg_result_type(&cached_result_type, args + 1, 2);
+ cached_field_type= agg_field_type(args + 1, 2);
maybe_null= args[1]->maybe_null || args[2]->maybe_null;
decimals= max(args[1]->decimals, args[2]->decimals);
unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag;
if (cached_result_type == STRING_RESULT)
{
- if (agg_arg_charsets_for_string_result(collation, args + 1, 2))
- return;
+ count_string_result_length(cached_field_type, args + 1, 2);
+ return;
}
else
{
collation.set_numeric(); // Number
}
- cached_field_type= agg_field_type(args + 1, 2);
uint32 char_length;
if ((cached_result_type == DECIMAL_RESULT )
@@ -2680,7 +2687,7 @@ uint Item_func_if::decimal_precision() const
double
-Item_func_if::val_real()
+Item_func_if::real_op()
{
DBUG_ASSERT(fixed == 1);
Item *arg= args[0]->val_bool() ? args[1] : args[2];
@@ -2690,7 +2697,7 @@ Item_func_if::val_real()
}
longlong
-Item_func_if::val_int()
+Item_func_if::int_op()
{
DBUG_ASSERT(fixed == 1);
Item *arg= args[0]->val_bool() ? args[1] : args[2];
@@ -2700,7 +2707,7 @@ Item_func_if::val_int()
}
String *
-Item_func_if::val_str(String *str)
+Item_func_if::str_op(String *str)
{
DBUG_ASSERT(fixed == 1);
Item *arg= args[0]->val_bool() ? args[1] : args[2];
@@ -2713,7 +2720,7 @@ Item_func_if::val_str(String *str)
my_decimal *
-Item_func_if::val_decimal(my_decimal *decimal_value)
+Item_func_if::decimal_op(my_decimal *decimal_value)
{
DBUG_ASSERT(fixed == 1);
Item *arg= args[0]->val_bool() ? args[1] : args[2];
@@ -2723,6 +2730,14 @@ Item_func_if::val_decimal(my_decimal *decimal_value)
}
+bool Item_func_if::date_op(MYSQL_TIME *ltime, uint fuzzydate)
+{
+ DBUG_ASSERT(fixed == 1);
+ Item *arg= args[0]->val_bool() ? args[1] : args[2];
+ return (null_value= arg->get_date(ltime, fuzzydate));
+}
+
+
void
Item_func_nullif::fix_length_and_dec()
{
@@ -2881,7 +2896,7 @@ Item *Item_func_case::find_item(String *str)
}
-String *Item_func_case::val_str(String *str)
+String *Item_func_case::str_op(String *str)
{
DBUG_ASSERT(fixed == 1);
String *res;
@@ -2899,7 +2914,7 @@ String *Item_func_case::val_str(String *str)
}
-longlong Item_func_case::val_int()
+longlong Item_func_case::int_op()
{
DBUG_ASSERT(fixed == 1);
char buff[MAX_FIELD_WIDTH];
@@ -2917,7 +2932,7 @@ longlong Item_func_case::val_int()
return res;
}
-double Item_func_case::val_real()
+double Item_func_case::real_op()
{
DBUG_ASSERT(fixed == 1);
char buff[MAX_FIELD_WIDTH];
@@ -2936,7 +2951,7 @@ double Item_func_case::val_real()
}
-my_decimal *Item_func_case::val_decimal(my_decimal *decimal_value)
+my_decimal *Item_func_case::decimal_op(my_decimal *decimal_value)
{
DBUG_ASSERT(fixed == 1);
char buff[MAX_FIELD_WIDTH];
@@ -2956,6 +2971,18 @@ my_decimal *Item_func_case::val_decimal(my_decimal *decimal_value)
}
+bool Item_func_case::date_op(MYSQL_TIME *ltime, uint fuzzydate)
+{
+ DBUG_ASSERT(fixed == 1);
+ char buff[MAX_FIELD_WIDTH];
+ String dummy_str(buff, sizeof(buff), default_charset());
+ Item *item= find_item(&dummy_str);
+ if (!item)
+ return (null_value= true);
+ return (null_value= item->get_date(ltime, fuzzydate));
+}
+
+
bool Item_func_case::fix_fields(THD *thd, Item **ref)
{
/*
@@ -3023,7 +3050,10 @@ void Item_func_case::fix_length_and_dec()
if (!(agg= (Item**) sql_alloc(sizeof(Item*)*(ncases+1))))
return;
-
+
+ if (else_expr_num == -1 || args[else_expr_num]->maybe_null)
+ maybe_null= 1;
+
/*
Aggregate all THEN and ELSE expression types
and collations when string result
@@ -3036,9 +3066,11 @@ void Item_func_case::fix_length_and_dec()
agg[nagg++]= args[else_expr_num];
agg_result_type(&cached_result_type, agg, nagg);
+ cached_field_type= agg_field_type(agg, nagg);
+
if (cached_result_type == STRING_RESULT)
{
- if (agg_arg_charsets_for_string_result(collation, agg, nagg))
+ if (count_string_result_length(cached_field_type, agg, nagg))
return;
/*
Copy all THEN and ELSE items back to args[] array.
@@ -3051,11 +3083,22 @@ void Item_func_case::fix_length_and_dec()
change_item_tree_if_needed(thd, &args[else_expr_num], agg[nagg++]);
}
else
+ {
collation.set_numeric();
+ max_length=0;
+ decimals=0;
+ unsigned_flag= TRUE;
+ for (uint i= 0; i < ncases; i+= 2)
+ agg_num_lengths(args[i + 1]);
+ if (else_expr_num != -1)
+ agg_num_lengths(args[else_expr_num]);
+ max_length= my_decimal_precision_to_length_no_truncation(max_length +
+ decimals, decimals,
+ unsigned_flag);
+ }
- cached_field_type= agg_field_type(agg, nagg);
/*
- Aggregate first expression and all THEN expression types
+ Aggregate first expression and all WHEN expression types
and collations when string comparison
*/
if (first_expr_num != -1)
@@ -3141,30 +3184,6 @@ void Item_func_case::fix_length_and_dec()
args[i]->cmp_context= item_cmp_type(left_result_type,
args[i]->result_type());
}
-
- if (else_expr_num == -1 || args[else_expr_num]->maybe_null)
- maybe_null=1;
-
- max_length=0;
- decimals=0;
- unsigned_flag= TRUE;
- if (cached_result_type == STRING_RESULT)
- {
- for (uint i= 0; i < ncases; i+= 2)
- agg_str_lengths(args[i + 1]);
- if (else_expr_num != -1)
- agg_str_lengths(args[else_expr_num]);
- }
- else
- {
- for (uint i= 0; i < ncases; i+= 2)
- agg_num_lengths(args[i + 1]);
- if (else_expr_num != -1)
- agg_num_lengths(args[else_expr_num]);
- max_length= my_decimal_precision_to_length_no_truncation(max_length +
- decimals, decimals,
- unsigned_flag);
- }
}
@@ -3272,18 +3291,18 @@ double Item_func_coalesce::real_op()
}
-bool Item_func_coalesce::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate)
+bool Item_func_coalesce::date_op(MYSQL_TIME *ltime,uint fuzzydate)
{
DBUG_ASSERT(fixed == 1);
null_value= 0;
for (uint i= 0; i < arg_count; i++)
{
- bool res= args[i]->get_date(ltime, fuzzydate);
+ bool res= args[i]->get_date(ltime, fuzzydate & ~TIME_FUZZY_DATES);
if (!args[i]->null_value)
return res;
}
- null_value=1;
- return 1;
+ bzero((char*) ltime,sizeof(*ltime));
+ return null_value|= !(fuzzydate & TIME_FUZZY_DATES);
}
@@ -3305,21 +3324,11 @@ my_decimal *Item_func_coalesce::decimal_op(my_decimal *decimal_value)
void Item_func_coalesce::fix_length_and_dec()
{
cached_field_type= agg_field_type(args, arg_count);
- agg_result_type(&hybrid_type, args, arg_count);
- Item_result cmp_type;
- agg_cmp_type(&cmp_type, args, arg_count);
- ///< @todo let result_type() return TIME_RESULT and remove this special case
- if (cmp_type == TIME_RESULT)
- {
- count_real_length();
- return;
- }
- switch (hybrid_type) {
+ agg_result_type(&cached_result_type, args, arg_count);
+ switch (cached_result_type) {
case STRING_RESULT:
- decimals= NOT_FIXED_DEC;
- if (agg_arg_charsets_for_string_result(collation, args, arg_count))
- return;
- count_only_length();
+ if (count_string_result_length(cached_field_type, args, arg_count))
+ return;
break;
case DECIMAL_RESULT:
count_decimal_length();
@@ -3328,7 +3337,7 @@ void Item_func_coalesce::fix_length_and_dec()
count_real_length();
break;
case INT_RESULT:
- count_only_length();
+ count_only_length(args, arg_count);
decimals= 0;
break;
case ROW_RESULT:
@@ -4342,7 +4351,8 @@ Item_cond::fix_fields(THD *thd, Item **ref)
used_tables_cache|= item->used_tables();
if (item->const_item())
{
- if (!item->is_expensive() && item->val_int() == 0)
+ if (!item->is_expensive() && !cond_has_datetime_is_null(item) &&
+ item->val_int() == 0)
{
/*
This is "... OR false_cond OR ..."
@@ -4354,27 +4364,18 @@ Item_cond::fix_fields(THD *thd, Item **ref)
/*
This is "... OR const_cond OR ..."
In this case, cond_or->not_null_tables()=0, because the condition
- some_cond_or might be true regardless of what tables are
- NULL-complemented.
+ const_cond might evaluate to true (regardless of whether some tables
+ were NULL-complemented).
*/
and_tables_cache= (table_map) 0;
}
}
else
{
- /*
- If an item is a
- - constant
- - inexpensive
- - its value is 0
- then we don't need to account it in not_null_tables_cache
- */
- //if (!(item->const_item() && !item->is_expensive() ))
- {
- table_map tmp_table_map= item->not_null_tables();
- not_null_tables_cache|= tmp_table_map;
- and_tables_cache&= tmp_table_map;
- }
+ table_map tmp_table_map= item->not_null_tables();
+ not_null_tables_cache|= tmp_table_map;
+ and_tables_cache&= tmp_table_map;
+
const_item_cache= FALSE;
}
@@ -4403,7 +4404,8 @@ Item_cond::eval_not_null_tables(uchar *opt_arg)
table_map tmp_table_map;
if (item->const_item())
{
- if (!item->is_expensive() && item->val_int() == 0)
+ if (!item->is_expensive() && !cond_has_datetime_is_null(item) &&
+ item->val_int() == 0)
{
/*
This is "... OR false_cond OR ..."
@@ -4798,6 +4800,8 @@ Item *and_expressions(Item *a, Item *b, Item **org_item)
longlong Item_func_isnull::val_int()
{
DBUG_ASSERT(fixed == 1);
+ if (const_item() && !args[0]->maybe_null)
+ return 0;
return args[0]->is_null() ? 1: 0;
}
@@ -4805,6 +4809,8 @@ longlong Item_is_not_null_test::val_int()
{
DBUG_ASSERT(fixed == 1);
DBUG_ENTER("Item_is_not_null_test::val_int");
+ if (const_item() && !args[0]->maybe_null)
+ DBUG_RETURN(1);
if (args[0]->is_null())
{
DBUG_PRINT("info", ("null"));
@@ -5814,10 +5820,12 @@ void Item_equal::merge(Item_equal *item)
@brief
Merge members of another Item_equal object into this one
- @param item multiple equality whose members are to be merged
+ @param item multiple equality whose members are to be merged
+ @param save_merged keep the list of equalities in 'item' intact
+ (e.g. for other merges)
@details
- If the Item_equal 'item' happened to have some elements of the list
+ If the Item_equal 'item' happens to have some elements of the list
of equal items belonging to 'this' object then the function merges
the equal items from 'item' into this list.
If both lists contains constants and they are different then
@@ -5832,24 +5840,45 @@ void Item_equal::merge(Item_equal *item)
The method 'merge' just joins the list of equal items belonging to 'item'
to the list of equal items belonging to this object assuming that the lists
are disjoint. It would be more correct to call the method 'join'.
- The method 'merge_with_check' really merges two lists of equal items if they
- have common members.
+ The method 'merge_into_with_check' really merges two lists of equal items if
+ they have common members.
*/
-bool Item_equal::merge_with_check(Item_equal *item)
+bool Item_equal::merge_with_check(Item_equal *item, bool save_merged)
{
bool intersected= FALSE;
- Item_equal_fields_iterator_slow fi(*this);
+ Item_equal_fields_iterator_slow fi(*item);
+
while (fi++)
{
- if (item->contains(fi.get_curr_field()))
+ if (contains(fi.get_curr_field()))
{
- fi.remove();
intersected= TRUE;
+ if (!save_merged)
+ fi.remove();
}
}
if (intersected)
- item->merge(this);
+ {
+ if (!save_merged)
+ merge(item);
+ else
+ {
+ Item *c= item->get_const();
+ if (c)
+ add_const(c);
+ if (!cond_false)
+ {
+ Item *item;
+ fi.rewind();
+ while ((item= fi++))
+ {
+ if (!contains(fi.get_curr_field()))
+ add(item);
+ }
+ }
+ }
+ }
return intersected;
}
@@ -5858,17 +5887,25 @@ bool Item_equal::merge_with_check(Item_equal *item)
@brief
Merge this object into a list of Item_equal objects
- @param list the list of Item_equal objects to merge into
+ @param list the list of Item_equal objects to merge into
+ @param save_merged keep the list of equalities in 'this' intact
+ (e.g. for other merges)
+ @param only_intersected do not merge if there are no common members
+ in any of Item_equal objects from the list
+ and this Item_equal
@details
If the list of equal items from 'this' object contains common members
with the lists of equal items belonging to Item_equal objects from 'list'
then all involved Item_equal objects e1,...,ek are merged into one
- Item equal that replaces e1,...,ek in the 'list'. Otherwise this
+ Item equal that replaces e1,...,ek in the 'list'. Otherwise, in the case
+ when the value of the parameter only_if_intersected is false, this
Item_equal is joined to the 'list'.
*/
-void Item_equal::merge_into_list(List<Item_equal> *list)
+void Item_equal::merge_into_list(List<Item_equal> *list,
+ bool save_merged,
+ bool only_intersected)
{
Item_equal *item;
List_iterator<Item_equal> it(*list);
@@ -5877,16 +5914,16 @@ void Item_equal::merge_into_list(List<Item_equal> *list)
{
if (!merge_into)
{
- if (merge_with_check(item))
+ if (item->merge_with_check(this, save_merged))
merge_into= item;
}
else
{
- if (item->merge_with_check(merge_into))
+ if (merge_into->merge_with_check(item, false))
it.remove();
}
}
- if (!merge_into)
+ if (!only_intersected && !merge_into)
list->push_back(this);
}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index bf65d6e7c07..4901b146b39 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -737,24 +737,19 @@ public:
};
-class Item_func_coalesce :public Item_func_numhybrid
+class Item_func_coalesce :public Item_func_hybrid_field_type
{
-protected:
- enum_field_types cached_field_type;
- Item_func_coalesce(Item *a, Item *b) :Item_func_numhybrid(a, b) {}
public:
- Item_func_coalesce(List<Item> &list) :Item_func_numhybrid(list) {}
+ Item_func_coalesce(Item *a, Item *b) :Item_func_hybrid_field_type(a, b) {}
+ Item_func_coalesce(List<Item> &list) :Item_func_hybrid_field_type(list) {}
double real_op();
longlong int_op();
String *str_op(String *);
my_decimal *decimal_op(my_decimal *);
+ bool date_op(MYSQL_TIME *ltime,uint fuzzydate);
void fix_length_and_dec();
- void find_num_type() {}
- enum Item_result result_type () const { return hybrid_type; }
const char *func_name() const { return "coalesce"; }
table_map not_null_tables() const { return 0; }
- enum_field_types field_type() const { return cached_field_type; }
- bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
};
@@ -768,7 +763,7 @@ public:
longlong int_op();
String *str_op(String *str);
my_decimal *decimal_op(my_decimal *);
- enum_field_types field_type() const;
+ bool date_op(MYSQL_TIME *ltime,uint fuzzydate);
void fix_length_and_dec();
void update_used_tables()
{
@@ -781,20 +776,17 @@ public:
};
-class Item_func_if :public Item_func
+class Item_func_if :public Item_func_hybrid_field_type
{
- enum Item_result cached_result_type;
- enum_field_types cached_field_type;
public:
Item_func_if(Item *a,Item *b,Item *c)
- :Item_func(a,b,c), cached_result_type(INT_RESULT)
+ :Item_func_hybrid_field_type(a,b,c)
{}
- double val_real();
- longlong val_int();
- String *val_str(String *str);
- my_decimal *val_decimal(my_decimal *);
- enum Item_result result_type () const { return cached_result_type; }
- enum_field_types field_type() const { return cached_field_type; }
+ bool date_op(MYSQL_TIME *ltime, uint fuzzydate);
+ longlong int_op();
+ double real_op();
+ my_decimal *decimal_op(my_decimal *);
+ String *str_op(String *);
bool fix_fields(THD *, Item **);
void fix_length_and_dec();
void update_used_tables()
@@ -1231,21 +1223,20 @@ public:
function and only comparators for there result types are used.
*/
-class Item_func_case :public Item_func
+class Item_func_case :public Item_func_hybrid_field_type
{
int first_expr_num, else_expr_num;
- enum Item_result cached_result_type, left_result_type;
+ enum Item_result left_result_type;
String tmp_value;
uint ncases;
Item_result cmp_type;
DTCollation cmp_collation;
- enum_field_types cached_field_type;
cmp_item *cmp_items[6]; /* For all result types */
cmp_item *case_item;
public:
Item_func_case(List<Item> &list, Item *first_expr_arg, Item *else_expr_arg)
- :Item_func(), first_expr_num(-1), else_expr_num(-1),
- cached_result_type(INT_RESULT), left_result_type(INT_RESULT), case_item(0)
+ :Item_func_hybrid_field_type(), first_expr_num(-1), else_expr_num(-1),
+ left_result_type(INT_RESULT), case_item(0)
{
ncases= list.elements;
if (first_expr_arg)
@@ -1261,10 +1252,11 @@ public:
set_arguments(list);
bzero(&cmp_items, sizeof(cmp_items));
}
- double val_real();
- longlong val_int();
- String *val_str(String *);
- my_decimal *val_decimal(my_decimal *);
+ double real_op();
+ longlong int_op();
+ String *str_op(String *);
+ my_decimal *decimal_op(my_decimal *);
+ bool date_op(MYSQL_TIME *ltime, uint fuzzydate);
bool fix_fields(THD *thd, Item **ref);
void fix_length_and_dec();
void update_used_tables()
@@ -1275,8 +1267,6 @@ public:
}
uint decimal_precision() const;
table_map not_null_tables() const { return 0; }
- enum Item_result result_type () const { return cached_result_type; }
- enum_field_types field_type() const { return cached_field_type; }
const char *func_name() const { return "case"; }
virtual void print(String *str, enum_query_type query_type);
Item *find_item(String *str);
@@ -1762,8 +1752,9 @@ public:
/** Get number of field items / references to field items in this object */
uint n_field_items() { return equal_items.elements-test(with_const); }
void merge(Item_equal *item);
- bool merge_with_check(Item_equal *equal_item);
- void merge_into_list(List<Item_equal> *list);
+ bool merge_with_check(Item_equal *equal_item, bool save_merged);
+ void merge_into_list(List<Item_equal> *list, bool save_merged,
+ bool only_intersected);
void update_const();
enum Functype functype() const { return MULT_EQUAL_FUNC; }
longlong val_int();
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 4c7b8fce98b..993576a624e 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -620,6 +620,30 @@ void Item_func_numhybrid::fix_num_length_and_dec()
{}
+
+/**
+ Count max_length and decimals for temporal functions.
+
+ @param item Argument array
+ @param nitems Number of arguments in the array.
+
+ @retval False on success, true on error.
+*/
+void Item_func::count_datetime_length(Item **item, uint nitems)
+{
+ unsigned_flag= 0;
+ decimals= 0;
+ if (field_type() != MYSQL_TYPE_DATE)
+ {
+ for (uint i= 0; i < nitems; i++)
+ set_if_bigger(decimals, item[i]->decimals);
+ }
+ set_if_smaller(decimals, TIME_SECOND_PART_DIGITS);
+ uint len= decimals ? (decimals + 1) : 0;
+ len+= mysql_temporal_int_part_length(field_type());
+ fix_char_length(len);
+}
+
/**
Set max_length/decimals of function if function is fixed point and
result length/precision depends on argument ones.
@@ -647,14 +671,14 @@ void Item_func::count_decimal_length()
Set max_length of if it is maximum length of its arguments.
*/
-void Item_func::count_only_length()
+void Item_func::count_only_length(Item **item, uint nitems)
{
uint32 char_length= 0;
unsigned_flag= 0;
- for (uint i=0 ; i < arg_count ; i++)
+ for (uint i= 0; i < nitems ; i++)
{
- set_if_bigger(char_length, args[i]->max_char_length());
- set_if_bigger(unsigned_flag, args[i]->unsigned_flag);
+ set_if_bigger(char_length, item[i]->max_char_length());
+ set_if_bigger(unsigned_flag, item[i]->unsigned_flag);
}
fix_char_length(char_length);
}
@@ -691,6 +715,30 @@ void Item_func::count_real_length()
}
+/**
+ Calculate max_length and decimals for STRING_RESULT functions.
+
+ @param field_type Field type.
+ @param items Argument array.
+ @param nitems Number of arguments.
+
+ @retval False on success, true on error.
+*/
+bool Item_func::count_string_result_length(enum_field_types field_type,
+ Item **items, uint nitems)
+{
+ if (agg_arg_charsets(collation, items, nitems, MY_COLL_ALLOW_CONV, 1))
+ return true;
+ if (is_temporal_type(field_type))
+ count_datetime_length(items, nitems);
+ else
+ {
+ decimals= NOT_FIXED_DEC;
+ count_only_length(items, nitems);
+ }
+ return false;
+}
+
void Item_func::signal_divide_by_null()
{
@@ -763,26 +811,26 @@ void Item_num_op::find_num_type(void)
{
count_real_length();
max_length= float_length(decimals);
- hybrid_type= REAL_RESULT;
+ cached_result_type= REAL_RESULT;
}
else if (r0 == DECIMAL_RESULT || r1 == DECIMAL_RESULT ||
r0 == TIME_RESULT || r1 == TIME_RESULT)
{
- hybrid_type= DECIMAL_RESULT;
+ cached_result_type= DECIMAL_RESULT;
result_precision();
fix_decimals();
}
else
{
DBUG_ASSERT(r0 == INT_RESULT && r1 == INT_RESULT);
- hybrid_type=INT_RESULT;
+ cached_result_type=INT_RESULT;
result_precision();
decimals= 0;
}
DBUG_PRINT("info", ("Type: %s",
- (hybrid_type == REAL_RESULT ? "REAL_RESULT" :
- hybrid_type == DECIMAL_RESULT ? "DECIMAL_RESULT" :
- hybrid_type == INT_RESULT ? "INT_RESULT" :
+ (cached_result_type == REAL_RESULT ? "REAL_RESULT" :
+ cached_result_type == DECIMAL_RESULT ? "DECIMAL_RESULT" :
+ cached_result_type == INT_RESULT ? "INT_RESULT" :
"--ILLEGAL!!!--")));
DBUG_VOID_RETURN;
}
@@ -798,17 +846,17 @@ void Item_func_num1::find_num_type()
{
DBUG_ENTER("Item_func_num1::find_num_type");
DBUG_PRINT("info", ("name %s", func_name()));
- switch (hybrid_type= args[0]->cast_to_int_type()) {
+ switch (cached_result_type= args[0]->cast_to_int_type()) {
case INT_RESULT:
unsigned_flag= args[0]->unsigned_flag;
break;
case STRING_RESULT:
case REAL_RESULT:
- hybrid_type= REAL_RESULT;
+ cached_result_type= REAL_RESULT;
max_length= float_length(decimals);
break;
case TIME_RESULT:
- hybrid_type= DECIMAL_RESULT;
+ cached_result_type= DECIMAL_RESULT;
case DECIMAL_RESULT:
break;
case ROW_RESULT:
@@ -816,9 +864,9 @@ void Item_func_num1::find_num_type()
DBUG_ASSERT(0);
}
DBUG_PRINT("info", ("Type: %s",
- (hybrid_type == REAL_RESULT ? "REAL_RESULT" :
- hybrid_type == DECIMAL_RESULT ? "DECIMAL_RESULT" :
- hybrid_type == INT_RESULT ? "INT_RESULT" :
+ (cached_result_type == REAL_RESULT ? "REAL_RESULT" :
+ cached_result_type == DECIMAL_RESULT ? "DECIMAL_RESULT" :
+ cached_result_type == INT_RESULT ? "INT_RESULT" :
"--ILLEGAL!!!--")));
DBUG_VOID_RETURN;
}
@@ -838,10 +886,10 @@ void Item_func_numhybrid::fix_length_and_dec()
}
-String *Item_func_numhybrid::val_str(String *str)
+String *Item_func_hybrid_result_type::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- switch (hybrid_type) {
+ switch (cached_result_type) {
case DECIMAL_RESULT:
{
my_decimal decimal_value, *val;
@@ -869,6 +917,21 @@ String *Item_func_numhybrid::val_str(String *str)
break;
}
case STRING_RESULT:
+ if (is_temporal_type(field_type()))
+ {
+ MYSQL_TIME ltime;
+ if (date_op(&ltime,
+ field_type() == MYSQL_TYPE_TIME ? TIME_TIME_ONLY : 0) ||
+ str->alloc(MAX_DATE_STRING_REP_LENGTH))
+ {
+ null_value= 1;
+ return (String *) 0;
+ }
+ ltime.time_type= mysql_type_to_time_type(field_type());
+ str->length(my_TIME_to_str(&ltime, const_cast<char*>(str->ptr()), decimals));
+ str->set_charset(&my_charset_bin);
+ return str;
+ }
return str_op(&str_value);
case TIME_RESULT:
case ROW_RESULT:
@@ -879,10 +942,10 @@ String *Item_func_numhybrid::val_str(String *str)
}
-double Item_func_numhybrid::val_real()
+double Item_func_hybrid_result_type::val_real()
{
DBUG_ASSERT(fixed == 1);
- switch (hybrid_type) {
+ switch (cached_result_type) {
case DECIMAL_RESULT:
{
my_decimal decimal_value, *val;
@@ -901,6 +964,18 @@ double Item_func_numhybrid::val_real()
return real_op();
case STRING_RESULT:
{
+ if (is_temporal_type(field_type()))
+ {
+ MYSQL_TIME ltime;
+ if (date_op(&ltime,
+ field_type() == MYSQL_TYPE_TIME ? TIME_TIME_ONLY : 0 ))
+ {
+ null_value= 1;
+ return 0;
+ }
+ ltime.time_type= mysql_type_to_time_type(field_type());
+ return TIME_to_double(&ltime);
+ }
char *end_not_used;
int err_not_used;
String *res= str_op(&str_value);
@@ -916,10 +991,10 @@ double Item_func_numhybrid::val_real()
}
-longlong Item_func_numhybrid::val_int()
+longlong Item_func_hybrid_result_type::val_int()
{
DBUG_ASSERT(fixed == 1);
- switch (hybrid_type) {
+ switch (cached_result_type) {
case DECIMAL_RESULT:
{
my_decimal decimal_value, *val;
@@ -935,6 +1010,18 @@ longlong Item_func_numhybrid::val_int()
return (longlong) rint(real_op());
case STRING_RESULT:
{
+ if (is_temporal_type(field_type()))
+ {
+ MYSQL_TIME ltime;
+ if (date_op(&ltime,
+ field_type() == MYSQL_TYPE_TIME ? TIME_TIME_ONLY : 0))
+ {
+ null_value= 1;
+ return 0;
+ }
+ ltime.time_type= mysql_type_to_time_type(field_type());
+ return TIME_to_ulonglong(&ltime);
+ }
int err_not_used;
String *res;
if (!(res= str_op(&str_value)))
@@ -953,11 +1040,11 @@ longlong Item_func_numhybrid::val_int()
}
-my_decimal *Item_func_numhybrid::val_decimal(my_decimal *decimal_value)
+my_decimal *Item_func_hybrid_result_type::val_decimal(my_decimal *decimal_value)
{
my_decimal *val= decimal_value;
DBUG_ASSERT(fixed == 1);
- switch (hybrid_type) {
+ switch (cached_result_type) {
case DECIMAL_RESULT:
val= decimal_op(decimal_value);
break;
@@ -975,6 +1062,19 @@ my_decimal *Item_func_numhybrid::val_decimal(my_decimal *decimal_value)
}
case STRING_RESULT:
{
+ if (is_temporal_type(field_type()))
+ {
+ MYSQL_TIME ltime;
+ if (date_op(&ltime,
+ field_type() == MYSQL_TYPE_TIME ? TIME_TIME_ONLY : 0))
+ {
+ my_decimal_set_zero(decimal_value);
+ null_value= 1;
+ return 0;
+ }
+ ltime.time_type= mysql_type_to_time_type(field_type());
+ return date2my_decimal(&ltime, decimal_value);
+ }
String *res;
if (!(res= str_op(&str_value)))
return NULL;
@@ -992,6 +1092,63 @@ my_decimal *Item_func_numhybrid::val_decimal(my_decimal *decimal_value)
}
+bool Item_func_hybrid_result_type::get_date(MYSQL_TIME *ltime,
+ ulonglong fuzzydate)
+{
+ DBUG_ASSERT(fixed == 1);
+ switch (cached_result_type) {
+ case DECIMAL_RESULT:
+ {
+ my_decimal value, *res;
+ if (!(res= decimal_op(&value)) ||
+ decimal_to_datetime_with_warn(res, ltime, fuzzydate,
+ field_name_or_null()))
+ goto err;
+ break;
+ }
+ case INT_RESULT:
+ {
+ longlong value= int_op();
+ if (null_value || int_to_datetime_with_warn(value, ltime, fuzzydate,
+ field_name_or_null()))
+ goto err;
+ break;
+ }
+ case REAL_RESULT:
+ {
+ double value= real_op();
+ if (null_value || double_to_datetime_with_warn(value, ltime, fuzzydate,
+ field_name_or_null()))
+ goto err;
+ break;
+ }
+ case STRING_RESULT:
+ {
+ if (is_temporal_type(field_type()))
+ return date_op(ltime, fuzzydate);
+ char buff[40];
+ String tmp(buff,sizeof(buff), &my_charset_bin),*res;
+ if (!(res= str_op(&tmp)) ||
+ str_to_datetime_with_warn(res->charset(), res->ptr(), res->length(),
+ ltime, fuzzydate) <= MYSQL_TIMESTAMP_ERROR)
+ goto err;
+ break;
+ break;
+ }
+ case ROW_RESULT:
+ case TIME_RESULT:
+ case IMPOSSIBLE_RESULT:
+ DBUG_ASSERT(0);
+ }
+
+ return (null_value= 0);
+
+err:
+ bzero(ltime, sizeof(*ltime));
+ return null_value|= !(fuzzydate & TIME_FUZZY_DATES);
+}
+
+
void Item_func_signed::print(String *str, enum_query_type query_type)
{
str->append(STRING_WITH_LEN("cast("));
@@ -1688,7 +1845,7 @@ void Item_func_div::fix_length_and_dec()
DBUG_ENTER("Item_func_div::fix_length_and_dec");
prec_increment= current_thd->variables.div_precincrement;
Item_num_op::fix_length_and_dec();
- switch (hybrid_type) {
+ switch (cached_result_type) {
case REAL_RESULT:
{
decimals=max(args[0]->decimals,args[1]->decimals)+prec_increment;
@@ -1704,7 +1861,7 @@ void Item_func_div::fix_length_and_dec()
break;
}
case INT_RESULT:
- hybrid_type= DECIMAL_RESULT;
+ cached_result_type= DECIMAL_RESULT;
DBUG_PRINT("info", ("Type changed: DECIMAL_RESULT"));
result_precision();
break;
@@ -1956,7 +2113,7 @@ void Item_func_neg::fix_length_and_dec()
Use val() to get value as arg_type doesn't mean that item is
Item_int or Item_real due to existence of Item_param.
*/
- if (hybrid_type == INT_RESULT && args[0]->const_item())
+ if (cached_result_type == INT_RESULT && args[0]->const_item())
{
longlong val= args[0]->val_int();
if ((ulonglong) val >= (ulonglong) LONGLONG_MIN &&
@@ -1967,7 +2124,7 @@ void Item_func_neg::fix_length_and_dec()
Ensure that result is converted to DECIMAL, as longlong can't hold
the negated number
*/
- hybrid_type= DECIMAL_RESULT;
+ cached_result_type= DECIMAL_RESULT;
DBUG_PRINT("info", ("Type changed: DECIMAL_RESULT"));
}
}
@@ -2271,11 +2428,11 @@ void Item_func_int_val::find_num_type()
{
DBUG_ENTER("Item_func_int_val::find_num_type");
DBUG_PRINT("info", ("name %s", func_name()));
- switch (hybrid_type= args[0]->cast_to_int_type())
+ switch (cached_result_type= args[0]->cast_to_int_type())
{
case STRING_RESULT:
case REAL_RESULT:
- hybrid_type= REAL_RESULT;
+ cached_result_type= REAL_RESULT;
max_length= float_length(decimals);
break;
case INT_RESULT:
@@ -2288,12 +2445,12 @@ void Item_func_int_val::find_num_type()
if ((args[0]->max_length - args[0]->decimals) >=
(DECIMAL_LONGLONG_DIGITS - 2))
{
- hybrid_type= DECIMAL_RESULT;
+ cached_result_type= DECIMAL_RESULT;
}
else
{
unsigned_flag= args[0]->unsigned_flag;
- hybrid_type= INT_RESULT;
+ cached_result_type= INT_RESULT;
}
break;
case ROW_RESULT:
@@ -2301,9 +2458,9 @@ void Item_func_int_val::find_num_type()
DBUG_ASSERT(0);
}
DBUG_PRINT("info", ("Type: %s",
- (hybrid_type == REAL_RESULT ? "REAL_RESULT" :
- hybrid_type == DECIMAL_RESULT ? "DECIMAL_RESULT" :
- hybrid_type == INT_RESULT ? "INT_RESULT" :
+ (cached_result_type == REAL_RESULT ? "REAL_RESULT" :
+ cached_result_type == DECIMAL_RESULT ? "DECIMAL_RESULT" :
+ cached_result_type == INT_RESULT ? "INT_RESULT" :
"--ILLEGAL!!!--")));
DBUG_VOID_RETURN;
@@ -2418,10 +2575,10 @@ void Item_func_round::fix_length_and_dec()
if (args[0]->result_type() == DECIMAL_RESULT)
{
max_length++;
- hybrid_type= DECIMAL_RESULT;
+ cached_result_type= DECIMAL_RESULT;
}
else
- hybrid_type= REAL_RESULT;
+ cached_result_type= REAL_RESULT;
return;
}
@@ -2439,14 +2596,14 @@ void Item_func_round::fix_length_and_dec()
{
decimals= min(decimals_to_set, NOT_FIXED_DEC);
max_length= float_length(decimals);
- hybrid_type= REAL_RESULT;
+ cached_result_type= REAL_RESULT;
return;
}
switch (args[0]->result_type()) {
case REAL_RESULT:
case STRING_RESULT:
- hybrid_type= REAL_RESULT;
+ cached_result_type= REAL_RESULT;
decimals= min(decimals_to_set, NOT_FIXED_DEC);
max_length= float_length(decimals);
break;
@@ -2456,14 +2613,14 @@ void Item_func_round::fix_length_and_dec()
int length_can_increase= test(!truncate && (val1 < 0) && !val1_unsigned);
max_length= args[0]->max_length + length_can_increase;
/* Here we can keep INT_RESULT */
- hybrid_type= INT_RESULT;
+ cached_result_type= INT_RESULT;
decimals= 0;
break;
}
/* fall through */
case DECIMAL_RESULT:
{
- hybrid_type= DECIMAL_RESULT;
+ cached_result_type= DECIMAL_RESULT;
decimals_to_set= min(DECIMAL_MAX_SCALE, decimals_to_set);
int decimals_delta= args[0]->decimals - decimals_to_set;
int precision= args[0]->decimal_precision();
diff --git a/sql/item_func.h b/sql/item_func.h
index 499ad9f1893..3c3c6861d33 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -156,13 +156,16 @@ public:
void print_op(String *str, enum_query_type query_type);
void print_args(String *str, uint from, enum_query_type query_type);
virtual void fix_num_length_and_dec();
- void count_only_length();
+ void count_only_length(Item **item, uint nitems);
void count_real_length();
void count_decimal_length();
inline bool get_arg0_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
{
return (null_value=args[0]->get_date(ltime, fuzzy_date));
}
+ void count_datetime_length(Item **item, uint nitems);
+ bool count_string_result_length(enum_field_types field_type,
+ Item **item, uint nitems);
inline bool get_arg0_time(MYSQL_TIME *ltime)
{
return (null_value=args[0]->get_time(ltime));
@@ -417,38 +420,33 @@ public:
};
-class Item_func_numhybrid: public Item_func
+class Item_func_hybrid_result_type: public Item_func
{
protected:
- Item_result hybrid_type;
+ Item_result cached_result_type;
+
public:
- Item_func_numhybrid() :Item_func(), hybrid_type(REAL_RESULT)
- {}
- Item_func_numhybrid(Item *a) :Item_func(a), hybrid_type(REAL_RESULT)
+ Item_func_hybrid_result_type() :Item_func(), cached_result_type(REAL_RESULT)
{ collation.set_numeric(); }
- Item_func_numhybrid(Item *a,Item *b)
- :Item_func(a,b), hybrid_type(REAL_RESULT)
+ Item_func_hybrid_result_type(Item *a) :Item_func(a), cached_result_type(REAL_RESULT)
{ collation.set_numeric(); }
- Item_func_numhybrid(List<Item> &list)
- :Item_func(list), hybrid_type(REAL_RESULT)
+ Item_func_hybrid_result_type(Item *a,Item *b)
+ :Item_func(a,b), cached_result_type(REAL_RESULT)
+ { collation.set_numeric(); }
+ Item_func_hybrid_result_type(Item *a,Item *b,Item *c)
+ :Item_func(a,b,c), cached_result_type(REAL_RESULT)
+ { collation.set_numeric(); }
+ Item_func_hybrid_result_type(List<Item> &list)
+ :Item_func(list), cached_result_type(REAL_RESULT)
{ collation.set_numeric(); }
- enum Item_result result_type () const { return hybrid_type; }
- void fix_length_and_dec();
- void fix_num_length_and_dec();
- virtual void find_num_type()= 0; /* To be called from fix_length_and_dec */
-
- inline void fix_decimals()
- {
- DBUG_ASSERT(result_type() == DECIMAL_RESULT);
- if (decimals == NOT_FIXED_DEC)
- set_if_smaller(decimals, max_length - 1);
- }
+ enum Item_result result_type () const { return cached_result_type; }
double val_real();
longlong val_int();
my_decimal *val_decimal(my_decimal *);
String *val_str(String*str);
+ bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
/**
@brief Performs the operation that this functions implements when the
@@ -485,9 +483,75 @@ public:
@return The result of the operation.
*/
virtual String *str_op(String *)= 0;
- bool is_null() { update_null_value(); return null_value; }
+
+ /**
+ @brief Performs the operation that this functions implements when
+ field type is a temporal type.
+ @return The result of the operation.
+ */
+ virtual bool date_op(MYSQL_TIME *res, uint fuzzy_date)= 0;
+
};
+
+
+class Item_func_hybrid_field_type :public Item_func_hybrid_result_type
+{
+protected:
+ enum_field_types cached_field_type;
+public:
+ Item_func_hybrid_field_type()
+ :Item_func_hybrid_result_type(), cached_field_type(MYSQL_TYPE_DOUBLE)
+ {}
+ Item_func_hybrid_field_type(Item *a, Item *b)
+ :Item_func_hybrid_result_type(a, b), cached_field_type(MYSQL_TYPE_DOUBLE)
+ {}
+ Item_func_hybrid_field_type(Item *a, Item *b, Item *c)
+ :Item_func_hybrid_result_type(a, b, c),
+ cached_field_type(MYSQL_TYPE_DOUBLE)
+ {}
+ Item_func_hybrid_field_type(List<Item> &list)
+ :Item_func_hybrid_result_type(list),
+ cached_field_type(MYSQL_TYPE_DOUBLE)
+ {}
+ enum_field_types field_type() const { return cached_field_type; }
+};
+
+
+
+class Item_func_numhybrid: public Item_func_hybrid_result_type
+{
+protected:
+
+ inline void fix_decimals()
+ {
+ DBUG_ASSERT(result_type() == DECIMAL_RESULT);
+ if (decimals == NOT_FIXED_DEC)
+ set_if_smaller(decimals, max_length - 1);
+ }
+
+public:
+ Item_func_numhybrid() :Item_func_hybrid_result_type()
+ { }
+ Item_func_numhybrid(Item *a) :Item_func_hybrid_result_type(a)
+ { }
+ Item_func_numhybrid(Item *a,Item *b)
+ :Item_func_hybrid_result_type(a,b)
+ { }
+ Item_func_numhybrid(Item *a,Item *b,Item *c)
+ :Item_func_hybrid_result_type(a,b,c)
+ { }
+ Item_func_numhybrid(List<Item> &list)
+ :Item_func_hybrid_result_type(list)
+ { }
+ void fix_length_and_dec();
+ void fix_num_length_and_dec();
+ virtual void find_num_type()= 0; /* To be called from fix_length_and_dec */
+ String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
+ bool date_op(MYSQL_TIME *ltime, uint fuzzydate) { DBUG_ASSERT(0); return true; }
+};
+
+
/* function where type of result detected by first argument */
class Item_func_num1: public Item_func_numhybrid
{
@@ -497,7 +561,6 @@ public:
void fix_num_length_and_dec();
void find_num_type();
- String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
};
@@ -514,7 +577,6 @@ class Item_num_op :public Item_func_numhybrid
}
void find_num_type();
- String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
};
@@ -1618,15 +1680,14 @@ public:
:Item_func(b), cached_result_type(INT_RESULT),
entry(NULL), entry_thread_id(0), name(a)
{}
- Item_func_set_user_var(Item_func_set_user_var *item)
- :Item_func(item), cached_result_type(item->cached_result_type),
- entry(item->entry), entry_thread_id(item->entry_thread_id),
- value(item->value), decimal_buff(item->decimal_buff),
- null_item(item->null_item), save_result(item->save_result),
- name(item->name)
- {
- //fixed= 1;
- }
+ Item_func_set_user_var(THD *thd, Item_func_set_user_var *item)
+ :Item_func(thd, item), cached_result_type(item->cached_result_type),
+ entry(item->entry), entry_thread_id(item->entry_thread_id),
+ value(item->value), decimal_buff(item->decimal_buff),
+ null_item(item->null_item), save_result(item->save_result),
+ name(item->name)
+ {}
+
enum Functype functype() const { return SUSERVAR_FUNC; }
double val_real();
longlong val_int();
@@ -1773,6 +1834,8 @@ public:
double val_real();
longlong val_int();
String* val_str(String*);
+ my_decimal *val_decimal(my_decimal *dec_buf)
+ { return val_decimal_from_real(dec_buf); }
/* TODO: fix to support views */
const char *func_name() const { return "get_system_var"; }
/**
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index d373b017db7..27c7b2ce88d 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -1752,6 +1752,15 @@ Item_in_subselect::single_value_transformer(JOIN *join)
*/
where_item->walk(&Item::remove_dependence_processor, 0,
(uchar *) select_lex->outer_select());
+ /*
+ fix_field of substitution item will be done in time of
+ substituting.
+ Note that real_item() should be used instead of
+ original left expression because left_expr can be
+ runtime created Ref item which is deleted at the end
+ of the statement. Thus one of 'substitution' arguments
+ can be broken in case of PS.
+ */
substitution= func->create(left_expr, where_item);
have_to_be_excluded= 1;
if (thd->lex->describe)
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index c82fb3dd0f2..b8421eaee94 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -1290,7 +1290,19 @@ bool get_interval_value(Item *args,interval_type int_type, INTERVAL *interval)
String str_value(buf, sizeof(buf), &my_charset_bin);
bzero((char*) interval,sizeof(*interval));
- if ((int) int_type <= INTERVAL_MICROSECOND)
+ if (int_type == INTERVAL_SECOND && args->decimals)
+ {
+ my_decimal decimal_value, *val;
+ ulonglong second;
+ ulong second_part;
+ if (!(val= args->val_decimal(&decimal_value)))
+ return true;
+ interval->neg= my_decimal2seconds(val, &second, &second_part);
+ interval->second= second;
+ interval->second_part= second_part;
+ return false;
+ }
+ else if ((int) int_type <= INTERVAL_MICROSECOND)
{
value= args->val_int();
if (args->null_value)
@@ -1435,12 +1447,12 @@ bool get_interval_value(Item *args,interval_type int_type, INTERVAL *interval)
void Item_temporal_func::fix_length_and_dec()
{
- static const uint max_time_type_width[5]=
- { MAX_DATETIME_WIDTH, MAX_DATETIME_WIDTH, MAX_DATE_WIDTH,
- MAX_DATETIME_WIDTH, MIN_TIME_WIDTH };
-
+ /*
+ We set maybe_null to 1 as default as any bad argument with date or
+ time can get us to return NULL.
+ */
set_persist_maybe_null(1);
- max_length= max_time_type_width[mysql_type_to_time_type(field_type())+2];
+ max_length= mysql_temporal_int_part_length(field_type());
if (decimals)
{
if (decimals == NOT_FIXED_DEC)
@@ -1929,7 +1941,7 @@ bool Item_func_from_unixtime::get_date(MYSQL_TIME *ltime,
void Item_func_convert_tz::fix_length_and_dec()
{
- decimals= args[0]->decimals;
+ decimals= args[0]->temporal_precision(MYSQL_TYPE_DATETIME);
Item_temporal_func::fix_length_and_dec();
}
@@ -2000,28 +2012,40 @@ void Item_date_add_interval::fix_length_and_dec()
*/
cached_field_type= MYSQL_TYPE_STRING;
arg0_field_type= args[0]->field_type();
+ uint interval_dec= 0;
+ if (int_type == INTERVAL_MICROSECOND ||
+ (int_type >= INTERVAL_DAY_MICROSECOND &&
+ int_type <= INTERVAL_SECOND_MICROSECOND))
+ interval_dec= TIME_SECOND_PART_DIGITS;
+ else if (int_type == INTERVAL_SECOND && args[1]->decimals > 0)
+ interval_dec= min(args[1]->decimals, TIME_SECOND_PART_DIGITS);
+
if (arg0_field_type == MYSQL_TYPE_DATETIME ||
arg0_field_type == MYSQL_TYPE_TIMESTAMP)
+ {
+ decimals= max(args[0]->temporal_precision(MYSQL_TYPE_DATETIME), interval_dec);
cached_field_type= MYSQL_TYPE_DATETIME;
+ }
else if (arg0_field_type == MYSQL_TYPE_DATE)
{
if (int_type <= INTERVAL_DAY || int_type == INTERVAL_YEAR_MONTH)
cached_field_type= arg0_field_type;
else
+ {
+ decimals= interval_dec;
cached_field_type= MYSQL_TYPE_DATETIME;
+ }
}
else if (arg0_field_type == MYSQL_TYPE_TIME)
{
+ decimals= max(args[0]->temporal_precision(MYSQL_TYPE_TIME), interval_dec);
if (int_type >= INTERVAL_DAY && int_type != INTERVAL_YEAR_MONTH)
cached_field_type= arg0_field_type;
else
cached_field_type= MYSQL_TYPE_DATETIME;
}
- if (int_type == INTERVAL_MICROSECOND || int_type >= INTERVAL_DAY_MICROSECOND)
- decimals= 6;
else
- decimals= args[0]->decimals;
-
+ decimals= max(args[0]->temporal_precision(MYSQL_TYPE_DATETIME), interval_dec);
Item_temporal_func::fix_length_and_dec();
}
@@ -2534,10 +2558,19 @@ void Item_func_add_time::fix_length_and_dec()
arg0_field_type= args[0]->field_type();
if (arg0_field_type == MYSQL_TYPE_DATE ||
arg0_field_type == MYSQL_TYPE_DATETIME ||
- arg0_field_type == MYSQL_TYPE_TIMESTAMP)
+ arg0_field_type == MYSQL_TYPE_TIMESTAMP ||
+ is_date)
+ {
cached_field_type= MYSQL_TYPE_DATETIME;
+ decimals= max(args[0]->temporal_precision(MYSQL_TYPE_DATETIME),
+ args[1]->temporal_precision(MYSQL_TYPE_TIME));
+ }
else if (arg0_field_type == MYSQL_TYPE_TIME)
+ {
cached_field_type= MYSQL_TYPE_TIME;
+ decimals= max(args[0]->temporal_precision(MYSQL_TYPE_TIME),
+ args[1]->temporal_precision(MYSQL_TYPE_TIME));
+ }
Item_temporal_func::fix_length_and_dec();
}
@@ -2718,13 +2751,14 @@ bool Item_func_maketime::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
{
DBUG_ASSERT(fixed == 1);
bool overflow= 0;
-
longlong hour= args[0]->val_int();
longlong minute= args[1]->val_int();
- longlong second= args[2]->val_int();
+ ulonglong second;
+ ulong microsecond;
+ bool neg= args[2]->get_seconds(&second, &microsecond);
if (args[0]->null_value || args[1]->null_value || args[2]->null_value ||
- minute < 0 || minute > 59 || second < 0 || second > 59)
+ minute < 0 || minute > 59 || neg || second > 59)
return (null_value= 1);
bzero(ltime, sizeof(*ltime));
@@ -2746,6 +2780,7 @@ bool Item_func_maketime::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
ltime->hour= (uint) ((hour < 0 ? -hour : hour));
ltime->minute= (uint) minute;
ltime->second= (uint) second;
+ ltime->second_part= microsecond;
}
else
{
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 8bea068357b..9abcff2e1bd 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -30,19 +30,17 @@ enum date_time_format_types
TIME_ONLY= 0, TIME_MICROSECOND, DATE_ONLY, DATE_TIME, DATE_TIME_MICROSECOND
};
-static inline enum enum_mysql_timestamp_type
-mysql_type_to_time_type(enum enum_field_types mysql_type)
+
+static inline uint
+mysql_temporal_int_part_length(enum enum_field_types mysql_type)
{
- switch(mysql_type) {
- case MYSQL_TYPE_TIME: return MYSQL_TIMESTAMP_TIME;
- case MYSQL_TYPE_TIMESTAMP:
- case MYSQL_TYPE_DATETIME: return MYSQL_TIMESTAMP_DATETIME;
- case MYSQL_TYPE_NEWDATE:
- case MYSQL_TYPE_DATE: return MYSQL_TIMESTAMP_DATE;
- default: return MYSQL_TIMESTAMP_ERROR;
- }
+ static uint max_time_type_width[5]=
+ { MAX_DATETIME_WIDTH, MAX_DATETIME_WIDTH, MAX_DATE_WIDTH,
+ MAX_DATETIME_WIDTH, MIN_TIME_WIDTH };
+ return max_time_type_width[mysql_type_to_time_type(mysql_type)+2];
}
+
bool get_interval_value(Item *args,interval_type int_type, INTERVAL *interval);
class Item_func_period_add :public Item_int_func
@@ -410,26 +408,32 @@ class Item_func_dayname :public Item_func_weekday
class Item_func_seconds_hybrid: public Item_func_numhybrid
{
+protected:
+ virtual enum_field_types arg0_expected_type() const = 0;
public:
Item_func_seconds_hybrid() :Item_func_numhybrid() {}
Item_func_seconds_hybrid(Item *a) :Item_func_numhybrid(a) {}
void fix_num_length_and_dec()
{
if (arg_count)
- decimals= args[0]->decimals;
+ decimals= args[0]->temporal_precision(arg0_expected_type());
set_if_smaller(decimals, TIME_SECOND_PART_DIGITS);
max_length=17 + (decimals ? decimals + 1 : 0);
set_persist_maybe_null(1);
}
- void find_num_type() { hybrid_type= decimals ? DECIMAL_RESULT : INT_RESULT; }
+ void find_num_type()
+ { cached_result_type= decimals ? DECIMAL_RESULT : INT_RESULT; }
double real_op() { DBUG_ASSERT(0); return 0; }
String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
+ bool date_op(MYSQL_TIME *ltime, uint fuzzydate) { DBUG_ASSERT(0); return true; }
};
class Item_func_unix_timestamp :public Item_func_seconds_hybrid
{
bool get_timestamp_value(my_time_t *seconds, ulong *second_part);
+protected:
+ enum_field_types arg0_expected_type() const { return MYSQL_TYPE_DATETIME; }
public:
Item_func_unix_timestamp() :Item_func_seconds_hybrid() {}
Item_func_unix_timestamp(Item *a) :Item_func_seconds_hybrid(a) {}
@@ -461,6 +465,8 @@ public:
class Item_func_time_to_sec :public Item_func_seconds_hybrid
{
+protected:
+ enum_field_types arg0_expected_type() const { return MYSQL_TYPE_TIME; }
public:
Item_func_time_to_sec(Item *item) :Item_func_seconds_hybrid(item) {}
const char *func_name() const { return "time_to_sec"; }
@@ -860,7 +866,7 @@ public:
void fix_length_and_dec()
{
if (decimals == NOT_FIXED_DEC)
- decimals= args[0]->decimals;
+ decimals= args[0]->temporal_precision(field_type());
Item_temporal_func::fix_length_and_dec();
}
};
@@ -934,7 +940,8 @@ public:
const char *func_name() const { return "timediff"; }
void fix_length_and_dec()
{
- decimals= max(args[0]->decimals, args[1]->decimals);
+ decimals= max(args[0]->temporal_precision(MYSQL_TYPE_TIME),
+ args[1]->temporal_precision(MYSQL_TYPE_TIME));
Item_timefunc::fix_length_and_dec();
}
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
@@ -946,6 +953,11 @@ public:
Item_func_maketime(Item *a, Item *b, Item *c)
:Item_timefunc(a, b, c)
{}
+ void fix_length_and_dec()
+ {
+ decimals= min(args[2]->decimals, TIME_SECOND_PART_DIGITS);
+ Item_timefunc::fix_length_and_dec();
+ }
const char *func_name() const { return "maketime"; }
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
};
diff --git a/sql/log_event.cc b/sql/log_event.cc
index b0380686e0f..1f1d5cd143d 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -6841,6 +6841,7 @@ void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
int Intvar_log_event::do_apply_event(Relay_log_info const *rli)
{
+ DBUG_ENTER("Intvar_log_event::do_apply_event");
/*
We are now in a statement until the associated query log event has
been processed.
@@ -6848,18 +6849,23 @@ int Intvar_log_event::do_apply_event(Relay_log_info const *rli)
const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
if (rli->deferred_events_collecting)
- return rli->deferred_events->add(this);
+ {
+ DBUG_PRINT("info",("deferring event"));
+ DBUG_RETURN(rli->deferred_events->add(this));
+ }
switch (type) {
case LAST_INSERT_ID_EVENT:
thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 1;
- thd->first_successful_insert_id_in_prev_stmt= val;
+ thd->first_successful_insert_id_in_prev_stmt_for_binlog=
+ thd->first_successful_insert_id_in_prev_stmt= val;
+ DBUG_PRINT("info",("last_insert_id_event: %ld", (long) val));
break;
case INSERT_ID_EVENT:
thd->force_one_auto_inc_interval(val);
break;
}
- return 0;
+ DBUG_RETURN(0);
}
int Intvar_log_event::do_update_pos(Relay_log_info *rli)
diff --git a/sql/log_event.h b/sql/log_event.h
index 9a74203757c..623169914b1 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -41,7 +41,6 @@
#include "rpl_utility.h"
#include "hash.h"
#include "rpl_tblmap.h"
-#include "rpl_tblmap.cc"
#endif
#ifdef MYSQL_SERVER
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 336a8f88891..abdd5ca0ac4 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -597,7 +597,6 @@ key_map key_map_full(0); // Will be initialized later
DATE_TIME_FORMAT global_date_format, global_datetime_format, global_time_format;
Time_zone *default_tz;
-char *mysql_data_home= const_cast<char*>(".");
const char *mysql_real_data_home_ptr= mysql_real_data_home;
char server_version[SERVER_VERSION_LENGTH];
char *mysqld_unix_port, *opt_mysql_tmpdir;
diff --git a/sql/mysqld.h b/sql/mysqld.h
index 02d6b41cf69..23ed192a7eb 100644
--- a/sql/mysqld.h
+++ b/sql/mysqld.h
@@ -323,7 +323,6 @@ extern uint mysql_data_home_len;
extern uint mysql_real_data_home_len;
extern const char *mysql_real_data_home_ptr;
extern ulong thread_handling;
-extern MYSQL_PLUGIN_IMPORT char *mysql_data_home;
extern "C" MYSQL_PLUGIN_IMPORT char server_version[SERVER_VERSION_LENGTH];
extern MYSQL_PLUGIN_IMPORT char mysql_real_data_home[];
extern char mysql_unpacked_real_data_home[];
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 27913f0aa8e..92a529c6f81 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -11785,6 +11785,26 @@ int QUICK_SELECT_DESC::get_next()
if (!(last_range= rev_it++))
DBUG_RETURN(HA_ERR_END_OF_FILE); // All ranges used
+ key_range start_key;
+ start_key.key= (const uchar*) last_range->min_key;
+ start_key.length= last_range->min_length;
+ start_key.flag= ((last_range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
+ (last_range->flag & EQ_RANGE) ?
+ HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
+ start_key.keypart_map= last_range->min_keypart_map;
+ key_range end_key;
+ end_key.key= (const uchar*) last_range->max_key;
+ end_key.length= last_range->max_length;
+ end_key.flag= (last_range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
+ HA_READ_AFTER_KEY);
+ end_key.keypart_map= last_range->max_keypart_map;
+ result= file->prepare_range_scan((last_range->flag & NO_MIN_RANGE) ? NULL : &start_key,
+ (last_range->flag & NO_MAX_RANGE) ? NULL : &end_key);
+ if (result)
+ {
+ DBUG_RETURN(result);
+ }
+
if (last_range->flag & NO_MAX_RANGE) // Read last record
{
int local_error;
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index d862c4cdac0..f218e4c35f2 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -5218,10 +5218,12 @@ bool setup_jtbm_semi_joins(JOIN *join, List<TABLE_LIST> *join_list,
{
eq_cond= new Item_func_eq(subq_pred->left_expr->element_index(i),
new_sink->row[i]);
- if (!eq_cond || eq_cond->fix_fields(join->thd, &eq_cond))
+ if (!eq_cond)
DBUG_RETURN(1);
- (*join_where)= and_items(*join_where, eq_cond);
+ if (!((*join_where)= and_items(*join_where, eq_cond)) ||
+ (*join_where)->fix_fields(join->thd, join_where))
+ DBUG_RETURN(1);
}
}
else
@@ -5236,6 +5238,12 @@ bool setup_jtbm_semi_joins(JOIN *join, List<TABLE_LIST> *join_list,
DBUG_RETURN(1);
table->table= dummy_table;
table->table->pos_in_table_list= table;
+ /*
+ Note: the table created above may be freed by:
+ 1. JOIN_TAB::cleanup(), when the parent join is a regular join.
+ 2. cleanup_empty_jtbm_semi_joins(), when the parent join is a
+ degenerate join (e.g. one with "Impossible where").
+ */
setup_table_map(table->table, table, table->jtbm_table_no);
}
else
@@ -5268,6 +5276,42 @@ bool setup_jtbm_semi_joins(JOIN *join, List<TABLE_LIST> *join_list,
}
+/*
+ Cleanup non-merged semi-joins (JBMs) that have empty.
+
+ This function is to cleanups for a special case:
+ Consider a query like
+
+ select * from t1 where 1=2 AND t1.col IN (select max(..) ... having 1=2)
+
+ For this query, optimization of subquery will short-circuit, and
+ setup_jtbm_semi_joins() will call create_dummy_tmp_table() so that we have
+ empty, constant temp.table to stand in as materialized temp. table.
+
+ Now, suppose that the upper join is also found to be degenerate. In that
+ case, no JOIN_TAB array will be produced, and hence, JOIN::cleanup() will
+ have a problem with cleaning up empty JTBMs (non-empty ones are cleaned up
+ through Item::cleanup() calls).
+*/
+
+void cleanup_empty_jtbm_semi_joins(JOIN *join)
+{
+ List_iterator<TABLE_LIST> li(*join->join_list);
+ TABLE_LIST *table;
+ while ((table= li++))
+ {
+ if ((table->jtbm_subselect && table->jtbm_subselect->is_jtbm_const_tab))
+ {
+ if (table->table)
+ {
+ free_tmp_table(join->thd, table->table);
+ table->table= NULL;
+ }
+ }
+ }
+}
+
+
/**
Choose an optimal strategy to execute an IN/ALL/ANY subquery predicate
based on cost.
diff --git a/sql/opt_subselect.h b/sql/opt_subselect.h
index 508531b8c37..3651c1d0020 100644
--- a/sql/opt_subselect.h
+++ b/sql/opt_subselect.h
@@ -28,6 +28,7 @@ int pull_out_semijoin_tables(JOIN *join);
bool optimize_semijoin_nests(JOIN *join, table_map all_table_map);
bool setup_jtbm_semi_joins(JOIN *join, List<TABLE_LIST> *join_list,
Item **join_where);
+void cleanup_empty_jtbm_semi_joins(JOIN *join);
// used by Loose_scan_opt
ulonglong get_bound_sj_equalities(TABLE_LIST *sj_nest,
diff --git a/sql/opt_table_elimination.cc b/sql/opt_table_elimination.cc
index 33164c1ed12..4a10d402fac 100644
--- a/sql/opt_table_elimination.cc
+++ b/sql/opt_table_elimination.cc
@@ -892,8 +892,11 @@ bool Dep_analysis_context::run_wave(List<Dep_module> *new_bound_modules)
iter= module->init_unbound_values_iter(iter_buf);
while ((value= module->get_next_unbound_value(this, iter)))
{
- value->make_bound();
- new_bound_values.push_back(value);
+ if (!value->is_bound())
+ {
+ value->make_bound();
+ new_bound_values.push_back(value);
+ }
}
}
new_bound_modules->empty();
@@ -1740,7 +1743,7 @@ Dep_module* Dep_value_field::get_next_unbound_module(Dep_analysis_context *dac,
- have this field as a part of them
*/
while (key_dep && (key_dep->is_applicable() ||
- !field->part_of_key.is_set(key_dep->keyno)))
+ !field->part_of_key_not_clustered.is_set(key_dep->keyno)))
{
key_dep= key_dep->next_table_key;
}
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index 34e47331664..415e6267ef3 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -2451,7 +2451,7 @@ bool partition_info::has_same_partitioning(partition_info *new_part_info)
partition_element *new_sub_part_elem= new_sub_part_it++;
/* new_part_elem may not have engine_type set! */
if (new_sub_part_elem->engine_type &&
- sub_part_elem->engine_type != new_part_elem->engine_type)
+ sub_part_elem->engine_type != new_sub_part_elem->engine_type)
DBUG_RETURN(false);
if (strcmp(sub_part_elem->partition_name,
diff --git a/sql/records.cc b/sql/records.cc
index d28799ea9d2..e534c04935a 100644
--- a/sql/records.cc
+++ b/sql/records.cc
@@ -371,7 +371,15 @@ static int rr_quick(READ_RECORD *info)
static int rr_index_first(READ_RECORD *info)
{
- int tmp= info->table->file->ha_index_first(info->record);
+ int tmp;
+ // tell handler that we are doing an index scan
+ if ((tmp = info->table->file->prepare_index_scan()))
+ {
+ tmp= rr_handle_error(info, tmp);
+ return tmp;
+ }
+
+ tmp= info->table->file->ha_index_first(info->record);
info->read_record= rr_index;
if (tmp)
tmp= rr_handle_error(info, tmp);
diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc
index 6bbe998a624..22ee49b9bfb 100644
--- a/sql/rpl_utility.cc
+++ b/sql/rpl_utility.cc
@@ -1146,7 +1146,7 @@ bool Deferred_log_events::is_empty()
bool Deferred_log_events::execute(Relay_log_info *rli)
{
bool res= false;
-
+ DBUG_ENTER("Deferred_log_events::execute");
DBUG_ASSERT(rli->deferred_events_collecting);
rli->deferred_events_collecting= false;
@@ -1157,7 +1157,7 @@ bool Deferred_log_events::execute(Relay_log_info *rli)
res= ev->apply_event(rli);
}
rli->deferred_events_collecting= true;
- return res;
+ DBUG_RETURN(res);
}
void Deferred_log_events::rewind()
diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc
index edc33c4d63b..33b0fd13267 100644
--- a/sql/signal_handler.cc
+++ b/sql/signal_handler.cc
@@ -12,7 +12,7 @@
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 */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "my_global.h"
#include <signal.h>
diff --git a/sql/spatial.cc b/sql/spatial.cc
index a01d2c59a49..32a2012a49d 100644
--- a/sql/spatial.cc
+++ b/sql/spatial.cc
@@ -447,19 +447,18 @@ const char *Geometry::append_points(String *txt, uint32 n_points,
const char *Geometry::get_mbr_for_points(MBR *mbr, const char *data,
uint offset) const
{
- uint32 n_points;
+ uint32 points;
/* read number of points */
if (no_data(data, 4))
return 0;
- n_points= uint4korr(data);
+ points= uint4korr(data);
data+= 4;
- if (n_points > max_n_points ||
- no_data(data, (POINT_DATA_SIZE + offset) * n_points))
+ if (not_enough_points(data, points, offset))
return 0;
/* Calculate MBR for points */
- while (n_points--)
+ while (points--)
{
data+= offset;
mbr->add_xy(data, data + SIZEOF_STORED_DOUBLE);
@@ -563,12 +562,16 @@ const Geometry::Class_info *Gis_point::get_class_info() const
uint32 Gis_line_string::get_data_size() const
{
- uint32 n_points, size;
- if (no_data(m_data, 4) ||
- (n_points= uint4korr(m_data)) > max_n_points ||
- no_data(m_data, (size= 4 + n_points * POINT_DATA_SIZE)))
+ uint32 n_points;
+ if (no_data(m_data, 4))
return GET_SIZE_ERROR;
- return size;
+
+ n_points= uint4korr(m_data);
+
+ if (not_enough_points(m_data + 4, n_points))
+ return GET_SIZE_ERROR;
+
+ return 4 + n_points * POINT_DATA_SIZE;
}
@@ -607,9 +610,8 @@ uint Gis_line_string::init_from_wkb(const char *wkb, uint len,
const char *wkb_end;
Gis_point p;
- if (len < 4 ||
- (n_points= wkb_get_uint(wkb, bo)) < 1 ||
- n_points > max_n_points)
+ if (len < 4 || (n_points= wkb_get_uint(wkb, bo)) < 1 ||
+ ((len - 4) / POINT_DATA_SIZE) < n_points)
return 0;
proper_length= 4 + n_points * POINT_DATA_SIZE;
@@ -638,8 +640,8 @@ bool Gis_line_string::get_data_as_wkt(String *txt, const char **end) const
n_points= uint4korr(data);
data += 4;
- if (n_points < 1 || n_points > max_n_points ||
- no_data(data, POINT_DATA_SIZE * n_points) ||
+ if (n_points < 1 ||
+ not_enough_points(data, n_points) ||
txt->reserve(((MAX_DIGITS_IN_DOUBLE + 1)*2 + 1) * n_points))
return 1;
@@ -676,8 +678,7 @@ int Gis_line_string::geom_length(double *len, const char **end) const
return 1;
n_points= uint4korr(data);
data+= 4;
- if (n_points < 1 || n_points > max_n_points ||
- no_data(data, POINT_DATA_SIZE * n_points))
+ if (n_points < 1 || not_enough_points(data, n_points))
return 1;
get_point(&prev_x, &prev_y, data);
@@ -725,8 +726,7 @@ int Gis_line_string::is_closed(int *closed) const
return 0;
}
data+= 4;
- if (n_points == 0 || n_points > max_n_points ||
- no_data(data, POINT_DATA_SIZE * n_points))
+ if (n_points == 0 || not_enough_points(data, n_points))
return 1;
/* Get first point */
@@ -761,8 +761,7 @@ int Gis_line_string::end_point(String *result) const
if (no_data(m_data, 4))
return 1;
n_points= uint4korr(m_data);
- if (n_points == 0 || n_points > max_n_points ||
- no_data(m_data, POINT_DATA_SIZE * n_points))
+ if (n_points == 0 || not_enough_points(m_data+4, n_points))
return 1;
return create_point(result, m_data + 4 + (n_points - 1) * POINT_DATA_SIZE);
}
@@ -775,9 +774,7 @@ int Gis_line_string::point_n(uint32 num, String *result) const
return 1;
num--;
n_points= uint4korr(m_data);
- if (num >= n_points ||
- num > max_n_points || // means (num > n_points || num < 1)
- no_data(m_data, num * POINT_DATA_SIZE))
+ if (num >= n_points || not_enough_points(m_data+4, n_points))
return 1;
return create_point(result, m_data + 4 + num*POINT_DATA_SIZE);
@@ -796,8 +793,7 @@ int Gis_line_string::store_shapes(Gcalc_shape_transporter *trn) const
return 1;
n_points= uint4korr(data);
data+= 4;
- if (n_points < 1 || n_points > max_n_points ||
- no_data(data, POINT_DATA_SIZE * n_points))
+ if (n_points < 1 || no_data(data, POINT_DATA_SIZE * n_points))
return 1;
trn->start_line();
@@ -840,7 +836,7 @@ uint32 Gis_polygon::get_data_size() const
while (n_linear_rings--)
{
if (no_data(data, 4) ||
- (n_points= uint4korr(data)) > max_n_points)
+ not_enough_points(data+4, n_points= uint4korr(data)))
return GET_SIZE_ERROR;
data+= 4 + n_points*POINT_DATA_SIZE;
}
@@ -986,7 +982,7 @@ bool Gis_polygon::get_data_as_wkt(String *txt, const char **end) const
return 1;
n_points= uint4korr(data);
data+= 4;
- if (n_points > max_n_points || no_data(data, POINT_DATA_SIZE * n_points) ||
+ if (not_enough_points(data, n_points) ||
txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points))
return 1;
txt->qs_append('(');
@@ -1040,8 +1036,8 @@ int Gis_polygon::area(double *ar, const char **end_of_data) const
if (no_data(data, 4))
return 1;
n_points= uint4korr(data);
- if (n_points == 0 || n_points > max_n_points ||
- no_data(data, POINT_DATA_SIZE * n_points))
+ if (n_points == 0 ||
+ not_enough_points(data, n_points))
return 1;
get_point(&prev_x, &prev_y, data+4);
data+= (4+POINT_DATA_SIZE);
@@ -1077,8 +1073,7 @@ int Gis_polygon::exterior_ring(String *result) const
n_points= uint4korr(data);
data+= 4;
length= n_points * POINT_DATA_SIZE;
- if (n_points > max_n_points ||
- no_data(data, length) || result->reserve(1 + 4 + 4 + length))
+ if (not_enough_points(data, n_points) || result->reserve(1+4+4+ length))
return 1;
result->q_append((char) wkb_ndr);
@@ -1124,8 +1119,7 @@ int Gis_polygon::interior_ring_n(uint32 num, String *result) const
n_points= uint4korr(data);
points_size= n_points * POINT_DATA_SIZE;
data+= 4;
- if (n_points > max_n_points ||
- no_data(data, points_size) || result->reserve(1 + 4 + 4 + points_size))
+ if (not_enough_points(data, n_points) || result->reserve(1+4+4+ points_size))
return 1;
result->q_append((char) wkb_ndr);
@@ -1162,8 +1156,7 @@ int Gis_polygon::centroid_xy(double *x, double *y) const
return 1;
org_n_points= n_points= uint4korr(data);
data+= 4;
- if (n_points == 0 || n_points > max_n_points ||
- no_data(data, POINT_DATA_SIZE * n_points))
+ if (n_points == 0 || not_enough_points(data, n_points))
return 1;
get_point(&prev_x, &prev_y, data);
data+= POINT_DATA_SIZE;
@@ -1237,8 +1230,7 @@ int Gis_polygon::store_shapes(Gcalc_shape_transporter *trn) const
return 1;
n_points= uint4korr(data);
data+= 4;
- if (!n_points || n_points > max_n_points ||
- no_data(data, POINT_DATA_SIZE * n_points))
+ if (!n_points || no_data(data, POINT_DATA_SIZE * n_points))
return 1;
trn->start_ring();
@@ -1292,13 +1284,12 @@ const Geometry::Class_info *Gis_polygon::get_class_info() const
uint32 Gis_multi_point::get_data_size() const
{
uint32 n_points;
- uint32 size;
if (no_data(m_data, 4) ||
- (n_points= uint4korr(m_data)) > max_n_points ||
- no_data(m_data, (size= 4 + n_points*(POINT_DATA_SIZE + WKB_HEADER_SIZE))))
+ not_enough_points(m_data+4, (n_points= uint4korr(m_data)),
+ WKB_HEADER_SIZE))
return GET_SIZE_ERROR;
- return size;
+ return 4 + n_points * (POINT_DATA_SIZE + WKB_HEADER_SIZE);
}
@@ -1393,7 +1384,7 @@ bool Gis_multi_point::get_data_as_wkt(String *txt, const char **end) const
n_points= uint4korr(m_data);
if (n_points > max_n_points ||
- no_data(m_data+4, n_points * (POINT_DATA_SIZE + WKB_HEADER_SIZE)) ||
+ not_enough_points(m_data+4, n_points, WKB_HEADER_SIZE) ||
txt->reserve(((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points))
return 1;
*end= append_points(txt, n_points, m_data+4, WKB_HEADER_SIZE);
@@ -1485,7 +1476,8 @@ uint32 Gis_multi_line_string::get_data_size() const
while (n_line_strings--)
{
if (no_data(data, WKB_HEADER_SIZE + 4) ||
- (n_points= uint4korr(data + WKB_HEADER_SIZE)) > max_n_points)
+ not_enough_points(data + WKB_HEADER_SIZE+4,
+ (n_points= uint4korr(data + WKB_HEADER_SIZE))))
return GET_SIZE_ERROR;
data+= (WKB_HEADER_SIZE + 4 + n_points*POINT_DATA_SIZE);
}
@@ -1614,7 +1606,7 @@ bool Gis_multi_line_string::get_data_as_wkt(String *txt,
return 1;
n_points= uint4korr(data + WKB_HEADER_SIZE);
data+= WKB_HEADER_SIZE + 4;
- if (n_points > max_n_points || no_data(data, n_points * POINT_DATA_SIZE) ||
+ if (not_enough_points(data, n_points) ||
txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points))
return 1;
txt->qs_append('(');
@@ -1675,7 +1667,7 @@ int Gis_multi_line_string::geometry_n(uint32 num, String *result) const
return 1;
n_points= uint4korr(data + WKB_HEADER_SIZE);
length= WKB_HEADER_SIZE + 4+ POINT_DATA_SIZE * n_points;
- if (n_points > max_n_points || no_data(data, length))
+ if (not_enough_points(data+WKB_HEADER_SIZE+4, n_points))
return 1;
if (!--num)
break;
@@ -1806,7 +1798,7 @@ uint32 Gis_multi_polygon::get_data_size() const
while (n_linear_rings--)
{
if (no_data(data, 4) ||
- (n_points= uint4korr(data)) > max_n_points)
+ not_enough_points(data+4, (n_points= uint4korr(data))))
return GET_SIZE_ERROR;
data+= 4 + n_points * POINT_DATA_SIZE;
}
@@ -1940,8 +1932,7 @@ bool Gis_multi_polygon::get_data_as_wkt(String *txt, const char **end) const
return 1;
uint32 n_points= uint4korr(data);
data+= 4;
- if (n_points > max_n_points ||
- no_data(data, POINT_DATA_SIZE * n_points) ||
+ if (not_enough_points(data, n_points) ||
txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points,
512))
return 1;
@@ -2024,7 +2015,7 @@ int Gis_multi_polygon::geometry_n(uint32 num, String *result) const
if (no_data(data, 4))
return 1;
n_points= uint4korr(data);
- if (n_points > max_n_points)
+ if (not_enough_points(data + 4, n_points))
return 1;
data+= 4 + POINT_DATA_SIZE * n_points;
}
diff --git a/sql/spatial.h b/sql/spatial.h
index 6df6e37e9b8..ee2d6d5ec8d 100644
--- a/sql/spatial.h
+++ b/sql/spatial.h
@@ -214,11 +214,6 @@ struct Geometry_buffer;
class Geometry
{
public:
- // Maximum number of points in feature that can fit into String
- static const uint32 max_n_points=
- (uint32) (INT_MAX32 - WKB_HEADER_SIZE - 4 /* n_points */) /
- POINT_DATA_SIZE;
-
Geometry() {} /* Remove gcc warning */
virtual ~Geometry() {} /* Remove gcc warning */
static void *operator new(size_t size, void *buffer)
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index d98c2d88781..2c6364ed61f 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -6085,8 +6085,8 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
LEX_USER *user_from, LEX_USER *user_to)
{
int result= 0;
- uint idx;
- uint elements;
+ int idx;
+ int elements;
const char *user;
const char *host;
ACL_USER *acl_user= NULL;
@@ -6135,8 +6135,8 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
DBUG_PRINT("loop",("scan struct: %u search user: '%s' host: '%s'",
struct_no, user_from->user.str, user_from->host.str));
#endif
- /* Loop over all elements. */
- for (idx= 0; idx < elements; idx++)
+ /* Loop over all elements *backwards* (see the comment below). */
+ for (idx= elements - 1; idx >= 0; idx--)
{
/*
Get a pointer to the element.
@@ -6187,6 +6187,7 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
result= 1; /* At least one element found. */
if ( drop )
{
+ elements--;
switch ( struct_no ) {
case USER_ACL:
delete_dynamic_element(&acl_users, idx);
@@ -6200,6 +6201,15 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
case PROC_PRIVILEGES_HASH:
case FUNC_PRIVILEGES_HASH:
my_hash_delete(grant_name_hash, (uchar*) grant_name);
+ /*
+ In our HASH implementation on deletion one elements
+ is moved into a place where a deleted element was,
+ and the last element is moved into the empty space.
+ Thus we need to re-examine the current element, but
+ we don't have to restart the search from the beginning.
+ */
+ if (idx != elements)
+ idx++;
break;
case PROXY_USERS_ACL:
@@ -6207,21 +6217,6 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
break;
}
- elements--;
- /*
- - If we are iterating through an array then we just have moved all
- elements after the current element one position closer to its head.
- This means that we have to take another look at the element at
- current position as it is a new element from the array's tail.
- - If we are iterating through a hash the current element was replaced
- with one of elements from the tail. So we also have to take a look
- at the new element in current position.
- Note that in our HASH implementation hash_delete() won't move any
- elements with position after current one to position before the
- current (i.e. from the tail to the head), so it is safe to continue
- iteration without re-starting.
- */
- idx--;
}
else if ( user_to )
{
@@ -6262,15 +6257,15 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
my_hash_update(grant_name_hash, (uchar*) grant_name, (uchar*) old_key,
old_key_length);
/*
- hash_update() operation could have moved element from the tail
- of the hash to the current position. So we need to take a look
- at the element in current position once again.
- Thanks to the fact that hash_update() for our HASH implementation
- won't move any elements from the tail of the hash to the positions
- before the current one (a.k.a. head) it is safe to continue
- iteration without restarting.
+ hash_update() operation could have moved element from the tail or
+ the head of the hash to the current position. But it can never
+ move an element from the head to the tail or from the tail to the
+ head over the current element.
+ So we need to examine the current element once again, but
+ we don't need to restart the search from the beginning.
*/
- idx--;
+ if (idx != elements)
+ idx++;
break;
}
diff --git a/sql/sql_audit.cc b/sql/sql_audit.cc
index 07a5243e836..f0e35cb022f 100644
--- a/sql/sql_audit.cc
+++ b/sql/sql_audit.cc
@@ -82,6 +82,9 @@ static void general_class_handler(THD *thd, uint event_subtype, va_list ap)
event.general_query_length= va_arg(ap, unsigned int);
event.general_charset= va_arg(ap, struct charset_info_st *);
event.general_rows= (unsigned long long) va_arg(ap, ha_rows);
+ event.database= va_arg(ap, const char *);
+ event.database_length= va_arg(ap, unsigned int);
+ event.query_id= (unsigned long long) thd->query_id;
event_class_dispatch(thd, MYSQL_AUDIT_GENERAL_CLASS, &event);
}
@@ -131,6 +134,7 @@ static void table_class_handler(THD *thd, uint event_subclass, va_list ap)
event.new_database_length= va_arg(ap, unsigned int);
event.new_table= va_arg(ap, const char *);
event.new_table_length= va_arg(ap, unsigned int);
+ event.query_id= (unsigned long long) thd->query_id;
event_class_dispatch(thd, MYSQL_AUDIT_TABLE_CLASS, &event);
}
diff --git a/sql/sql_audit.h b/sql/sql_audit.h
index 22fdd221e62..f71b09f740b 100644
--- a/sql/sql_audit.h
+++ b/sql/sql_audit.h
@@ -99,7 +99,8 @@ void mysql_audit_general_log(THD *thd, time_t time,
mysql_audit_notify(thd, MYSQL_AUDIT_GENERAL_CLASS, MYSQL_AUDIT_GENERAL_LOG,
0, time, user, userlen, cmd, cmdlen,
- query, querylen, clientcs, 0);
+ query, querylen, clientcs, (ha_rows) 0,
+ thd->db, thd->db_length);
}
}
@@ -145,7 +146,8 @@ void mysql_audit_general(THD *thd, uint event_subtype,
mysql_audit_notify(thd, MYSQL_AUDIT_GENERAL_CLASS, event_subtype,
error_code, time, user, userlen, msg, msglen,
- query.str(), query.length(), query.charset(), rows);
+ query.str(), query.length(), query.charset(), rows,
+ thd->db, thd->db_length);
}
}
@@ -175,10 +177,18 @@ void mysql_audit_notify_connection_disconnect(THD *thd, int errcode)
{
if (mysql_audit_connection_enabled())
{
+ const Security_context *sctx= thd->security_ctx;
mysql_audit_notify(thd, MYSQL_AUDIT_CONNECTION_CLASS,
MYSQL_AUDIT_CONNECTION_DISCONNECT,
errcode, thd->thread_id,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ sctx->user, sctx->user ? strlen(sctx->user) : 0,
+ sctx->priv_user, strlen(sctx->priv_user),
+ sctx->external_user,
+ sctx->external_user ? strlen(sctx->external_user) : 0,
+ sctx->proxy_user, strlen(sctx->proxy_user),
+ sctx->host, sctx->host ? strlen(sctx->host) : 0,
+ sctx->ip, sctx->ip ? strlen(sctx->ip) : 0,
+ thd->db, thd->db ? strlen(thd->db) : 0);
}
}
diff --git a/sql/sql_bitmap.h b/sql/sql_bitmap.h
index 5e86a889053..7e163b0dbcc 100644
--- a/sql/sql_bitmap.h
+++ b/sql/sql_bitmap.h
@@ -72,6 +72,7 @@ public:
bool is_subset(const Bitmap& map2) const { return bitmap_is_subset(&map, &map2.map); }
bool is_overlapping(const Bitmap& map2) const { return bitmap_is_overlapping(&map, &map2.map); }
bool operator==(const Bitmap& map2) const { return bitmap_cmp(&map, &map2.map); }
+ bool operator!=(const Bitmap& map2) const { return !(*this == map2); }
char *print(char *buf) const
{
char *s=buf;
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 08e8fbe7361..2354b30a263 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -3502,7 +3502,8 @@ select_materialize_with_stats::
create_result_table(THD *thd_arg, List<Item> *column_types,
bool is_union_distinct, ulonglong options,
const char *table_alias, bool bit_fields_as_long,
- bool create_table)
+ bool create_table,
+ bool keep_row_order)
{
DBUG_ASSERT(table == 0);
tmp_table_param.field_count= column_types->elements;
@@ -3510,7 +3511,8 @@ create_result_table(THD *thd_arg, List<Item> *column_types,
if (! (table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
(ORDER*) 0, is_union_distinct, 1,
- options, HA_POS_ERROR, (char*) table_alias)))
+ options, HA_POS_ERROR, (char*) table_alias,
+ keep_row_order)))
return TRUE;
col_stat= (Column_statistics*) table->in_use->alloc(table->s->fields *
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 02a2d2d8b3f..0958e5184f7 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -3744,7 +3744,8 @@ public:
bool is_distinct, ulonglong options,
const char *alias,
bool bit_fields_as_long,
- bool create_table);
+ bool create_table,
+ bool keep_row_order= FALSE);
TMP_TABLE_PARAM *get_tmp_table_param() { return &tmp_table_param; }
};
@@ -3814,7 +3815,8 @@ public:
bool is_distinct, ulonglong options,
const char *alias,
bool bit_fields_as_long,
- bool create_table);
+ bool create_table,
+ bool keep_row_order= FALSE);
bool init_result_table(ulonglong select_options);
int send_data(List<Item> &items);
void cleanup();
diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc
index 3758bf27819..230a8b2c802 100644
--- a/sql/sql_cursor.cc
+++ b/sql/sql_cursor.cc
@@ -389,7 +389,7 @@ bool Select_materialize::send_result_set_metadata(List<Item> &list, uint flags)
if (create_result_table(unit->thd, unit->get_unit_column_types(),
FALSE,
thd->variables.option_bits | TMP_TABLE_ALL_COLUMNS,
- "", FALSE, TRUE))
+ "", FALSE, TRUE, TRUE))
return TRUE;
materialized_cursor= new (&table->mem_root)
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 18908abbfcd..aa1fe292564 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -30,7 +30,7 @@
#include "sp.h"
#include "sql_select.h"
-static int lex_one_token(void *arg, void *yythd);
+static int lex_one_token(void *arg, THD *thd);
/*
We are using pointer to this variable for distinguishing between assignment
@@ -959,9 +959,8 @@ bool consume_comment(Lex_input_stream *lip, int remaining_recursions_permitted)
(which can't be followed by a signed number)
*/
-int MYSQLlex(void *arg, void *yythd)
+int MYSQLlex(void *arg, THD *thd)
{
- THD *thd= (THD *)yythd;
Lex_input_stream *lip= & thd->m_parser_state->m_lip;
YYSTYPE *yylval=(YYSTYPE*) arg;
int token;
@@ -979,7 +978,7 @@ int MYSQLlex(void *arg, void *yythd)
return token;
}
- token= lex_one_token(arg, yythd);
+ token= lex_one_token(arg, thd);
switch(token) {
case WITH:
@@ -990,7 +989,7 @@ int MYSQLlex(void *arg, void *yythd)
to transform the grammar into a LALR(1) grammar,
which sql_yacc.yy can process.
*/
- token= lex_one_token(arg, yythd);
+ token= lex_one_token(arg, thd);
switch(token) {
case CUBE_SYM:
return WITH_CUBE_SYM;
@@ -1013,14 +1012,13 @@ int MYSQLlex(void *arg, void *yythd)
return token;
}
-int lex_one_token(void *arg, void *yythd)
+int lex_one_token(void *arg, THD *thd)
{
reg1 uchar c;
bool comment_closed;
int tokval, result_state;
uint length;
enum my_lex_states state;
- THD *thd= (THD *)yythd;
Lex_input_stream *lip= & thd->m_parser_state->m_lip;
LEX *lex= thd->lex;
YYSTYPE *yylval=(YYSTYPE*) arg;
@@ -3787,10 +3785,7 @@ void SELECT_LEX::mark_as_belong_to_derived(TABLE_LIST *derived)
TABLE_LIST *tl;
List_iterator<TABLE_LIST> ti(leaf_tables);
while ((tl= ti++))
- {
- tl->open_type= OT_BASE_ONLY;
tl->belong_to_derived= derived;
- }
}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index a2c5181443d..2b742e80603 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -2961,7 +2961,7 @@ extern void lex_start(THD *thd);
extern void lex_end(LEX *lex);
void end_lex_with_single_table(THD *thd, TABLE *table, LEX *old_lex);
int init_lex_with_single_table(THD *thd, TABLE *table, LEX *lex);
-extern int MYSQLlex(void *arg, void *yythd);
+extern int MYSQLlex(void *arg, THD *thd);
extern void trim_whitespace(CHARSET_INFO *cs, LEX_STRING *str);
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index af6e5d5a411..774f1b2a56d 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -1,5 +1,6 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2000, 2013, Oracle and/or its affiliates.
+ Copyright (c) 2010, 2013, Monty Progrm Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 4a64ee30929..3f79bbb55eb 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -7862,7 +7862,7 @@ bool check_host_name(LEX_STRING *str)
}
-extern int MYSQLparse(void *thd); // from sql_yacc.cc
+extern int MYSQLparse(THD *thd); // from sql_yacc.cc
/**
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 2734e998e44..454ff7c443c 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -173,7 +173,8 @@ int get_part_iter_for_interval_via_walking(partition_info *part_info,
static int cmp_rec_and_tuple(part_column_list_val *val, uint32 nvals_in_rec);
static int cmp_rec_and_tuple_prune(part_column_list_val *val,
uint32 n_vals_in_rec,
- bool tail_is_min);
+ bool is_left_endpoint,
+ bool include_endpoint);
/*
Convert constants in VALUES definition to the character set the
@@ -3222,44 +3223,6 @@ notfound:
}
-/*
- Find the sub-array part_info->list_array that corresponds to given interval
-
- SYNOPSIS
- get_list_array_idx_for_endpoint()
- part_info Partitioning info (partitioning type must be LIST)
- left_endpoint TRUE - the interval is [a; +inf) or (a; +inf)
- FALSE - the interval is (-inf; a] or (-inf; a)
- include_endpoint TRUE iff the interval includes the endpoint
-
- DESCRIPTION
- This function finds the sub-array of part_info->list_array where values of
- list_array[idx].list_value are contained within the specifed interval.
- list_array is ordered by list_value, so
- 1. For [a; +inf) or (a; +inf)-type intervals (left_endpoint==TRUE), the
- sought sub-array starts at some index idx and continues till array end.
- The function returns first number idx, such that
- list_array[idx].list_value is contained within the passed interval.
-
- 2. For (-inf; a] or (-inf; a)-type intervals (left_endpoint==FALSE), the
- sought sub-array starts at array start and continues till some last
- index idx.
- The function returns first number idx, such that
- list_array[idx].list_value is NOT contained within the passed interval.
- If all array elements are contained, part_info->num_list_values is
- returned.
-
- NOTE
- The caller will call this function and then will run along the sub-array of
- list_array to collect partition ids. If the number of list values is
- significantly higher then number of partitions, this could be slow and
- we could invent some other approach. The "run over list array" part is
- already wrapped in a get_next()-like function.
-
- RETURN
- The edge of corresponding sub-array of part_info->list_array
-*/
-
uint32 get_partition_id_cols_list_for_endpoint(partition_info *part_info,
bool left_endpoint,
bool include_endpoint,
@@ -3267,37 +3230,81 @@ uint32 get_partition_id_cols_list_for_endpoint(partition_info *part_info,
{
part_column_list_val *list_col_array= part_info->list_col_array;
uint num_columns= part_info->part_field_list.elements;
- int list_index, cmp;
+ uint list_index;
uint min_list_index= 0;
- uint max_list_index= part_info->num_list_values - 1;
- bool tailf= !(left_endpoint ^ include_endpoint);
+ uint max_list_index= part_info->num_list_values;
DBUG_ENTER("get_partition_id_cols_list_for_endpoint");
+ /* Find the matching partition (including taking endpoint into account). */
do
{
+ /* Midpoint, adjusted down, so it can never be > last index. */
list_index= (max_list_index + min_list_index) >> 1;
- cmp= cmp_rec_and_tuple_prune(list_col_array + list_index*num_columns,
- nparts, tailf);
- if (cmp > 0)
+ if (cmp_rec_and_tuple_prune(list_col_array + list_index*num_columns,
+ nparts, left_endpoint, include_endpoint) > 0)
min_list_index= list_index + 1;
- else if (cmp < 0)
- {
- if (!list_index)
- goto notfound;
- max_list_index= list_index - 1;
- }
- else
- {
- DBUG_RETURN(list_index + test(!tailf));
- }
- } while (max_list_index >= min_list_index);
- if (cmp > 0)
- list_index++;
-notfound:
+ else
+ max_list_index= list_index;
+ } while (max_list_index > min_list_index);
+ list_index= max_list_index;
+
+ /* Given value must be LESS THAN or EQUAL to the found partition. */
+ DBUG_ASSERT(list_index == part_info->num_list_values ||
+ (0 >= cmp_rec_and_tuple_prune(list_col_array +
+ list_index*num_columns,
+ nparts, left_endpoint,
+ include_endpoint)));
+ /* Given value must be GREATER THAN the previous partition. */
+ DBUG_ASSERT(list_index == 0 ||
+ (0 < cmp_rec_and_tuple_prune(list_col_array +
+ (list_index - 1)*num_columns,
+ nparts, left_endpoint,
+ include_endpoint)));
+
+ if (!left_endpoint)
+ {
+ /* Set the end after this list tuple if not already after the last. */
+ if (list_index < part_info->num_parts)
+ list_index++;
+ }
+
DBUG_RETURN(list_index);
}
+/**
+ Find the sub-array part_info->list_array that corresponds to given interval.
+
+ @param part_info Partitioning info (partitioning type must be LIST)
+ @param left_endpoint TRUE - the interval is [a; +inf) or (a; +inf)
+ FALSE - the interval is (-inf; a] or (-inf; a)
+ @param include_endpoint TRUE iff the interval includes the endpoint
+
+ This function finds the sub-array of part_info->list_array where values of
+ list_array[idx].list_value are contained within the specifed interval.
+ list_array is ordered by list_value, so
+ 1. For [a; +inf) or (a; +inf)-type intervals (left_endpoint==TRUE), the
+ sought sub-array starts at some index idx and continues till array end.
+ The function returns first number idx, such that
+ list_array[idx].list_value is contained within the passed interval.
+
+ 2. For (-inf; a] or (-inf; a)-type intervals (left_endpoint==FALSE), the
+ sought sub-array starts at array start and continues till some last
+ index idx.
+ The function returns first number idx, such that
+ list_array[idx].list_value is NOT contained within the passed interval.
+ If all array elements are contained, part_info->num_list_values is
+ returned.
+
+ @note The caller will call this function and then will run along the
+ sub-array of list_array to collect partition ids. If the number of list
+ values is significantly higher then number of partitions, this could be slow
+ and we could invent some other approach. The "run over list array" part is
+ already wrapped in a get_next()-like function.
+
+ @return The index of corresponding sub-array of part_info->list_array.
+*/
+
uint32 get_list_array_idx_for_endpoint_charset(partition_info *part_info,
bool left_endpoint,
bool include_endpoint)
@@ -7340,15 +7347,17 @@ uint32 store_tuple_to_record(Field **pfield,
return nparts;
}
-/*
- RANGE(columns) partitioning: compare value bound and probe tuple.
+/**
+ RANGE(columns) partitioning: compare partition value bound and probe tuple.
+
+ @param val Partition column values.
+ @param nvals_in_rec Number of (prefix) fields to compare.
- The value bound always is a full tuple (but may include the MAXVALUE
- special value).
+ @return Less than/Equal to/Greater than 0 if the record is L/E/G than val.
- The probe tuple may be a prefix of partitioning tuple. The tail_is_min
- parameter specifies whether the suffix components should be assumed to
- hold MAXVALUE
+ @note The partition value bound is always a full tuple (but may include the
+ MAXVALUE special value). The probe tuple may be a prefix of partitioning
+ tuple.
*/
static int cmp_rec_and_tuple(part_column_list_val *val, uint32 nvals_in_rec)
@@ -7378,25 +7387,73 @@ static int cmp_rec_and_tuple(part_column_list_val *val, uint32 nvals_in_rec)
}
+/**
+ Compare record and columns partition tuple including endpoint handling.
+
+ @param val Columns partition tuple
+ @param n_vals_in_rec Number of columns to compare
+ @param is_left_endpoint True if left endpoint (part_tuple < rec or
+ part_tuple <= rec)
+ @param include_endpoint If endpoint is included (part_tuple <= rec or
+ rec <= part_tuple)
+
+ @return Less than/Equal to/Greater than 0 if the record is L/E/G than
+ the partition tuple.
+
+ @see get_list_array_idx_for_endpoint() and
+ get_partition_id_range_for_endpoint().
+*/
+
static int cmp_rec_and_tuple_prune(part_column_list_val *val,
uint32 n_vals_in_rec,
- bool tail_is_min)
+ bool is_left_endpoint,
+ bool include_endpoint)
{
int cmp;
Field **field;
- partition_info *part_info;
if ((cmp= cmp_rec_and_tuple(val, n_vals_in_rec)))
return cmp;
- part_info= val->part_info;
- field= part_info->part_field_array + n_vals_in_rec;
- for (; *field; field++, val++)
+ field= val->part_info->part_field_array + n_vals_in_rec;
+ if (!(*field))
{
- if (tail_is_min)
- return -1;
- if (!tail_is_min && !val->max_value)
- return +1;
+ /*
+ Full match, if right endpoint and not including the endpoint,
+ (rec < part) return lesser.
+ */
+ if (!is_left_endpoint && !include_endpoint)
+ return -4;
+
+ /* Otherwise they are equal! */
+ return 0;
}
- return 0;
+ /*
+ The prefix is equal and there are more partition columns to compare.
+
+ If including left endpoint or not including right endpoint
+ then the record is considered lesser compared to the partition.
+
+ i.e:
+ part(10, x) <= rec(10, unknown) and rec(10, unknown) < part(10, x)
+ part <= rec -> lesser (i.e. this or previous partitions)
+ rec < part -> lesser (i.e. this or previous partitions)
+ */
+ if (is_left_endpoint == include_endpoint)
+ return -2;
+
+ /*
+ If right endpoint and the first additional partition value
+ is MAXVALUE, then the record is lesser.
+ */
+ if (!is_left_endpoint && (val + n_vals_in_rec)->max_value)
+ return -3;
+
+ /*
+ Otherwise the record is considered greater.
+
+ rec <= part -> greater (i.e. does not match this partition, seek higher).
+ part < rec -> greater (i.e. does not match this partition, seek higher).
+ */
+ return 2;
}
@@ -7407,91 +7464,65 @@ typedef uint32 (*get_col_endpoint_func)(partition_info*, bool left_endpoint,
bool include_endpoint,
uint32 num_parts);
-/*
- Partitioning Interval Analysis: Initialize the iterator for "mapping" case
+/**
+ Get partition for RANGE COLUMNS endpoint.
- SYNOPSIS
- get_part_iter_for_interval_via_mapping()
- part_info Partition info
- is_subpart TRUE - act for subpartitioning
- FALSE - act for partitioning
- min_value minimum field value, in opt_range key format.
- max_value minimum field value, in opt_range key format.
- flags Some combination of NEAR_MIN, NEAR_MAX, NO_MIN_RANGE,
- NO_MAX_RANGE.
- part_iter Iterator structure to be initialized
+ @param part_info Partitioning metadata.
+ @param is_left_endpoint True if left endpoint (const <=/< cols)
+ @param include_endpoint True if range includes the endpoint (<=/>=)
+ @param nparts Total number of partitions
- DESCRIPTION
- Initialize partition set iterator to walk over the interval in
- ordered-array-of-partitions (for RANGE partitioning) or
- ordered-array-of-list-constants (for LIST partitioning) space.
+ @return Partition id of matching partition.
- IMPLEMENTATION
- This function is used when partitioning is done by
- <RANGE|LIST>(ascending_func(t.field)), and we can map an interval in
- t.field space into a sub-array of partition_info::range_int_array or
- partition_info::list_array (see get_partition_id_range_for_endpoint,
- get_list_array_idx_for_endpoint for details).
-
- The function performs this interval mapping, and sets the iterator to
- traverse the sub-array and return appropriate partitions.
-
- RETURN
- 0 - No matching partitions (iterator not initialized)
- 1 - Ok, iterator intialized for traversal of matching partitions.
- -1 - All partitions would match (iterator not initialized)
+ @see get_partition_id_cols_list_for_endpoint and
+ get_partition_id_range_for_endpoint.
*/
uint32 get_partition_id_cols_range_for_endpoint(partition_info *part_info,
- bool left_endpoint,
+ bool is_left_endpoint,
bool include_endpoint,
uint32 nparts)
{
- uint max_partition= part_info->num_parts - 1;
- uint min_part_id= 0, max_part_id= max_partition, loc_part_id;
+ uint min_part_id= 0, max_part_id= part_info->num_parts, loc_part_id;
part_column_list_val *range_col_array= part_info->range_col_array;
uint num_columns= part_info->part_field_list.elements;
- bool tailf= !(left_endpoint ^ include_endpoint);
DBUG_ENTER("get_partition_id_cols_range_for_endpoint");
- /* Get the partitioning function value for the endpoint */
- while (max_part_id > min_part_id)
+ /* Find the matching partition (including taking endpoint into account). */
+ do
{
- loc_part_id= (max_part_id + min_part_id + 1) >> 1;
- if (cmp_rec_and_tuple_prune(range_col_array + loc_part_id*num_columns,
- nparts, tailf) >= 0)
+ /* Midpoint, adjusted down, so it can never be > last partition. */
+ loc_part_id= (max_part_id + min_part_id) >> 1;
+ if (0 <= cmp_rec_and_tuple_prune(range_col_array +
+ loc_part_id * num_columns,
+ nparts,
+ is_left_endpoint,
+ include_endpoint))
min_part_id= loc_part_id + 1;
else
- max_part_id= loc_part_id - 1;
- }
+ max_part_id= loc_part_id;
+ } while (max_part_id > min_part_id);
loc_part_id= max_part_id;
- if (loc_part_id < max_partition &&
- cmp_rec_and_tuple_prune(range_col_array + (loc_part_id+1)*num_columns,
- nparts, tailf) >= 0
- )
- {
- loc_part_id++;
- }
- if (left_endpoint)
- {
- if (cmp_rec_and_tuple_prune(range_col_array + loc_part_id*num_columns,
- nparts, tailf) >= 0)
+
+ /* Given value must be LESS THAN the found partition. */
+ DBUG_ASSERT(loc_part_id == part_info->num_parts ||
+ (0 > cmp_rec_and_tuple_prune(range_col_array +
+ loc_part_id * num_columns,
+ nparts, is_left_endpoint,
+ include_endpoint)));
+ /* Given value must be GREATER THAN or EQUAL to the previous partition. */
+ DBUG_ASSERT(loc_part_id == 0 ||
+ (0 <= cmp_rec_and_tuple_prune(range_col_array +
+ (loc_part_id - 1) * num_columns,
+ nparts, is_left_endpoint,
+ include_endpoint)));
+
+ if (!is_left_endpoint)
+ {
+ /* Set the end after this partition if not already after the last. */
+ if (loc_part_id < part_info->num_parts)
loc_part_id++;
}
- else
- {
- if (loc_part_id < max_partition)
- {
- int res= cmp_rec_and_tuple_prune(range_col_array +
- loc_part_id * num_columns,
- nparts, tailf);
- if (!res)
- loc_part_id += test(include_endpoint);
- else if (res > 0)
- loc_part_id++;
- }
- loc_part_id++;
- }
DBUG_RETURN(loc_part_id);
}
@@ -7563,6 +7594,40 @@ int get_part_iter_for_interval_cols_via_map(partition_info *part_info,
}
+/**
+ Partitioning Interval Analysis: Initialize the iterator for "mapping" case
+
+ @param part_info Partition info
+ @param is_subpart TRUE - act for subpartitioning
+ FALSE - act for partitioning
+ @param store_length_array Ignored.
+ @param min_value minimum field value, in opt_range key format.
+ @param max_value minimum field value, in opt_range key format.
+ @param min_len Ignored.
+ @param max_len Ignored.
+ @param flags Some combination of NEAR_MIN, NEAR_MAX, NO_MIN_RANGE,
+ NO_MAX_RANGE.
+ @param part_iter Iterator structure to be initialized
+
+ @details Initialize partition set iterator to walk over the interval in
+ ordered-array-of-partitions (for RANGE partitioning) or
+ ordered-array-of-list-constants (for LIST partitioning) space.
+
+ This function is used when partitioning is done by
+ <RANGE|LIST>(ascending_func(t.field)), and we can map an interval in
+ t.field space into a sub-array of partition_info::range_int_array or
+ partition_info::list_array (see get_partition_id_range_for_endpoint,
+ get_list_array_idx_for_endpoint for details).
+
+ The function performs this interval mapping, and sets the iterator to
+ traverse the sub-array and return appropriate partitions.
+
+ @return Status of iterator
+ @retval 0 No matching partitions (iterator not initialized)
+ @retval 1 Ok, iterator intialized for traversal of matching partitions.
+ @retval -1 All partitions would match (iterator not initialized)
+*/
+
int get_part_iter_for_interval_via_mapping(partition_info *part_info,
bool is_subpart,
uint32 *store_length_array, /* ignored */
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index a66fa5f63dd..4b7963f91f4 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -175,8 +175,7 @@ static struct
/* we disable few other plugins by default */
{ "ndbcluster", PLUGIN_OFF },
- { "feedback", PLUGIN_OFF },
- { "pbxt", PLUGIN_OFF }
+ { "feedback", PLUGIN_OFF }
};
/* support for Services */
@@ -690,6 +689,8 @@ static my_bool read_maria_plugin_info(struct st_plugin_dl *plugin_dl,
sym= cur;
plugin_dl->allocated= true;
}
+ else
+ sym= ptr;
}
plugin_dl->plugins= (struct st_maria_plugin *)sym;
@@ -2437,6 +2438,7 @@ typedef DECLARE_MYSQL_SYSVAR_SIMPLE(sysvar_longlong_t, longlong);
typedef DECLARE_MYSQL_SYSVAR_SIMPLE(sysvar_uint_t, uint);
typedef DECLARE_MYSQL_SYSVAR_SIMPLE(sysvar_ulong_t, ulong);
typedef DECLARE_MYSQL_SYSVAR_SIMPLE(sysvar_ulonglong_t, ulonglong);
+typedef DECLARE_MYSQL_SYSVAR_SIMPLE(sysvar_double_t, double);
typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_int_t, int);
typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_long_t, long);
@@ -2444,6 +2446,7 @@ typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_longlong_t, longlong);
typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_uint_t, uint);
typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_ulong_t, ulong);
typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_ulonglong_t, ulonglong);
+typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_double_t, double);
/****************************************************************************
@@ -2659,6 +2662,20 @@ err:
return 1;
}
+static int check_func_double(THD *thd, struct st_mysql_sys_var *var,
+ void *save, st_mysql_value *value)
+{
+ double v;
+ my_bool fixed;
+ struct my_option option;
+
+ value->val_real(value, &v);
+ plugin_opt_set_limits(&option, var);
+ *(double *) save= getopt_double_limit_value(v, &option, &fixed);
+
+ return throw_bounds_warning(thd, var->name, fixed, v);
+}
+
static void update_func_bool(THD *thd, struct st_mysql_sys_var *var,
void *tgt, const void *save)
@@ -2691,15 +2708,25 @@ static void update_func_longlong(THD *thd, struct st_mysql_sys_var *var,
static void update_func_str(THD *thd, struct st_mysql_sys_var *var,
void *tgt, const void *save)
{
- char *old= *(char **) tgt;
- *(char **)tgt= *(char **) save;
+ char *value= *(char**) save;
if (var->flags & PLUGIN_VAR_MEMALLOC)
{
- *(char **)tgt= my_strdup(*(char **) save, MYF(0));
+ char *old= *(char**) tgt;
+ if (value)
+ *(char**) tgt= my_strdup(value, MYF(0));
+ else
+ *(char**) tgt= 0;
my_free(old);
}
+ else
+ *(char**) tgt= value;
}
+static void update_func_double(THD *thd, struct st_mysql_sys_var *var,
+ void *tgt, const void *save)
+{
+ *(double *) tgt= *(double *) save;
+}
/****************************************************************************
System Variables support
@@ -2814,6 +2841,9 @@ static st_bookmark *register_var(const char *plugin, const char *name,
case PLUGIN_VAR_STR:
size= sizeof(char*);
break;
+ case PLUGIN_VAR_DOUBLE:
+ size= sizeof(double);
+ break;
default:
DBUG_ASSERT(0);
return NULL;
@@ -3026,6 +3056,11 @@ static char **mysql_sys_var_str(THD* thd, int offset)
return (char **) intern_sys_var_ptr(thd, offset, true);
}
+static double *mysql_sys_var_double(THD* thd, int offset)
+{
+ return (double *) intern_sys_var_ptr(thd, offset, true);
+}
+
void plugin_thdvar_init(THD *thd)
{
plugin_ref old_table_plugin= thd->variables.table_plugin;
@@ -3178,6 +3213,8 @@ static SHOW_TYPE pluginvar_show_type(st_mysql_sys_var *plugin_var)
case PLUGIN_VAR_ENUM:
case PLUGIN_VAR_SET:
return SHOW_CHAR;
+ case PLUGIN_VAR_DOUBLE:
+ return SHOW_DOUBLE;
default:
DBUG_ASSERT(0);
return SHOW_UNDEF;
@@ -3198,6 +3235,8 @@ bool sys_var_pluginvar::check_update_type(Item_result type)
case PLUGIN_VAR_BOOL:
case PLUGIN_VAR_SET:
return type != STRING_RESULT && type != INT_RESULT;
+ case PLUGIN_VAR_DOUBLE:
+ return type != INT_RESULT && type != REAL_RESULT && type != DECIMAL_RESULT;
default:
return true;
}
@@ -3316,6 +3355,9 @@ bool sys_var_pluginvar::global_update(THD *thd, set_var *var)
case PLUGIN_VAR_STR:
src= &((sysvar_str_t*) plugin_var)->def_val;
break;
+ case PLUGIN_VAR_DOUBLE:
+ src= &((sysvar_double_t*) plugin_var)->def_val;
+ break;
case PLUGIN_VAR_INT | PLUGIN_VAR_THDLOCAL:
src= &((thdvar_uint_t*) plugin_var)->def_val;
break;
@@ -3337,6 +3379,9 @@ bool sys_var_pluginvar::global_update(THD *thd, set_var *var)
case PLUGIN_VAR_STR | PLUGIN_VAR_THDLOCAL:
src= &((thdvar_str_t*) plugin_var)->def_val;
break;
+ case PLUGIN_VAR_DOUBLE | PLUGIN_VAR_THDLOCAL:
+ src= &((thdvar_double_t*) plugin_var)->def_val;
+ break;
default:
DBUG_ASSERT(0);
}
@@ -3354,6 +3399,13 @@ bool sys_var_pluginvar::global_update(THD *thd, set_var *var)
options->max_value= (opt)->max_val; \
options->block_size= (long) (opt)->blk_sz
+#define OPTION_SET_LIMITS_DOUBLE(options, opt) \
+ options->var_type= GET_DOUBLE; \
+ options->def_value= (longlong) getopt_double2ulonglong((opt)->def_val); \
+ options->min_value= (longlong) getopt_double2ulonglong((opt)->min_val); \
+ options->max_value= getopt_double2ulonglong((opt)->max_val); \
+ options->block_size= (long) (opt)->blk_sz;
+
void plugin_opt_set_limits(struct my_option *options,
const struct st_mysql_sys_var *opt)
@@ -3404,6 +3456,9 @@ void plugin_opt_set_limits(struct my_option *options,
GET_STR_ALLOC : GET_STR);
options->def_value= (intptr) ((sysvar_str_t*) opt)->def_val;
break;
+ case PLUGIN_VAR_DOUBLE:
+ OPTION_SET_LIMITS_DOUBLE(options, (sysvar_double_t*) opt);
+ break;
/* threadlocal variables */
case PLUGIN_VAR_INT | PLUGIN_VAR_THDLOCAL:
OPTION_SET_LIMITS(GET_INT, options, (thdvar_int_t*) opt);
@@ -3423,6 +3478,9 @@ void plugin_opt_set_limits(struct my_option *options,
case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_THDLOCAL:
OPTION_SET_LIMITS(GET_ULL, options, (thdvar_ulonglong_t*) opt);
break;
+ case PLUGIN_VAR_DOUBLE | PLUGIN_VAR_THDLOCAL:
+ OPTION_SET_LIMITS_DOUBLE(options, (thdvar_double_t*) opt);
+ break;
case PLUGIN_VAR_ENUM | PLUGIN_VAR_THDLOCAL:
options->var_type= GET_ENUM;
options->typelib= ((thdvar_enum_t*) opt)->typelib;
@@ -3574,6 +3632,9 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
case PLUGIN_VAR_SET:
((thdvar_set_t *) opt)->resolve= mysql_sys_var_ulonglong;
break;
+ case PLUGIN_VAR_DOUBLE:
+ ((thdvar_double_t *) opt)->resolve= mysql_sys_var_double;
+ break;
default:
sql_print_error("Unknown variable type code 0x%x in plugin '%s'.",
opt->flags, plugin_name);
@@ -3637,6 +3698,12 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
if (!opt->update)
opt->update= update_func_longlong;
break;
+ case PLUGIN_VAR_DOUBLE:
+ if (!opt->check)
+ opt->check= check_func_double;
+ if (!opt->update)
+ opt->update= update_func_double;
+ break;
default:
sql_print_error("Unknown variable type code 0x%x in plugin '%s'.",
opt->flags, plugin_name);
diff --git a/sql/sql_plugin_services.h b/sql/sql_plugin_services.h
index d2f60a6e08c..d983b01a6bd 100644
--- a/sql/sql_plugin_services.h
+++ b/sql/sql_plugin_services.h
@@ -54,6 +54,16 @@ static struct kill_statement_service_st thd_kill_statement_handler= {
thd_kill_level
};
+static struct logger_service_st logger_service_handler= {
+ logger_init_mutexes,
+ logger_open,
+ logger_close,
+ logger_vprintf,
+ logger_printf,
+ logger_write,
+ logger_rotate
+};
+
static struct st_service_ref list_of_services[]=
{
{ "my_snprintf_service", VERSION_my_snprintf, &my_snprintf_handler },
@@ -61,6 +71,7 @@ static struct st_service_ref list_of_services[]=
{ "thd_wait_service", VERSION_thd_wait, &thd_wait_handler },
{ "progress_report_service", VERSION_progress_report, &progress_report_handler },
{ "debug_sync_service", VERSION_debug_sync, 0 }, // updated in plugin_init()
- { "thd_kill_statement_service", VERSION_kill_statement, &thd_kill_statement_handler }
+ { "thd_kill_statement_service", VERSION_kill_statement, &thd_kill_statement_handler },
+ { "logger_service", VERSION_logger, &logger_service_handler },
};
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc
index c957076ac4f..295a55e1eb1 100644
--- a/sql/sql_rename.cc
+++ b/sql/sql_rename.cc
@@ -1,5 +1,6 @@
/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates.
+ Copyright (c) 2000, 2013, Oracle and/or its affiliates.
+ Copyright (c) 2011, 2013, Monty Program Ab.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -296,7 +297,7 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name,
and handler's data and report about failure to rename table.
*/
(void) mysql_rename_table(hton, new_db, new_alias,
- ren_table->db, old_alias, 0);
+ ren_table->db, old_alias, NO_FK_CHECKS);
}
}
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 3bb62598027..ebbd4302f39 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1358,6 +1358,15 @@ TODO: make view to decide if it is possible to write to WHERE directly or make S
/* Handle the case where we have an OUTER JOIN without a WHERE */
conds=new Item_int((longlong) 1,1); // Always true
}
+
+ if (impossible_where)
+ {
+ zero_result_cause=
+ "Impossible WHERE noticed after reading const tables";
+ select_lex->mark_const_derived(zero_result_cause);
+ goto setup_subq_exit;
+ }
+
select= make_select(*table, const_table_map,
const_table_map, conds, 1, &error);
if (error)
@@ -1462,6 +1471,12 @@ TODO: make view to decide if it is possible to write to WHERE directly or make S
new store_key_const_item(*tab->ref.key_copy[key_copy_index],
item);
}
+ else if (item->const_item())
+ {
+ tab->ref.key_copy[key_copy_index]=
+ new store_key_item(*tab->ref.key_copy[key_copy_index],
+ item, TRUE);
+ }
else
{
store_key_field *field_copy= ((store_key_field *)key_copy);
@@ -3751,6 +3766,18 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
}
}
+ join->impossible_where= false;
+ if (conds && const_count)
+ {
+ conds= remove_eq_conds(join->thd, conds, &join->cond_value);
+ if (join->cond_value == Item::COND_FALSE)
+ {
+ join->impossible_where= true;
+ conds=new Item_int((longlong) 0,1);
+ }
+ join->conds= conds;
+ }
+
/* Calc how many (possible) matched records in each table */
for (s=stat ; s < stat_end ; s++)
@@ -5212,8 +5239,23 @@ static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array)
Optionally (if out_args is supplied) will push the arguments of
AGGFN(DISTINCT) to the list
+ Check for every COUNT(DISTINCT), AVG(DISTINCT) or
+ SUM(DISTINCT). These can be resolved by Loose Index Scan as long
+ as all the aggregate distinct functions refer to the same
+ fields. Thus:
+
+ SELECT AGGFN(DISTINCT a, b), AGGFN(DISTINCT b, a)... => can use LIS
+ SELECT AGGFN(DISTINCT a), AGGFN(DISTINCT a) ... => can use LIS
+ SELECT AGGFN(DISTINCT a, b), AGGFN(DISTINCT a) ... => cannot use LIS
+ SELECT AGGFN(DISTINCT a), AGGFN(DISTINCT b) ... => cannot use LIS
+ etc.
+
@param join the join to check
- @param[out] out_args list of aggregate function arguments
+ @param[out] out_args Collect the arguments of the aggregate functions
+ to a list. We don't worry about duplicates as
+ these will be sorted out later in
+ get_best_group_min_max.
+
@return does the query qualify for indexed AGGFN(DISTINCT)
@retval true it does
@retval false AGGFN(DISTINCT) must apply distinct in it.
@@ -5224,6 +5266,7 @@ is_indexed_agg_distinct(JOIN *join, List<Item_field> *out_args)
{
Item_sum **sum_item_ptr;
bool result= false;
+ Field_map first_aggdistinct_fields;
if (join->table_count != 1 || /* reference more than 1 table */
join->select_distinct || /* or a DISTINCT */
@@ -5236,6 +5279,7 @@ is_indexed_agg_distinct(JOIN *join, List<Item_field> *out_args)
for (sum_item_ptr= join->sum_funcs; *sum_item_ptr; sum_item_ptr++)
{
Item_sum *sum_item= *sum_item_ptr;
+ Field_map cur_aggdistinct_fields;
Item *expr;
/* aggregate is not AGGFN(DISTINCT) or more than 1 argument to it */
switch (sum_item->sum_func())
@@ -5265,15 +5309,23 @@ is_indexed_agg_distinct(JOIN *join, List<Item_field> *out_args)
if (expr->real_item()->type() != Item::FIELD_ITEM)
return false;
- /*
- If we came to this point the AGGFN(DISTINCT) loose index scan
- optimization is applicable
- */
+ Item_field* item= static_cast<Item_field*>(expr->real_item());
if (out_args)
- out_args->push_back((Item_field *) expr->real_item());
+ out_args->push_back(item);
+
+ cur_aggdistinct_fields.set_bit(item->field->field_index);
result= true;
}
+ /*
+ If there are multiple aggregate functions, make sure that they all
+ refer to exactly the same set of columns.
+ */
+ if (first_aggdistinct_fields.is_clear_all())
+ first_aggdistinct_fields.merge(cur_aggdistinct_fields);
+ else if (first_aggdistinct_fields != cur_aggdistinct_fields)
+ return false;
}
+
return result;
}
@@ -8706,14 +8758,13 @@ static void add_not_null_conds(JOIN *join)
Item *item= tab->ref.items[keypart];
Item *notnull;
Item *real= item->real_item();
- if (real->basic_const_item())
+ if (real->const_item() && real->type() != Item::FIELD_ITEM &&
+ !real->is_expensive())
{
/*
It could be constant instead of field after constant
propagation.
*/
- DBUG_ASSERT(real->is_expensive() || // prevent early expensive eval
- !real->is_null()); // NULLs are not propagated
continue;
}
DBUG_ASSERT(real->type() == Item::FIELD_ITEM);
@@ -9300,19 +9351,18 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
else
{
sel->needed_reg=tab->needed_reg;
- sel->quick_keys.clear_all();
}
+ sel->quick_keys= tab->table->quick_keys;
if (!sel->quick_keys.is_subset(tab->checked_keys) ||
!sel->needed_reg.is_subset(tab->checked_keys))
{
- tab->keys=sel->quick_keys;
- tab->keys.merge(sel->needed_reg);
tab->use_quick= (!sel->needed_reg.is_clear_all() &&
- (select->quick_keys.is_clear_all() ||
- (select->quick &&
- (select->quick->records >= 100L)))) ?
+ (sel->quick_keys.is_clear_all() ||
+ (sel->quick &&
+ (sel->quick->records >= 100L)))) ?
2 : 1;
sel->read_tables= used_tables & ~current_map;
+ sel->quick_keys.clear_all();
}
if (i != join->const_tables && tab->use_quick != 2 &&
!tab->first_inner)
@@ -10737,6 +10787,11 @@ void JOIN_TAB::cleanup()
{
if (table->pos_in_table_list->jtbm_subselect->is_jtbm_const_tab)
{
+ /*
+ Set this to NULL so that cleanup_empty_jtbm_semi_joins() doesn't
+ attempt to make another free_tmp_table call.
+ */
+ table->pos_in_table_list->table= NULL;
free_tmp_table(join->thd, table);
table= NULL;
}
@@ -11160,6 +11215,7 @@ void JOIN::cleanup(bool full)
}
if (full)
{
+ cleanup_empty_jtbm_semi_joins(this);
/*
Ensure that the following delete_elements() would not be called
twice for the same list.
@@ -13904,22 +13960,230 @@ optimize_cond(JOIN *join, COND *conds,
/**
- Handles the recursive job remove_eq_conds()
+ @brief
+ Propagate multiple equalities to the sub-expressions of a condition
- Remove const and eq items. Return new item, or NULL if no condition
- cond_value is set to according:
- COND_OK query is possible (field = constant)
- COND_TRUE always true ( 1 = 1 )
- COND_FALSE always false ( 1 = 2 )
+ @param thd thread handle
+ @param cond the condition where equalities are to be propagated
+ @param *new_equalities the multiple equalities to be propagated
+ @param inherited path to all inherited multiple equality items
+ @param[out] is_simplifiable_cond 'cond' may be simplified after the
+ propagation of the equalities
+
+ @details
+ The function recursively traverses the tree of the condition 'cond' and
+ for each its AND sub-level of any depth the function merges the multiple
+ equalities from the list 'new_equalities' into the multiple equalities
+ attached to the AND item created for this sub-level.
+ The function also [re]sets references to the equalities formed by the
+ merges of multiple equalities in all field items occurred in 'cond'
+ that are encountered in the equalities.
+ If the result of any merge of multiple equalities is an impossible
+ condition the function returns TRUE in the parameter is_simplifiable_cond.
+*/
- SYNOPSIS
- internal_remove_eq_conds()
- thd THD environment
- cond the condition to handle
- cond_value the resulting value of the condition
+void propagate_new_equalities(THD *thd, Item *cond,
+ List<Item_equal> *new_equalities,
+ COND_EQUAL *inherited,
+ bool *is_simplifiable_cond)
+{
+ if (cond->type() == Item::COND_ITEM)
+ {
+ bool and_level= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC;
+ if (and_level)
+ {
+ Item_cond_and *cond_and= (Item_cond_and *) cond;
+ List<Item_equal> *cond_equalities= &cond_and->cond_equal.current_level;
+ cond_and->cond_equal.upper_levels= inherited;
+ if (!cond_equalities->is_empty() && cond_equalities != new_equalities)
+ {
+ Item_equal *equal_item;
+ List_iterator<Item_equal> it(*new_equalities);
+ while ((equal_item= it++))
+ {
+ equal_item->merge_into_list(cond_equalities, true, true);
+ }
+ List_iterator<Item_equal> ei(*cond_equalities);
+ while ((equal_item= ei++))
+ {
+ if (equal_item->const_item() && !equal_item->val_int())
+ {
+ *is_simplifiable_cond= true;
+ return;
+ }
+ }
+ }
+ }
- RETURN
- *COND with the simplified condition
+ Item *item;
+ List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
+ while ((item= li++))
+ {
+ COND_EQUAL *new_inherited= and_level && item->type() == Item::COND_ITEM ?
+ &((Item_cond_and *) cond)->cond_equal :
+ inherited;
+ propagate_new_equalities(thd, item, new_equalities, new_inherited,
+ is_simplifiable_cond);
+ }
+ }
+ else if (cond->type() == Item::FUNC_ITEM &&
+ ((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
+ {
+ Item_equal *equal_item;
+ List_iterator<Item_equal> it(*new_equalities);
+ Item_equal *equality= (Item_equal *) cond;
+ equality->upper_levels= inherited;
+ while ((equal_item= it++))
+ {
+ equality->merge_with_check(equal_item, true);
+ }
+ if (equality->const_item() && !equality->val_int())
+ *is_simplifiable_cond= true;
+ }
+ else
+ {
+ uchar* is_subst_valid= (uchar *) Item::ANY_SUBST;
+ cond= cond->compile(&Item::subst_argument_checker,
+ &is_subst_valid,
+ &Item::equal_fields_propagator,
+ (uchar *) inherited);
+ cond->update_used_tables();
+ }
+}
+
+/*
+ Check if cond_is_datetime_is_null() is true for the condition cond, or
+ for any of its AND/OR-children
+*/
+bool cond_has_datetime_is_null(Item *cond)
+{
+ if (cond_is_datetime_is_null(cond))
+ return true;
+
+ if (cond->type() == Item::COND_ITEM)
+ {
+ List<Item> *cond_arg_list= ((Item_cond*) cond)->argument_list();
+ List_iterator<Item> li(*cond_arg_list);
+ Item *item;
+ while ((item= li++))
+ {
+ if (cond_has_datetime_is_null(item))
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ Check if passed condtition has for of
+
+ not_null_date_col IS NULL
+
+ where not_null_date_col has a datte or datetime type
+*/
+
+bool cond_is_datetime_is_null(Item *cond)
+{
+ if (cond->type() == Item::FUNC_ITEM &&
+ ((Item_func*) cond)->functype() == Item_func::ISNULL_FUNC)
+ {
+ Item **args= ((Item_func_isnull*) cond)->arguments();
+ if (args[0]->type() == Item::FIELD_ITEM)
+ {
+ Field *field=((Item_field*) args[0])->field;
+
+ if (((field->type() == MYSQL_TYPE_DATE) ||
+ (field->type() == MYSQL_TYPE_DATETIME)) &&
+ (field->flags & NOT_NULL_FLAG))
+ {
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+
+/**
+ @brief
+ Evaluate all constant boolean sub-expressions in a condition
+
+ @param thd thread handle
+ @param cond condition where where to evaluate constant sub-expressions
+ @param[out] cond_value : the returned value of the condition
+ (TRUE/FALSE/UNKNOWN:
+ Item::COND_TRUE/Item::COND_FALSE/Item::COND_OK)
+ @return
+ the item that is the result of the substitution of all inexpensive constant
+ boolean sub-expressions into cond, or,
+ NULL if the condition is constant and is evaluated to FALSE.
+
+ @details
+ This function looks for all inexpensive constant boolean sub-expressions in
+ the given condition 'cond' and substitutes them for their values.
+ For example, the condition 2 > (5 + 1) or a < (10 / 2)
+ will be transformed to the condition a < (10 / 2).
+ Note that a constant sub-expression is evaluated only if it is constant and
+ inexpensive. A sub-expression with an uncorrelated subquery may be evaluated
+ only if the subquery is considered as inexpensive.
+ The function does not evaluate a constant sub-expression if it is not on one
+ of AND/OR levels of the condition 'cond'. For example, the subquery in the
+ condition a > (select max(b) from t1 where b > 5) will never be evaluated
+ by this function.
+ If a constant boolean sub-expression is evaluated to TRUE then:
+ - when the sub-expression is a conjunct of an AND formula it is simply
+ removed from this formula
+ - when the sub-expression is a disjunct of an OR formula the whole OR
+ formula is converted to TRUE
+ If a constant boolean sub-expression is evaluated to FALSE then:
+ - when the sub-expression is a disjunct of an OR formula it is simply
+ removed from this formula
+ - when the sub-expression is a conjuct of an AND formula the whole AND
+ formula is converted to FALSE
+ When a disjunct/conjunct is removed from an OR/AND formula it might happen
+ that there is only one conjunct/disjunct remaining. In this case this
+ remaining disjunct/conjunct must be merged into underlying AND/OR formula,
+ because AND/OR levels must alternate in the same way as they alternate
+ after fix_fields() is called for the original condition.
+ The specifics of merging a formula f into an AND formula A appears
+ when A contains multiple equalities and f contains multiple equalities.
+ In this case the multiple equalities from f and A have to be merged.
+ After this the resulting multiple equalities have to be propagated into
+ the all AND/OR levels of the formula A (see propagate_new_equalities()).
+ The propagation of multiple equalities might result in forming multiple
+ equalities that are always FALSE. This, in its turn, might trigger further
+ simplification of the condition.
+
+ @note
+ EXAMPLE 1:
+ SELECT * FROM t1 WHERE (b = 1 OR a = 1) AND (b = 5 AND a = 5 OR 1 != 1);
+ First 1 != 1 will be removed from the second conjunct:
+ => SELECT * FROM t1 WHERE (b = 1 OR a = 1) AND (b = 5 AND a = 5);
+ Then (b = 5 AND a = 5) will be merged into the top level condition:
+ => SELECT * FROM t1 WHERE (b = 1 OR a = 1) AND (b = 5) AND (a = 5);
+ Then (b = 5), (a = 5) will be propagated into the disjuncs of
+ (b = 1 OR a = 1):
+ => SELECT * FROM t1 WHERE ((b = 1) AND (b = 5) AND (a = 5) OR
+ (a = 1) AND (b = 5) AND (a = 5)) AND
+ (b = 5) AND (a = 5)
+ => SELECT * FROM t1 WHERE ((FALSE AND (a = 5)) OR
+ (FALSE AND (b = 5))) AND
+ (b = 5) AND (a = 5)
+ After this an additional call of remove_eq_conds() converts it
+ to FALSE
+
+ EXAMPLE 2:
+ SELECT * FROM t1 WHERE (b = 1 OR a = 5) AND (b = 5 AND a = 5 OR 1 != 1);
+ => SELECT * FROM t1 WHERE (b = 1 OR a = 5) AND (b = 5 AND a = 5);
+ => SELECT * FROM t1 WHERE (b = 1 OR a = 5) AND (b = 5) AND (a = 5);
+ => SELECT * FROM t1 WHERE ((b = 1) AND (b = 5) AND (a = 5) OR
+ (a = 5) AND (b = 5) AND (a = 5)) AND
+ (b = 5) AND (a = 5)
+ => SELECT * FROM t1 WHERE ((FALSE AND (a = 5)) OR
+ ((b = 5) AND (a = 5))) AND
+ (b = 5) AND (a = 5)
+ After this an additional call of remove_eq_conds() converts it to
+ => SELECT * FROM t1 WHERE (b = 5) AND (a = 5)
*/
static COND *
@@ -13927,9 +14191,11 @@ internal_remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
{
if (cond->type() == Item::COND_ITEM)
{
+ List<Item_equal> new_equalities;
bool and_level= ((Item_cond*) cond)->functype()
== Item_func::COND_AND_FUNC;
- List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
+ List<Item> *cond_arg_list= ((Item_cond*) cond)->argument_list();
+ List_iterator<Item> li(*cond_arg_list);
Item::cond_result tmp_cond_value;
bool should_fix_fields=0;
@@ -13939,92 +14205,86 @@ internal_remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
{
Item *new_item=internal_remove_eq_conds(thd, item, &tmp_cond_value);
if (!new_item)
+ {
+ /* This can happen only when item is converted to TRUE or FALSE */
li.remove();
+ }
else if (item != new_item)
{
- if (and_level)
- {
- /*
- Take a special care of multiple equality predicates
- that may be part of 'cond' and 'new_item'.
- Those multiple equalities that have common members
- must be merged.
- */
- Item_cond_and *cond_and= (Item_cond_and *) cond;
- List<Item_equal> *cond_equal_items=
- &cond_and->cond_equal.current_level;
- List<Item> *cond_and_list= cond_and->argument_list();
-
- if (new_item->type() == Item::COND_ITEM &&
- ((Item_cond*) new_item)->functype() == Item_func::COND_AND_FUNC)
- {
- Item_cond_and *new_item_and= (Item_cond_and *) new_item;
- List<Item_equal> *new_item_equal_items=
- &new_item_and->cond_equal.current_level;
- List<Item> *new_item_and_list= new_item_and->argument_list();
- cond_and_list->disjoin((List<Item>*) cond_equal_items);
- new_item_and_list->disjoin((List<Item>*) new_item_equal_items);
- Item_equal *equal_item;
- List_iterator<Item_equal> it(*new_item_equal_items);
- while ((equal_item= it++))
- {
- equal_item->merge_into_list(cond_equal_items);
- }
- if (new_item_and_list->is_empty())
- li.remove();
- else
+ /*
+ This can happen when:
+ - item was an OR formula converted to one disjunct
+ - item was an AND formula converted to one conjunct
+ In these cases the disjunct/conjunct must be merged into the
+ argument list of cond.
+ */
+ if (new_item->type() == Item::COND_ITEM &&
+ item->type() == Item::COND_ITEM)
+ {
+ DBUG_ASSERT(((Item_cond *) cond)->functype() ==
+ ((Item_cond *) new_item)->functype());
+ List<Item> *new_item_arg_list=
+ ((Item_cond *) new_item)->argument_list();
+ if (and_level)
+ {
+ /*
+ If new_item is an AND formula then multiple equalities
+ of new_item_arg_list must merged into multiple equalities
+ of cond_arg_list.
+ */
+ List<Item_equal> *new_item_equalities=
+ &((Item_cond_and *) new_item)->cond_equal.current_level;
+ if (!new_item_equalities->is_empty())
{
- Item *list_item;
- Item *new_list_item;
- uint cnt= new_item_and_list->elements;
- List_iterator<Item> it(*new_item_and_list);
- while ((list_item= it++))
- {
- uchar* is_subst_valid= (uchar *) Item::ANY_SUBST;
- new_list_item=
- list_item->compile(&Item::subst_argument_checker,
- &is_subst_valid,
- &Item::equal_fields_propagator,
- (uchar *) &cond_and->cond_equal);
- if (new_list_item != list_item)
- it.replace(new_list_item);
- new_list_item->update_used_tables();
- }
- li.replace(*new_item_and_list);
- for (cnt--; cnt; cnt--)
- item= li++;
+ /*
+ Cut the multiple equalities from the new_item_arg_list and
+ append them on the list new_equalities. Later the equalities
+ from this list will be merged into the multiple equalities
+ of cond_arg_list all together.
+ */
+ new_item_arg_list->disjoin((List<Item> *) new_item_equalities);
+ new_equalities.concat(new_item_equalities);
}
- cond_and_list->concat((List<Item>*) cond_equal_items);
}
- else if (new_item->type() == Item::FUNC_ITEM &&
- ((Item_cond*) new_item)->functype() ==
- Item_func::MULT_EQUAL_FUNC)
+ if (new_item_arg_list->is_empty())
+ li.remove();
+ else
{
- cond_and_list->disjoin((List<Item>*) cond_equal_items);
- ((Item_equal *) new_item)->merge_into_list(cond_equal_items);
- li.remove();
- cond_and_list->concat((List<Item>*) cond_equal_items);
+ uint cnt= new_item_arg_list->elements;
+ li.replace(*new_item_arg_list);
+ /* Make iterator li ignore new items */
+ for (cnt--; cnt; cnt--)
+ li++;
+ should_fix_fields= 1;
}
- else
- li.replace(new_item);
+ }
+ else if (and_level &&
+ new_item->type() == Item::FUNC_ITEM &&
+ ((Item_cond*) new_item)->functype() ==
+ Item_func::MULT_EQUAL_FUNC)
+ {
+ li.remove();
+ new_equalities.push_back((Item_equal *) new_item);
}
else
- {
+ {
if (new_item->type() == Item::COND_ITEM &&
((Item_cond*) new_item)->functype() ==
((Item_cond*) cond)->functype())
{
- List<Item> *arg_list= ((Item_cond*) new_item)->argument_list();
- uint cnt= arg_list->elements;
- li.replace(*arg_list);
- for ( cnt--; cnt; cnt--)
- item= li++;
+ List<Item> *new_item_arg_list=
+ ((Item_cond *) new_item)->argument_list();
+ uint cnt= new_item_arg_list->elements;
+ li.replace(*new_item_arg_list);
+ /* Make iterator li ignore new items */
+ for (cnt--; cnt; cnt--)
+ li++;
}
- else
+ else
li.replace(new_item);
+ should_fix_fields= 1;
}
- should_fix_fields=1;
- }
+ }
if (*cond_value == Item::COND_UNDEF)
*cond_value=tmp_cond_value;
switch (tmp_cond_value) {
@@ -14050,6 +14310,55 @@ internal_remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
break; /* purecov: deadcode */
}
}
+ if (!new_equalities.is_empty())
+ {
+ DBUG_ASSERT(and_level);
+ /*
+ Merge multiple equalities that were cut from the results of
+ simplification of OR formulas converted into AND formulas.
+ These multiple equalities are to be merged into the
+ multiple equalities of cond_arg_list.
+ */
+ COND_EQUAL *cond_equal= &((Item_cond_and *) cond)->cond_equal;
+ List<Item_equal> *cond_equalities= &cond_equal->current_level;
+ cond_arg_list->disjoin((List<Item> *) cond_equalities);
+ Item_equal *equality;
+ List_iterator_fast<Item_equal> it(new_equalities);
+ while ((equality= it++))
+ {
+ equality->upper_levels= cond_equal->upper_levels;
+ equality->merge_into_list(cond_equalities, false, false);
+ List_iterator_fast<Item_equal> ei(*cond_equalities);
+ while ((equality= ei++))
+ {
+ if (equality->const_item() && !equality->val_int())
+ {
+ *cond_value= Item::COND_FALSE;
+ return (COND*) 0;
+ }
+ }
+ }
+ cond_arg_list->concat((List<Item> *) cond_equalities);
+ /*
+ Propagate the newly formed multiple equalities to
+ the all AND/OR levels of cond
+ */
+ bool is_simplifiable_cond= false;
+ propagate_new_equalities(thd, cond, cond_equalities,
+ cond_equal->upper_levels,
+ &is_simplifiable_cond);
+ /*
+ If the above propagation of multiple equalities brings us
+ to multiple equalities that are always FALSE then try to
+ simplify the condition with remove_eq_cond() again.
+ */
+ if (is_simplifiable_cond)
+ {
+ if (!(cond= internal_remove_eq_conds(thd, cond, cond_value)))
+ return cond;
+ }
+ should_fix_fields= 1;
+ }
if (should_fix_fields)
cond->update_used_tables();
@@ -14063,53 +14372,45 @@ internal_remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
return item;
}
}
- else if (cond->type() == Item::FUNC_ITEM &&
- ((Item_func*) cond)->functype() == Item_func::ISNULL_FUNC)
+ else if (cond_is_datetime_is_null(cond))
{
- Item_func_isnull *func=(Item_func_isnull*) cond;
- Item **args= func->arguments();
- if (args[0]->type() == Item::FIELD_ITEM)
- {
- Field *field=((Item_field*) args[0])->field;
- /* fix to replace 'NULL' dates with '0' (shreeve@uci.edu) */
- /*
- See BUG#12594011
- Documentation says that
- SELECT datetime_notnull d FROM t1 WHERE d IS NULL
- shall return rows where d=='0000-00-00'
+ /* fix to replace 'NULL' dates with '0' (shreeve@uci.edu) */
+ /*
+ See BUG#12594011
+ Documentation says that
+ SELECT datetime_notnull d FROM t1 WHERE d IS NULL
+ shall return rows where d=='0000-00-00'
- Thus, for DATE and DATETIME columns defined as NOT NULL,
- "date_notnull IS NULL" has to be modified to
- "date_notnull IS NULL OR date_notnull == 0" (if outer join)
- "date_notnull == 0" (otherwise)
+ Thus, for DATE and DATETIME columns defined as NOT NULL,
+ "date_notnull IS NULL" has to be modified to
+ "date_notnull IS NULL OR date_notnull == 0" (if outer join)
+ "date_notnull == 0" (otherwise)
- */
- if (((field->type() == MYSQL_TYPE_DATE) ||
- (field->type() == MYSQL_TYPE_DATETIME)) &&
- (field->flags & NOT_NULL_FLAG))
- {
- Item *item0= new(thd->mem_root) Item_int((longlong)0, 1);
- Item *eq_cond= new(thd->mem_root) Item_func_eq(args[0], item0);
- if (!eq_cond)
- return cond;
+ */
+ Item **args= ((Item_func_isnull*) cond)->arguments();
+ Field *field=((Item_field*) args[0])->field;
- if (field->table->pos_in_table_list->outer_join)
- {
- // outer join: transform "col IS NULL" to "col IS NULL or col=0"
- Item *or_cond= new(thd->mem_root) Item_cond_or(eq_cond, cond);
- if (!or_cond)
- return cond;
- cond= or_cond;
- }
- else
- {
- // not outer join: transform "col IS NULL" to "col=0"
- cond= eq_cond;
- }
+ Item *item0= new(thd->mem_root) Item_int((longlong)0, 1);
+ Item *eq_cond= new(thd->mem_root) Item_func_eq(args[0], item0);
+ if (!eq_cond)
+ return cond;
- cond->fix_fields(thd, &cond);
- }
+ if (field->table->pos_in_table_list->is_inner_table_of_outer_join())
+ {
+ // outer join: transform "col IS NULL" to "col IS NULL or col=0"
+ Item *or_cond= new(thd->mem_root) Item_cond_or(eq_cond, cond);
+ if (!or_cond)
+ return cond;
+ cond= or_cond;
}
+ else
+ {
+ // not outer join: transform "col IS NULL" to "col=0"
+ cond= eq_cond;
+ }
+
+ cond->fix_fields(thd, &cond);
+
if (cond->const_item() && !cond->is_expensive())
{
*cond_value= eval_const_cond(cond) ? Item::COND_TRUE : Item::COND_FALSE;
@@ -14214,7 +14515,7 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
}
-/*
+/**
Check if equality can be used in removing components of GROUP BY/DISTINCT
@param l the left comparison argument (a field if any)
@@ -14793,7 +15094,8 @@ TABLE *
create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
ORDER *group, bool distinct, bool save_sum_fields,
ulonglong select_options, ha_rows rows_limit,
- const char *table_alias, bool do_not_open)
+ const char *table_alias, bool do_not_open,
+ bool keep_row_order)
{
MEM_ROOT *mem_root_save, own_root;
TABLE *table;
@@ -15602,6 +15904,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
share->db_record_offset= 1;
table->used_for_duplicate_elimination= (param->sum_func_count == 0 &&
(table->group || table->distinct));
+ table->keep_row_order= keep_row_order;
if (!do_not_open)
{
@@ -15939,7 +16242,8 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
table->no_rows ? NO_RECORD :
(share->reclength < 64 &&
!share->blob_fields ? STATIC_RECORD :
- table->used_for_duplicate_elimination ?
+ table->used_for_duplicate_elimination ||
+ table->keep_row_order ?
DYNAMIC_RECORD : BLOCK_RECORD),
share->keys, &keydef,
(uint) (*recinfo-start_recinfo),
@@ -17195,7 +17499,7 @@ int report_error(TABLE *table, int error)
print them to the .err log
*/
if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT
- && !table->in_use->killed)
+ && error != HA_ERR_TABLE_DEF_CHANGED && !table->in_use->killed)
{
push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN, error,
"Got error %d when reading table %`s.%`s",
@@ -17574,6 +17878,11 @@ join_read_always_key(JOIN_TAB *tab)
if (cp_buffer_from_ref(tab->join->thd, table, &tab->ref))
return -1;
+ if ((error= table->file->prepare_index_key_scan_map(tab->ref.key_buff, make_prev_keypart_map(tab->ref.key_parts))))
+ {
+ report_error(table,error);
+ return -1;
+ }
if ((error= table->file->ha_index_read_map(table->record[0],
tab->ref.key_buff,
make_prev_keypart_map(tab->ref.key_parts),
@@ -17607,6 +17916,11 @@ join_read_last_key(JOIN_TAB *tab)
if (cp_buffer_from_ref(tab->join->thd, table, &tab->ref))
return -1;
+ if ((error= table->file->prepare_index_key_scan_map(tab->ref.key_buff, make_prev_keypart_map(tab->ref.key_parts))))
+ {
+ report_error(table,error);
+ return -1;
+ }
if ((error= table->file->ha_index_read_map(table->record[0],
tab->ref.key_buff,
make_prev_keypart_map(tab->ref.key_parts),
@@ -21343,22 +21657,20 @@ change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
if (field != NULL)
{
/*
- Replace "@:=<expression>" with "@:=<tmp table column>". Otherwise,
- we would re-evaluate <expression>, and if expression were
- a subquery, this would access already-unlocked tables.
- */
+ Replace "@:=<expression>" with "@:=<tmp table column>". Otherwise, we
+ would re-evaluate <expression>, and if expression were a subquery, this
+ would access already-unlocked tables.
+ */
Item_func_set_user_var* suv=
- new Item_func_set_user_var((Item_func_set_user_var*) item);
+ new Item_func_set_user_var(thd, (Item_func_set_user_var*) item);
Item_field *new_field= new Item_field(field);
- if (!suv || !new_field || suv->fix_fields(thd, (Item**)&suv))
+ if (!suv || !new_field)
DBUG_RETURN(true); // Fatal error
- ((Item *)suv)->name= item->name;
/*
- We are replacing the argument of Item_func_set_user_var after its
- value has been read. The argument's null_value should be set by
- now, so we must set it explicitly for the replacement argument
- since the null_value may be read without any preceeding call to
- val_*().
+ We are replacing the argument of Item_func_set_user_var after its value
+ has been read. The argument's null_value should be set by now, so we
+ must set it explicitly for the replacement argument since the null_value
+ may be read without any preceeding call to val_*().
*/
new_field->update_null_value();
List<Item> list;
@@ -21389,15 +21701,15 @@ change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
ifield->db_name= iref->db_name;
}
#ifndef DBUG_OFF
- if (!item_field->name)
- {
- char buff[256];
- String str(buff,sizeof(buff),&my_charset_bin);
- str.length(0);
- str.extra_allocation(1024);
- item->print(&str, QT_ORDINARY);
- item_field->name= sql_strmake(str.ptr(),str.length());
- }
+ if (!item_field->name)
+ {
+ char buff[256];
+ String str(buff,sizeof(buff),&my_charset_bin);
+ str.length(0);
+ str.extra_allocation(1024);
+ item->print(&str, QT_ORDINARY);
+ item_field->name= sql_strmake(str.ptr(),str.length());
+ }
#endif
}
else
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 0f622b0c84e..686f159fabf 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -1173,6 +1173,11 @@ public:
bool cleaned;
DYNAMIC_ARRAY keyuse;
Item::cond_result cond_value, having_value;
+ /**
+ Impossible where after reading const tables
+ (set in make_join_statistics())
+ */
+ bool impossible_where;
List<Item> all_fields; ///< to store all fields that used in query
///Above list changed to use temporary table
List<Item> tmp_all_fields1, tmp_all_fields2, tmp_all_fields3;
@@ -1825,6 +1830,8 @@ ORDER *simple_remove_const(ORDER *order, COND *where);
bool const_expression_in_where(COND *cond, Item *comp_item,
Field *comp_field= NULL,
Item **const_item= NULL);
+bool cond_is_datetime_is_null(Item *cond);
+bool cond_has_datetime_is_null(Item *cond);
/* Table elimination entry point function */
void eliminate_tables(JOIN *join);
@@ -1846,7 +1853,8 @@ void push_index_cond(JOIN_TAB *tab, uint keyno);
TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
ORDER *group, bool distinct, bool save_sum_fields,
ulonglong select_options, ha_rows rows_limit,
- const char* alias, bool do_not_open=FALSE);
+ const char* alias, bool do_not_open=FALSE,
+ bool keep_row_order= FALSE);
void free_tmp_table(THD *thd, TABLE *entry);
bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
ENGINE_COLUMNDEF *start_recinfo,
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 438047d0ebb..2b1dbbd394f 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -4564,6 +4564,8 @@ make_unique_key_name(const char *field_name,KEY *start,KEY *end)
FN_TO_IS_TMP new_name is temporary.
NO_FRM_RENAME Don't rename the FRM file
but only the table in the storage engine.
+ NO_FK_CHECKS Don't check FK constraints
+ during rename.
RETURN
FALSE OK
@@ -4582,9 +4584,14 @@ mysql_rename_table(handlerton *base, const char *old_db,
char tmp_name[SAFE_NAME_LEN+1];
handler *file;
int error=0;
+ ulonglong save_bits= thd->variables.option_bits;
DBUG_ENTER("mysql_rename_table");
DBUG_PRINT("enter", ("old: '%s'.'%s' new: '%s'.'%s'",
old_db, old_name, new_db, new_name));
+
+ // Temporarily disable foreign key checks
+ if (flags & NO_FK_CHECKS)
+ thd->variables.option_bits|= OPTION_NO_FOREIGN_KEY_CHECKS;
file= (base == NULL ? 0 :
get_new_handler((TABLE_SHARE*) 0, thd->mem_root, base));
@@ -4636,6 +4643,10 @@ mysql_rename_table(handlerton *base, const char *old_db,
my_error(ER_ERROR_ON_RENAME, MYF(0), from, to, error);
else if (!(flags & FN_IS_TMP))
mysql_audit_rename_table(thd, old_db, old_name, new_db, new_name);
+
+ // Restore options bits to the original value
+ thd->variables.option_bits= save_bits;
+
DBUG_RETURN(error != 0);
}
@@ -6559,7 +6570,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
new_db, new_alias))
{
(void) mysql_rename_table(old_db_type, new_db, new_alias, db,
- table_name, 0);
+ table_name, NO_FK_CHECKS);
error= -1;
}
}
@@ -7357,7 +7368,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
error= 1;
(void) quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
(void) mysql_rename_table(old_db_type, db, old_name, db, alias,
- FN_FROM_IS_TMP);
+ FN_FROM_IS_TMP | NO_FK_CHECKS);
}
else if (new_name != table_name || new_db != db)
{
@@ -7369,7 +7380,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
error= 1;
(void) quick_rm_table(new_db_type, new_db, new_alias, 0);
(void) mysql_rename_table(old_db_type, db, old_name, db, alias,
- FN_FROM_IS_TMP);
+ FN_FROM_IS_TMP | NO_FK_CHECKS);
}
else if (Table_triggers_list::change_table_name(thd, db, alias,
table_name, new_db,
@@ -7379,7 +7390,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
error= 1;
(void) quick_rm_table(new_db_type, new_db, new_alias, 0);
(void) mysql_rename_table(old_db_type, db, old_name, db,
- alias, FN_FROM_IS_TMP);
+ alias, FN_FROM_IS_TMP | NO_FK_CHECKS);
/*
If we were performing "fast"/in-place ALTER TABLE we also need
to restore old name of table in storage engine as a separate
@@ -7388,7 +7399,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (need_copy_table == ALTER_TABLE_METADATA_ONLY)
{
(void) mysql_rename_table(save_old_db_type, new_db, new_alias,
- db, table_name, NO_FRM_RENAME);
+ db, table_name,
+ NO_FRM_RENAME | NO_FK_CHECKS);
}
}
}
@@ -7812,11 +7824,13 @@ copy_data_between_tables(THD *thd, TABLE *from,TABLE *to,
AUTO_INCREMENT_FLAG))
err_msg= ER(ER_DUP_ENTRY_AUTOINCREMENT_CASE);
to->file->print_keydup_error(key_nr, err_msg, MYF(0));
+ error= 1;
break;
}
}
to->file->print_error(error,MYF(0));
+ error= 1;
break;
}
to->file->restore_auto_increment(prev_insert_id);
diff --git a/sql/sql_table.h b/sql/sql_table.h
index 8bc6865decd..58280b45861 100644
--- a/sql/sql_table.h
+++ b/sql/sql_table.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2006, 2010, Oracle and/or its affiliates.
+/* Copyright (c) 2006, 2013, Oracle and/or its affiliates.
Copyright (c) 2011, 2013, Monty Program Ab.
This program is free software; you can redistribute it and/or modify
@@ -120,6 +120,8 @@ enum enum_explain_filename_mode
#define FN_IS_TMP (FN_FROM_IS_TMP | FN_TO_IS_TMP)
#define NO_FRM_RENAME (1 << 2)
#define FRM_ONLY (1 << 3)
+/** Don't check foreign key constraints while renaming table */
+#define NO_FK_CHECKS (1 << 4)
uint filename_to_tablename(const char *from, char *to, uint to_length
#ifndef DBUG_OFF
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 0950cd371eb..19664c5079f 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -129,6 +129,7 @@ bool select_union::flush()
table_alias name of the temporary table
bit_fields_as_long convert bit fields to ulonglong
create_table whether to physically create result table
+ keep_row_order keep rows in order as they were inserted
DESCRIPTION
Create a temporary table that is used to store the result of a UNION,
@@ -143,7 +144,8 @@ bool
select_union::create_result_table(THD *thd_arg, List<Item> *column_types,
bool is_union_distinct, ulonglong options,
const char *alias,
- bool bit_fields_as_long, bool create_table)
+ bool bit_fields_as_long, bool create_table,
+ bool keep_row_order)
{
DBUG_ASSERT(table == 0);
tmp_table_param.init();
@@ -153,7 +155,7 @@ select_union::create_result_table(THD *thd_arg, List<Item> *column_types,
if (! (table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
(ORDER*) 0, is_union_distinct, 1,
options, HA_POS_ERROR, alias,
- !create_table)))
+ !create_table, keep_row_order)))
return TRUE;
table->keys_in_use_for_query.clear_all();
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 663e2a1bc2b..41714772588 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -23,20 +23,13 @@
*/
%{
-/* thd is passed as an argument to yyparse(), and subsequently to yylex().
-** The type will be void*, so it must be cast to (THD*) when used.
-** Use the YYTHD macro for this.
-*/
-#define YYPARSE_PARAM yythd
-#define YYLEX_PARAM yythd
-#define YYTHD ((THD *)yythd)
-#define YYLIP (& YYTHD->m_parser_state->m_lip)
-#define YYPS (& YYTHD->m_parser_state->m_yacc)
+#define YYLIP (& thd->m_parser_state->m_lip)
+#define YYPS (& thd->m_parser_state->m_yacc)
#define MYSQL_YACC
#define YYINITDEPTH 100
#define YYMAXDEPTH 3200 /* Because of 64K stack */
-#define Lex (YYTHD->lex)
+#define Lex (thd->lex)
#define Select Lex->current_select
#include "sql_priv.h"
@@ -80,7 +73,7 @@ int yylex(void *yylval, void *yythd);
ulong val= *(F); \
if (my_yyoverflow((B), (D), &val)) \
{ \
- yyerror((char*) (A)); \
+ yyerror(current_thd, (char*) (A)); \
return 2; \
} \
else \
@@ -92,7 +85,7 @@ int yylex(void *yylval, void *yythd);
#define MYSQL_YYABORT \
do \
{ \
- LEX::cleanup_lex_after_parse_error(YYTHD);\
+ LEX::cleanup_lex_after_parse_error(thd); \
YYABORT; \
} while (0)
@@ -178,10 +171,8 @@ void my_parse_error(const char *s)
to abort from the parser.
*/
-void MYSQLerror(const char *s)
+void MYSQLerror(THD *thd, const char *s)
{
- THD *thd= current_thd;
-
/*
Restore the original LEX if it was replaced when parsing
a stored procedure. We must ensure that a parsing error
@@ -789,6 +780,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%}
%pure_parser /* We have threads */
+%parse-param { THD *thd }
+%lex-param { THD *thd }
/*
Currently there are 197 shift/reduce conflicts.
We should not introduce new conflicts any more.
@@ -1720,7 +1713,6 @@ rule: <-- starts at col 1
query:
END_OF_INPUT
{
- THD *thd= YYTHD;
if (!thd->bootstrap &&
(!(thd->lex->select_lex.options & OPTION_FOUND_COMMENT)))
{
@@ -1734,7 +1726,7 @@ query:
{
Lex_input_stream *lip = YYLIP;
- if ((YYTHD->client_capabilities & CLIENT_MULTI_QUERIES) &&
+ if ((thd->client_capabilities & CLIENT_MULTI_QUERIES) &&
lip->multi_statements &&
! lip->eof())
{
@@ -1833,7 +1825,6 @@ statement:
deallocate:
deallocate_or_drop PREPARE_SYM ident
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
lex->sql_command= SQLCOM_DEALLOCATE_PREPARE;
lex->prepared_stmt_name= $3;
@@ -1848,7 +1839,6 @@ deallocate_or_drop:
prepare:
PREPARE_SYM ident FROM prepare_src
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
lex->sql_command= SQLCOM_PREPARE;
lex->prepared_stmt_name= $2;
@@ -1858,14 +1848,12 @@ prepare:
prepare_src:
TEXT_STRING_sys
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
lex->prepared_stmt_code= $1;
lex->prepared_stmt_code_is_varref= FALSE;
}
| '@' ident_or_text
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
lex->prepared_stmt_code= $2;
lex->prepared_stmt_code_is_varref= TRUE;
@@ -1875,7 +1863,6 @@ prepare_src:
execute:
EXECUTE_SYM ident
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
lex->sql_command= SQLCOM_EXECUTE;
lex->prepared_stmt_name= $2;
@@ -2005,7 +1992,7 @@ master_def:
}
if (Lex->mi.heartbeat_period > slave_net_timeout)
{
- push_warning_printf(YYTHD, MYSQL_ERROR::WARN_LEVEL_WARN,
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX,
ER(ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX));
}
@@ -2013,7 +2000,7 @@ master_def:
{
if (Lex->mi.heartbeat_period != 0.0)
{
- push_warning_printf(YYTHD, MYSQL_ERROR::WARN_LEVEL_WARN,
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MIN,
ER(ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MIN));
Lex->mi.heartbeat_period= 0.0;
@@ -2107,7 +2094,6 @@ master_file_def:
optional_connection_name:
/* empty */
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
lex->mi.connection_name= thd->variables.default_master_connection;
}
@@ -2132,7 +2118,6 @@ connection_name:
create:
CREATE opt_table_options TABLE_SYM opt_if_not_exists table_ident
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
lex->sql_command= SQLCOM_CREATE_TABLE;
if (!lex->select_lex.add_table_to_list(thd, $5, NULL,
@@ -2157,13 +2142,13 @@ create:
}
create_body
{
- LEX *lex= YYTHD->lex;
+ LEX *lex= thd->lex;
lex->current_select= &lex->select_lex;
if ((lex->create_info.used_fields & HA_CREATE_USED_ENGINE) &&
!lex->create_info.db_type)
{
- lex->create_info.db_type= ha_default_handlerton(YYTHD);
- push_warning_printf(YYTHD, MYSQL_ERROR::WARN_LEVEL_WARN,
+ lex->create_info.db_type= ha_default_handlerton(thd);
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_USING_OTHER_HANDLER,
ER(ER_WARN_USING_OTHER_HANDLER),
hton_name(lex->create_info.db_type)->str,
@@ -2293,7 +2278,6 @@ server_option:
event_tail:
remember_name EVENT_SYM opt_if_not_exists sp_name
{
- THD *thd= YYTHD;
LEX *lex=Lex;
lex->stmt_definition_begin= $1;
@@ -2360,7 +2344,7 @@ opt_ev_status:
ev_starts:
/* empty */
{
- Item *item= new (YYTHD->mem_root) Item_func_now_local(0);
+ Item *item= new (thd->mem_root) Item_func_now_local(0);
if (item == NULL)
MYSQL_YYABORT;
Lex->event_parse_data->item_starts= item;
@@ -2410,7 +2394,6 @@ opt_ev_comment:
ev_sql_stmt:
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= YYLIP;
@@ -2453,7 +2436,6 @@ ev_sql_stmt:
}
ev_sql_stmt_inner
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
/* return back to the original memory root ASAP */
@@ -2512,11 +2494,10 @@ sp_name:
$$= new sp_name($1, $3, true);
if ($$ == NULL)
MYSQL_YYABORT;
- $$->init_qname(YYTHD);
+ $$->init_qname(thd);
}
| ident
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
LEX_STRING db;
if (check_routine_name(&$1))
@@ -2586,7 +2567,7 @@ call:
lex->sql_command= SQLCOM_CALL;
lex->spname= $2;
lex->value_list.empty();
- sp_add_used_routine(lex, YYTHD, $2, TYPE_ENUM_PROCEDURE);
+ sp_add_used_routine(lex, thd, $2, TYPE_ENUM_PROCEDURE);
}
opt_sp_cparam_list {}
;
@@ -2660,7 +2641,7 @@ sp_fdparam:
(enum enum_field_types)$3,
sp_param_in);
- if (lex->sphead->fill_field_definition(YYTHD, lex,
+ if (lex->sphead->fill_field_definition(thd, lex,
(enum enum_field_types) $3,
&spvar->field_def))
{
@@ -2697,7 +2678,7 @@ sp_pdparam:
(enum enum_field_types)$4,
(sp_param_mode_t)$1);
- if (lex->sphead->fill_field_definition(YYTHD, lex,
+ if (lex->sphead->fill_field_definition(thd, lex,
(enum enum_field_types) $4,
&spvar->field_def))
{
@@ -2760,13 +2741,12 @@ sp_decl:
{
LEX *lex= Lex;
- lex->sphead->reset_lex(YYTHD);
+ lex->sphead->reset_lex(thd);
lex->spcont->declare_var_boundary($2);
}
type_with_opt_collate
sp_opt_default
{
- THD *thd= YYTHD;
LEX *lex= Lex;
sp_pcontext *pctx= lex->spcont;
uint num_vars= pctx->context_var_count();
@@ -2792,7 +2772,7 @@ sp_decl:
spvar->type= var_type;
spvar->dflt= dflt_value_item;
- if (lex->sphead->fill_field_definition(YYTHD, lex, var_type,
+ if (lex->sphead->fill_field_definition(thd, lex, var_type,
&spvar->field_def))
{
MYSQL_YYABORT;
@@ -2816,7 +2796,7 @@ sp_decl:
}
pctx->declare_var_boundary(0);
- if (lex->sphead->restore_lex(YYTHD))
+ if (lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
$$.vars= $2;
$$.conds= $$.hndlrs= $$.curs= 0;
@@ -2831,7 +2811,7 @@ sp_decl:
my_error(ER_SP_DUP_COND, MYF(0), $2.str);
MYSQL_YYABORT;
}
- if(YYTHD->lex->spcont->push_cond(&$2, $5))
+ if(thd->lex->spcont->push_cond(&$2, $5))
MYSQL_YYABORT;
$$.vars= $$.hndlrs= $$.curs= 0;
$$.conds= 1;
@@ -2917,7 +2897,7 @@ sp_decl:
sp_cursor_stmt:
{
- Lex->sphead->reset_lex(YYTHD);
+ Lex->sphead->reset_lex(thd);
}
select
{
@@ -2933,7 +2913,7 @@ sp_cursor_stmt:
}
lex->sp_lex_in_use= TRUE;
$$= lex;
- if (lex->sphead->restore_lex(YYTHD))
+ if (lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
}
;
@@ -2982,7 +2962,7 @@ sp_cond:
my_error(ER_WRONG_VALUE, MYF(0), "CONDITION", "0");
MYSQL_YYABORT;
}
- $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t));
+ $$= (sp_cond_type_t *) thd->alloc(sizeof(sp_cond_type_t));
if ($$ == NULL)
MYSQL_YYABORT;
$$->type= sp_cond_type_t::number;
@@ -2999,7 +2979,7 @@ sqlstate:
my_error(ER_SP_BAD_SQLSTATE, MYF(0), $3.str);
MYSQL_YYABORT;
}
- $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t));
+ $$= (sp_cond_type_t *) thd->alloc(sizeof(sp_cond_type_t));
if ($$ == NULL)
MYSQL_YYABORT;
$$->type= sp_cond_type_t::state;
@@ -3029,21 +3009,21 @@ sp_hcond:
}
| SQLWARNING_SYM /* SQLSTATEs 01??? */
{
- $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t));
+ $$= (sp_cond_type_t *) thd->alloc(sizeof(sp_cond_type_t));
if ($$ == NULL)
MYSQL_YYABORT;
$$->type= sp_cond_type_t::warning;
}
| not FOUND_SYM /* SQLSTATEs 02??? */
{
- $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t));
+ $$= (sp_cond_type_t *) thd->alloc(sizeof(sp_cond_type_t));
if ($$ == NULL)
MYSQL_YYABORT;
$$->type= sp_cond_type_t::notfound;
}
| SQLEXCEPTION_SYM /* All other SQLSTATEs */
{
- $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t));
+ $$= (sp_cond_type_t *) thd->alloc(sizeof(sp_cond_type_t));
if ($$ == NULL)
MYSQL_YYABORT;
$$->type= sp_cond_type_t::exception;
@@ -3053,7 +3033,6 @@ sp_hcond:
signal_stmt:
SIGNAL_SYM signal_value opt_set_signal_information
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
Yacc_state *state= & thd->m_parser_state->m_yacc;
@@ -3103,7 +3082,7 @@ opt_signal_value:
opt_set_signal_information:
/* empty */
{
- YYTHD->m_parser_state->m_yacc.m_set_signal_info.clear();
+ thd->m_parser_state->m_yacc.m_set_signal_info.clear();
}
| SET signal_information_item_list
;
@@ -3112,7 +3091,7 @@ signal_information_item_list:
signal_condition_information_item_name EQ signal_allowed_expr
{
Set_signal_information *info;
- info= & YYTHD->m_parser_state->m_yacc.m_set_signal_info;
+ info= &thd->m_parser_state->m_yacc.m_set_signal_info;
int index= (int) $1;
info->clear();
info->m_item[index]= $3;
@@ -3121,7 +3100,7 @@ signal_information_item_list:
signal_condition_information_item_name EQ signal_allowed_expr
{
Set_signal_information *info;
- info= & YYTHD->m_parser_state->m_yacc.m_set_signal_info;
+ info= &thd->m_parser_state->m_yacc.m_set_signal_info;
int index= (int) $3;
if (info->m_item[index] != NULL)
{
@@ -3192,7 +3171,6 @@ signal_condition_information_item_name:
resignal_stmt:
RESIGNAL_SYM opt_signal_value opt_set_signal_information
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
Yacc_state *state= & thd->m_parser_state->m_yacc;
@@ -3267,7 +3245,6 @@ sp_proc_stmt_if:
sp_proc_stmt_statement:
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= YYLIP;
@@ -3276,7 +3253,6 @@ sp_proc_stmt_statement:
}
statement
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= YYLIP;
sp_head *sp= lex->sphead;
@@ -3323,7 +3299,7 @@ sp_proc_stmt_statement:
sp_proc_stmt_return:
RETURN_SYM
- { Lex->sphead->reset_lex(YYTHD); }
+ { Lex->sphead->reset_lex(thd); }
expr
{
LEX *lex= Lex;
@@ -3345,7 +3321,7 @@ sp_proc_stmt_return:
MYSQL_YYABORT;
sp->m_flags|= sp_head::HAS_RETURN;
}
- if (sp->restore_lex(YYTHD))
+ if (sp->restore_lex(thd))
MYSQL_YYABORT;
}
;
@@ -3572,7 +3548,7 @@ sp_fetch_list:
;
sp_if:
- { Lex->sphead->reset_lex(YYTHD); }
+ { Lex->sphead->reset_lex(thd); }
expr THEN_SYM
{
LEX *lex= Lex;
@@ -3586,7 +3562,7 @@ sp_if:
sp->add_cont_backpatch(i) ||
sp->add_instr(i))
MYSQL_YYABORT;
- if (sp->restore_lex(YYTHD))
+ if (sp->restore_lex(thd))
MYSQL_YYABORT;
}
sp_proc_stmts1
@@ -3625,7 +3601,7 @@ simple_case_stmt:
{
LEX *lex= Lex;
case_stmt_action_case(lex);
- lex->sphead->reset_lex(YYTHD); /* For expr $3 */
+ lex->sphead->reset_lex(thd); /* For expr $3 */
}
expr
{
@@ -3634,7 +3610,7 @@ simple_case_stmt:
MYSQL_YYABORT;
/* For expr $3 */
- if (lex->sphead->restore_lex(YYTHD))
+ if (lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
}
simple_when_clause_list
@@ -3676,7 +3652,7 @@ searched_when_clause_list:
simple_when_clause:
WHEN_SYM
{
- Lex->sphead->reset_lex(YYTHD); /* For expr $3 */
+ Lex->sphead->reset_lex(thd); /* For expr $3 */
}
expr
{
@@ -3686,7 +3662,7 @@ simple_when_clause:
if (case_stmt_action_when(lex, $3, true))
MYSQL_YYABORT;
/* For expr $3 */
- if (lex->sphead->restore_lex(YYTHD))
+ if (lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
}
THEN_SYM
@@ -3701,7 +3677,7 @@ simple_when_clause:
searched_when_clause:
WHEN_SYM
{
- Lex->sphead->reset_lex(YYTHD); /* For expr $3 */
+ Lex->sphead->reset_lex(thd); /* For expr $3 */
}
expr
{
@@ -3709,7 +3685,7 @@ searched_when_clause:
if (case_stmt_action_when(lex, $3, false))
MYSQL_YYABORT;
/* For expr $3 */
- if (lex->sphead->restore_lex(YYTHD))
+ if (lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
}
THEN_SYM
@@ -3873,7 +3849,7 @@ sp_unlabeled_control:
MYSQL_YYABORT;
}
| WHILE_SYM
- { Lex->sphead->reset_lex(YYTHD); }
+ { Lex->sphead->reset_lex(thd); }
expr DO_SYM
{
LEX *lex= Lex;
@@ -3887,7 +3863,7 @@ sp_unlabeled_control:
sp->new_cont_backpatch(i) ||
sp->add_instr(i))
MYSQL_YYABORT;
- if (sp->restore_lex(YYTHD))
+ if (sp->restore_lex(thd))
MYSQL_YYABORT;
}
sp_proc_stmts1 END WHILE_SYM
@@ -3902,7 +3878,7 @@ sp_unlabeled_control:
lex->sphead->do_cont_backpatch();
}
| REPEAT_SYM sp_proc_stmts1 UNTIL_SYM
- { Lex->sphead->reset_lex(YYTHD); }
+ { Lex->sphead->reset_lex(thd); }
expr END REPEAT_SYM
{
LEX *lex= Lex;
@@ -3914,7 +3890,7 @@ sp_unlabeled_control:
if (i == NULL ||
lex->sphead->add_instr(i))
MYSQL_YYABORT;
- if (lex->sphead->restore_lex(YYTHD))
+ if (lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
/* We can shortcut the cont_backpatch here */
i->m_cont_dest= ip+1;
@@ -4279,8 +4255,8 @@ ts_wait:
;
size_number:
- real_ulong_num { $$= $1;}
- | IDENT
+ real_ulonglong_num { $$= $1;}
+ | IDENT_sys
{
ulonglong number;
uint text_shift_number= 0;
@@ -4345,7 +4321,7 @@ create_body:
{
Lex->create_info.options|= HA_LEX_CREATE_TABLE_LIKE;
- TABLE_LIST *src_table= Lex->select_lex.add_table_to_list(YYTHD,
+ TABLE_LIST *src_table= Lex->select_lex.add_table_to_list(thd,
$1, NULL, 0, TL_READ, MDL_SHARED_READ);
if (! src_table)
MYSQL_YYABORT;
@@ -4935,7 +4911,7 @@ part_value_expr_item:
my_parse_error(ER(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR));
MYSQL_YYABORT;
}
- if (part_info->add_column_list_value(YYTHD, part_expr))
+ if (part_info->add_column_list_value(thd, part_expr))
{
MYSQL_YYABORT;
}
@@ -5315,25 +5291,25 @@ create_table_option:
}
| IDENT_sys equal TEXT_STRING_sys
{
- new (YYTHD->mem_root)
+ new (thd->mem_root)
engine_option_value($1, $3, true, &Lex->create_info.option_list,
&Lex->option_list_last);
}
| IDENT_sys equal ident
{
- new (YYTHD->mem_root)
+ new (thd->mem_root)
engine_option_value($1, $3, false, &Lex->create_info.option_list,
&Lex->option_list_last);
}
| IDENT_sys equal real_ulonglong_num
{
- new (YYTHD->mem_root)
+ new (thd->mem_root)
engine_option_value($1, $3, &Lex->create_info.option_list,
- &Lex->option_list_last, YYTHD->mem_root);
+ &Lex->option_list_last, thd->mem_root);
}
| IDENT_sys equal DEFAULT
{
- new (YYTHD->mem_root)
+ new (thd->mem_root)
engine_option_value($1, &Lex->create_info.option_list,
&Lex->option_list_last);
}
@@ -5377,19 +5353,19 @@ default_collation:
storage_engines:
ident_or_text
{
- plugin_ref plugin= ha_resolve_by_name(YYTHD, &$1);
+ plugin_ref plugin= ha_resolve_by_name(thd, &$1);
if (plugin)
$$= plugin_hton(plugin);
else
{
- if (YYTHD->variables.sql_mode & MODE_NO_ENGINE_SUBSTITUTION)
+ if (thd->variables.sql_mode & MODE_NO_ENGINE_SUBSTITUTION)
{
my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), $1.str);
MYSQL_YYABORT;
}
$$= 0;
- push_warning_printf(YYTHD, MYSQL_ERROR::WARN_LEVEL_WARN,
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_UNKNOWN_STORAGE_ENGINE,
ER(ER_UNKNOWN_STORAGE_ENGINE),
$1.str);
@@ -5401,7 +5377,7 @@ known_storage_engines:
ident_or_text
{
plugin_ref plugin;
- if ((plugin= ha_resolve_by_name(YYTHD, &$1)))
+ if ((plugin= ha_resolve_by_name(thd, &$1)))
$$= plugin_hton(plugin);
else
{
@@ -5734,7 +5710,7 @@ type:
{
char buff[sizeof("YEAR()") + MY_INT64_NUM_DECIMAL_DIGITS + 1];
my_snprintf(buff, sizeof(buff), "YEAR(%lu)", length);
- push_warning_printf(YYTHD, MYSQL_ERROR::WARN_LEVEL_NOTE,
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_WARN_DEPRECATED_SYNTAX,
ER(ER_WARN_DEPRECATED_SYNTAX),
buff, "YEAR(4)");
@@ -5748,7 +5724,7 @@ type:
{ $$=MYSQL_TYPE_TIME; }
| TIMESTAMP opt_field_length
{
- if (YYTHD->variables.sql_mode & MODE_MAXDB)
+ if (thd->variables.sql_mode & MODE_MAXDB)
$$=MYSQL_TYPE_DATETIME;
else
{
@@ -5880,7 +5856,7 @@ int_type:
real_type:
REAL
{
- $$= YYTHD->variables.sql_mode & MODE_REAL_AS_FLOAT ?
+ $$= thd->variables.sql_mode & MODE_REAL_AS_FLOAT ?
MYSQL_TYPE_FLOAT : MYSQL_TYPE_DOUBLE;
}
| DOUBLE_SYM
@@ -5955,7 +5931,7 @@ attribute:
| DEFAULT now_or_signed_literal { Lex->default_value=$2; }
| ON UPDATE_SYM NOW_SYM opt_default_time_precision
{
- Item *item= new (YYTHD->mem_root) Item_func_now_local($4);
+ Item *item= new (thd->mem_root) Item_func_now_local($4);
if (item == NULL)
MYSQL_YYABORT;
Lex->on_update_value= item;
@@ -6001,25 +5977,25 @@ attribute:
}
| IDENT_sys equal TEXT_STRING_sys
{
- new (YYTHD->mem_root)
+ new (thd->mem_root)
engine_option_value($1, $3, true, &Lex->option_list,
&Lex->option_list_last);
}
| IDENT_sys equal ident
{
- new (YYTHD->mem_root)
+ new (thd->mem_root)
engine_option_value($1, $3, false, &Lex->option_list,
&Lex->option_list_last);
}
| IDENT_sys equal real_ulonglong_num
{
- new (YYTHD->mem_root)
+ new (thd->mem_root)
engine_option_value($1, $3, &Lex->option_list,
- &Lex->option_list_last, YYTHD->mem_root);
+ &Lex->option_list_last, thd->mem_root);
}
| IDENT_sys equal DEFAULT
{
- new (YYTHD->mem_root)
+ new (thd->mem_root)
engine_option_value($1, &Lex->option_list, &Lex->option_list_last);
}
;
@@ -6049,7 +6025,7 @@ type_with_opt_collate:
now_or_signed_literal:
NOW_SYM opt_default_time_precision
{
- $$= new (YYTHD->mem_root) Item_func_now_local($2);
+ $$= new (thd->mem_root) Item_func_now_local($2);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -6398,25 +6374,25 @@ all_key_opt:
| COMMENT_SYM TEXT_STRING_sys { Lex->key_create_info.comment= $2; }
| IDENT_sys equal TEXT_STRING_sys
{
- new (YYTHD->mem_root)
+ new (thd->mem_root)
engine_option_value($1, $3, true, &Lex->option_list,
&Lex->option_list_last);
}
| IDENT_sys equal ident
{
- new (YYTHD->mem_root)
+ new (thd->mem_root)
engine_option_value($1, $3, false, &Lex->option_list,
&Lex->option_list_last);
}
| IDENT_sys equal real_ulonglong_num
{
- new (YYTHD->mem_root)
+ new (thd->mem_root)
engine_option_value($1, $3, &Lex->option_list,
- &Lex->option_list_last, YYTHD->mem_root);
+ &Lex->option_list_last, thd->mem_root);
}
| IDENT_sys equal DEFAULT
{
- new (YYTHD->mem_root)
+ new (thd->mem_root)
engine_option_value($1, &Lex->option_list, &Lex->option_list_last);
}
;
@@ -6508,7 +6484,6 @@ string_list:
alter:
ALTER alter_options TABLE_SYM table_ident
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
lex->name.str= 0;
lex->name.length= 0;
@@ -6534,7 +6509,6 @@ alter:
}
alter_commands
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
if (!lex->m_stmt)
{
@@ -6647,7 +6621,7 @@ alter:
Event_parse_data.
*/
- if (!(Lex->event_parse_data= Event_parse_data::new_instance(YYTHD)))
+ if (!(Lex->event_parse_data= Event_parse_data::new_instance(thd)))
MYSQL_YYABORT;
Lex->event_parse_data->identifier= $4;
@@ -6762,7 +6736,6 @@ alter_commands:
| OPTIMIZE PARTITION_SYM opt_no_write_to_binlog
all_or_alt_part_name_list
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
lex->no_write_to_binlog= $3;
lex->check_opt.init();
@@ -6776,7 +6749,6 @@ alter_commands:
| ANALYZE_SYM PARTITION_SYM opt_no_write_to_binlog
all_or_alt_part_name_list
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
lex->no_write_to_binlog= $3;
lex->check_opt.init();
@@ -6788,7 +6760,6 @@ alter_commands:
}
| CHECK_SYM PARTITION_SYM all_or_alt_part_name_list
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
lex->check_opt.init();
DBUG_ASSERT(!lex->m_stmt);
@@ -6801,7 +6772,6 @@ alter_commands:
| REPAIR PARTITION_SYM opt_no_write_to_binlog
all_or_alt_part_name_list
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
lex->no_write_to_binlog= $3;
lex->check_opt.init();
@@ -6821,7 +6791,6 @@ alter_commands:
}
| TRUNCATE_SYM PARTITION_SYM all_or_alt_part_name_list
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
lex->check_opt.init();
DBUG_ASSERT(!lex->m_stmt);
@@ -7081,7 +7050,6 @@ alter_list_item:
{
if (!$4)
{
- THD *thd= YYTHD;
$4= thd->variables.collation_database;
}
$5= $5 ? $5 : $4;
@@ -7309,7 +7277,6 @@ repair:
}
table_list opt_mi_repair_type
{
- THD *thd= YYTHD;
LEX* lex= thd->lex;
DBUG_ASSERT(!lex->m_stmt);
lex->m_stmt= new (thd->mem_root) Repair_table_statement(lex);
@@ -7347,7 +7314,6 @@ analyze:
}
analyze_table_list
{
- THD *thd= YYTHD;
LEX* lex= thd->lex;
DBUG_ASSERT(!lex->m_stmt);
lex->m_stmt= new (thd->mem_root) Analyze_table_statement(lex);
@@ -7370,7 +7336,6 @@ opt_persistent_stat_clause:
{}
| PERSISTENT_SYM FOR_SYM persistent_stat_spec
{
- THD *thd= YYTHD;
thd->lex->with_persistent_for_clause= TRUE;
}
;
@@ -7385,7 +7350,6 @@ persistent_column_stat_spec:
ALL {}
| '('
{
- THD *thd= YYTHD;
LEX* lex= thd->lex;
lex->column_list= new List<LEX_STRING>;
if (lex->column_list == NULL)
@@ -7399,7 +7363,6 @@ persistent_index_stat_spec:
ALL {}
| '('
{
- THD *thd= YYTHD;
LEX* lex= thd->lex;
lex->index_list= new List<LEX_STRING>;
if (lex->index_list == NULL)
@@ -7472,7 +7435,6 @@ check:
}
table_list opt_mi_check_type
{
- THD *thd= YYTHD;
LEX* lex= thd->lex;
DBUG_ASSERT(!lex->m_stmt);
lex->m_stmt= new (thd->mem_root) Check_table_statement(lex);
@@ -7513,7 +7475,6 @@ optimize:
}
table_list
{
- THD *thd= YYTHD;
LEX* lex= thd->lex;
DBUG_ASSERT(!lex->m_stmt);
lex->m_stmt= new (thd->mem_root) Optimize_table_statement(lex);
@@ -7598,7 +7559,7 @@ keycache_list:
assign_to_keycache:
table_ident cache_keys_spec
{
- if (!Select->add_table_to_list(YYTHD, $1, NULL, 0, TL_READ,
+ if (!Select->add_table_to_list(thd, $1, NULL, 0, TL_READ,
MDL_SHARED_READ,
Select->pop_index_hints()))
MYSQL_YYABORT;
@@ -7608,7 +7569,7 @@ assign_to_keycache:
assign_to_keycache_parts:
table_ident adm_partition cache_keys_spec
{
- if (!Select->add_table_to_list(YYTHD, $1, NULL, 0, TL_READ,
+ if (!Select->add_table_to_list(thd, $1, NULL, 0, TL_READ,
MDL_SHARED_READ,
Select->pop_index_hints()))
MYSQL_YYABORT;
@@ -7644,7 +7605,7 @@ preload_list:
preload_keys:
table_ident cache_keys_spec opt_ignore_leaves
{
- if (!Select->add_table_to_list(YYTHD, $1, NULL, $3, TL_READ,
+ if (!Select->add_table_to_list(thd, $1, NULL, $3, TL_READ,
MDL_SHARED_READ,
Select->pop_index_hints()))
MYSQL_YYABORT;
@@ -7654,7 +7615,7 @@ preload_keys:
preload_keys_parts:
table_ident adm_partition cache_keys_spec opt_ignore_leaves
{
- if (!Select->add_table_to_list(YYTHD, $1, NULL, $4, TL_READ,
+ if (!Select->add_table_to_list(thd, $1, NULL, $4, TL_READ,
MDL_SHARED_READ,
Select->pop_index_hints()))
MYSQL_YYABORT;
@@ -7671,7 +7632,7 @@ adm_partition:
cache_keys_spec:
{
- Lex->select_lex.alloc_index_hints(YYTHD);
+ Lex->select_lex.alloc_index_hints(thd);
Select->set_index_hint_type(INDEX_HINT_USE,
INDEX_HINT_MASK_ALL);
}
@@ -7884,7 +7845,6 @@ select_item_list:
| select_item
| '*'
{
- THD *thd= YYTHD;
Item *item= new (thd->mem_root)
Item_field(&thd->lex->current_select->context,
NULL, NULL, "*");
@@ -7899,14 +7859,11 @@ select_item_list:
select_item:
remember_name table_wild remember_end
{
- THD *thd= YYTHD;
-
if (add_item_to_list(thd, $2))
MYSQL_YYABORT;
}
| remember_name expr remember_end select_alias
{
- THD *thd= YYTHD;
DBUG_ASSERT($1 < $3);
if (add_item_to_list(thd, $2))
@@ -8014,7 +7971,7 @@ expr:
else
{
/* X OR Y */
- $$ = new (YYTHD->mem_root) Item_cond_or($1, $3);
+ $$ = new (thd->mem_root) Item_cond_or($1, $3);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -8022,7 +7979,7 @@ expr:
| expr XOR expr %prec XOR
{
/* XOR is a proprietary extension */
- $$ = new (YYTHD->mem_root) Item_func_xor($1, $3);
+ $$ = new (thd->mem_root) Item_func_xor($1, $3);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -8064,50 +8021,50 @@ expr:
else
{
/* X AND Y */
- $$ = new (YYTHD->mem_root) Item_cond_and($1, $3);
+ $$ = new (thd->mem_root) Item_cond_and($1, $3);
if ($$ == NULL)
MYSQL_YYABORT;
}
}
| NOT_SYM expr %prec NOT_SYM
{
- $$= negate_expression(YYTHD, $2);
+ $$= negate_expression(thd, $2);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bool_pri IS TRUE_SYM %prec IS
{
- $$= new (YYTHD->mem_root) Item_func_istrue($1);
+ $$= new (thd->mem_root) Item_func_istrue($1);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bool_pri IS not TRUE_SYM %prec IS
{
- $$= new (YYTHD->mem_root) Item_func_isnottrue($1);
+ $$= new (thd->mem_root) Item_func_isnottrue($1);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bool_pri IS FALSE_SYM %prec IS
{
- $$= new (YYTHD->mem_root) Item_func_isfalse($1);
+ $$= new (thd->mem_root) Item_func_isfalse($1);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bool_pri IS not FALSE_SYM %prec IS
{
- $$= new (YYTHD->mem_root) Item_func_isnotfalse($1);
+ $$= new (thd->mem_root) Item_func_isnotfalse($1);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bool_pri IS UNKNOWN_SYM %prec IS
{
- $$= new (YYTHD->mem_root) Item_func_isnull($1);
+ $$= new (thd->mem_root) Item_func_isnull($1);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bool_pri IS not UNKNOWN_SYM %prec IS
{
- $$= new (YYTHD->mem_root) Item_func_isnotnull($1);
+ $$= new (thd->mem_root) Item_func_isnotnull($1);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -8117,19 +8074,19 @@ expr:
bool_pri:
bool_pri IS NULL_SYM %prec IS
{
- $$= new (YYTHD->mem_root) Item_func_isnull($1);
+ $$= new (thd->mem_root) Item_func_isnull($1);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bool_pri IS not NULL_SYM %prec IS
{
- $$= new (YYTHD->mem_root) Item_func_isnotnull($1);
+ $$= new (thd->mem_root) Item_func_isnotnull($1);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bool_pri EQUAL_SYM predicate %prec EQUAL_SYM
{
- $$= new (YYTHD->mem_root) Item_func_equal($1,$3);
+ $$= new (thd->mem_root) Item_func_equal($1,$3);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -8151,13 +8108,12 @@ bool_pri:
predicate:
bit_expr IN_SYM '(' subselect ')'
{
- $$= new (YYTHD->mem_root) Item_in_subselect($1, $4);
+ $$= new (thd->mem_root) Item_in_subselect($1, $4);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bit_expr not IN_SYM '(' subselect ')'
{
- THD *thd= YYTHD;
Item *item= new (thd->mem_root) Item_in_subselect($1, $5);
if (item == NULL)
MYSQL_YYABORT;
@@ -8167,7 +8123,7 @@ predicate:
}
| bit_expr IN_SYM '(' expr ')'
{
- $$= handle_sql2003_note184_exception(YYTHD, $1, true, $4);
+ $$= handle_sql2003_note184_exception(thd, $1, true, $4);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -8175,13 +8131,13 @@ predicate:
{
$6->push_front($4);
$6->push_front($1);
- $$= new (YYTHD->mem_root) Item_func_in(*$6);
+ $$= new (thd->mem_root) Item_func_in(*$6);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bit_expr not IN_SYM '(' expr ')'
{
- $$= handle_sql2003_note184_exception(YYTHD, $1, false, $5);
+ $$= handle_sql2003_note184_exception(thd, $1, false, $5);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -8189,7 +8145,7 @@ predicate:
{
$7->push_front($5);
$7->push_front($1);
- Item_func_in *item = new (YYTHD->mem_root) Item_func_in(*$7);
+ Item_func_in *item = new (thd->mem_root) Item_func_in(*$7);
if (item == NULL)
MYSQL_YYABORT;
item->negate();
@@ -8197,14 +8153,14 @@ predicate:
}
| bit_expr BETWEEN_SYM bit_expr AND_SYM predicate
{
- $$= new (YYTHD->mem_root) Item_func_between($1,$3,$5);
+ $$= new (thd->mem_root) Item_func_between($1,$3,$5);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bit_expr not BETWEEN_SYM bit_expr AND_SYM predicate
{
Item_func_between *item;
- item= new (YYTHD->mem_root) Item_func_between($1,$4,$6);
+ item= new (thd->mem_root) Item_func_between($1,$4,$6);
if (item == NULL)
MYSQL_YYABORT;
item->negate();
@@ -8212,42 +8168,42 @@ predicate:
}
| bit_expr SOUNDS_SYM LIKE bit_expr
{
- Item *item1= new (YYTHD->mem_root) Item_func_soundex($1);
- Item *item4= new (YYTHD->mem_root) Item_func_soundex($4);
+ Item *item1= new (thd->mem_root) Item_func_soundex($1);
+ Item *item4= new (thd->mem_root) Item_func_soundex($4);
if ((item1 == NULL) || (item4 == NULL))
MYSQL_YYABORT;
- $$= new (YYTHD->mem_root) Item_func_eq(item1, item4);
+ $$= new (thd->mem_root) Item_func_eq(item1, item4);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bit_expr LIKE simple_expr opt_escape
{
- $$= new (YYTHD->mem_root) Item_func_like($1,$3,$4,Lex->escape_used);
+ $$= new (thd->mem_root) Item_func_like($1,$3,$4,Lex->escape_used);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bit_expr not LIKE simple_expr opt_escape
{
- Item *item= new (YYTHD->mem_root) Item_func_like($1,$4,$5,
+ Item *item= new (thd->mem_root) Item_func_like($1,$4,$5,
Lex->escape_used);
if (item == NULL)
MYSQL_YYABORT;
- $$= new (YYTHD->mem_root) Item_func_not(item);
+ $$= new (thd->mem_root) Item_func_not(item);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bit_expr REGEXP bit_expr
{
- $$= new (YYTHD->mem_root) Item_func_regex($1,$3);
+ $$= new (thd->mem_root) Item_func_regex($1,$3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bit_expr not REGEXP bit_expr
{
- Item *item= new (YYTHD->mem_root) Item_func_regex($1,$4);
+ Item *item= new (thd->mem_root) Item_func_regex($1,$4);
if (item == NULL)
MYSQL_YYABORT;
- $$= negate_expression(YYTHD, item);
+ $$= negate_expression(thd, item);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -8257,85 +8213,85 @@ predicate:
bit_expr:
bit_expr '|' bit_expr %prec '|'
{
- $$= new (YYTHD->mem_root) Item_func_bit_or($1,$3);
+ $$= new (thd->mem_root) Item_func_bit_or($1,$3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bit_expr '&' bit_expr %prec '&'
{
- $$= new (YYTHD->mem_root) Item_func_bit_and($1,$3);
+ $$= new (thd->mem_root) Item_func_bit_and($1,$3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bit_expr SHIFT_LEFT bit_expr %prec SHIFT_LEFT
{
- $$= new (YYTHD->mem_root) Item_func_shift_left($1,$3);
+ $$= new (thd->mem_root) Item_func_shift_left($1,$3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bit_expr SHIFT_RIGHT bit_expr %prec SHIFT_RIGHT
{
- $$= new (YYTHD->mem_root) Item_func_shift_right($1,$3);
+ $$= new (thd->mem_root) Item_func_shift_right($1,$3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bit_expr '+' bit_expr %prec '+'
{
- $$= new (YYTHD->mem_root) Item_func_plus($1,$3);
+ $$= new (thd->mem_root) Item_func_plus($1,$3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bit_expr '-' bit_expr %prec '-'
{
- $$= new (YYTHD->mem_root) Item_func_minus($1,$3);
+ $$= new (thd->mem_root) Item_func_minus($1,$3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bit_expr '+' INTERVAL_SYM expr interval %prec '+'
{
- $$= new (YYTHD->mem_root) Item_date_add_interval($1,$4,$5,0);
+ $$= new (thd->mem_root) Item_date_add_interval($1,$4,$5,0);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bit_expr '-' INTERVAL_SYM expr interval %prec '-'
{
- $$= new (YYTHD->mem_root) Item_date_add_interval($1,$4,$5,1);
+ $$= new (thd->mem_root) Item_date_add_interval($1,$4,$5,1);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bit_expr '*' bit_expr %prec '*'
{
- $$= new (YYTHD->mem_root) Item_func_mul($1,$3);
+ $$= new (thd->mem_root) Item_func_mul($1,$3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bit_expr '/' bit_expr %prec '/'
{
- $$= new (YYTHD->mem_root) Item_func_div($1,$3);
+ $$= new (thd->mem_root) Item_func_div($1,$3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bit_expr '%' bit_expr %prec '%'
{
- $$= new (YYTHD->mem_root) Item_func_mod($1,$3);
+ $$= new (thd->mem_root) Item_func_mod($1,$3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bit_expr DIV_SYM bit_expr %prec DIV_SYM
{
- $$= new (YYTHD->mem_root) Item_func_int_div($1,$3);
+ $$= new (thd->mem_root) Item_func_int_div($1,$3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bit_expr MOD_SYM bit_expr %prec MOD_SYM
{
- $$= new (YYTHD->mem_root) Item_func_mod($1,$3);
+ $$= new (thd->mem_root) Item_func_mod($1,$3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bit_expr '^' bit_expr
{
- $$= new (YYTHD->mem_root) Item_func_bit_xor($1,$3);
+ $$= new (thd->mem_root) Item_func_bit_xor($1,$3);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -8471,7 +8427,7 @@ dyncall_create_element:
{
LEX *lex= Lex;
$$= (DYNCALL_CREATE_DEF *)
- alloc_root(YYTHD->mem_root, sizeof(DYNCALL_CREATE_DEF));
+ alloc_root(thd->mem_root, sizeof(DYNCALL_CREATE_DEF));
if ($$ == NULL)
MYSQL_YYABORT;
$$->key= $1;
@@ -8491,7 +8447,7 @@ dyncall_create_element:
dyncall_create_list:
dyncall_create_element
{
- $$= new (YYTHD->mem_root) List<DYNCALL_CREATE_DEF>;
+ $$= new (thd->mem_root) List<DYNCALL_CREATE_DEF>;
if ($$ == NULL)
MYSQL_YYABORT;
$$->push_back($1);
@@ -8511,7 +8467,6 @@ simple_expr:
| function_call_conflict
| simple_expr COLLATE_SYM ident_or_text %prec NEG
{
- THD *thd= YYTHD;
Item *i1= new (thd->mem_root) Item_string($3.str,
$3.length,
thd->charset());
@@ -8527,7 +8482,7 @@ simple_expr:
| sum_expr
| simple_expr OR_OR_SYM simple_expr
{
- $$= new (YYTHD->mem_root) Item_func_concat($1, $3);
+ $$= new (thd->mem_root) Item_func_concat($1, $3);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -8537,25 +8492,25 @@ simple_expr:
}
| '-' simple_expr %prec NEG
{
- $$= new (YYTHD->mem_root) Item_func_neg($2);
+ $$= new (thd->mem_root) Item_func_neg($2);
if ($$ == NULL)
MYSQL_YYABORT;
}
| '~' simple_expr %prec NEG
{
- $$= new (YYTHD->mem_root) Item_func_bit_neg($2);
+ $$= new (thd->mem_root) Item_func_bit_neg($2);
if ($$ == NULL)
MYSQL_YYABORT;
}
| not2 simple_expr %prec NEG
{
- $$= negate_expression(YYTHD, $2);
+ $$= negate_expression(thd, $2);
if ($$ == NULL)
MYSQL_YYABORT;
}
| '(' subselect ')'
{
- $$= new (YYTHD->mem_root) Item_singlerow_subselect($2);
+ $$= new (thd->mem_root) Item_singlerow_subselect($2);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -8564,20 +8519,20 @@ simple_expr:
| '(' expr ',' expr_list ')'
{
$4->push_front($2);
- $$= new (YYTHD->mem_root) Item_row(*$4);
+ $$= new (thd->mem_root) Item_row(*$4);
if ($$ == NULL)
MYSQL_YYABORT;
}
| ROW_SYM '(' expr ',' expr_list ')'
{
$5->push_front($3);
- $$= new (YYTHD->mem_root) Item_row(*$5);
+ $$= new (thd->mem_root) Item_row(*$5);
if ($$ == NULL)
MYSQL_YYABORT;
}
| EXISTS '(' subselect ')'
{
- $$= new (YYTHD->mem_root) Item_exists_subselect($3);
+ $$= new (thd->mem_root) Item_exists_subselect($3);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -8586,7 +8541,7 @@ simple_expr:
| MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')'
{
$2->push_front($5);
- Item_func_match *i1= new (YYTHD->mem_root) Item_func_match(*$2, $6);
+ Item_func_match *i1= new (thd->mem_root) Item_func_match(*$2, $6);
if (i1 == NULL)
MYSQL_YYABORT;
Select->add_ftfunc_to_list(i1);
@@ -8594,7 +8549,7 @@ simple_expr:
}
| BINARY simple_expr %prec NEG
{
- $$= create_func_cast(YYTHD, $2, ITEM_CAST_CHAR, NULL, NULL,
+ $$= create_func_cast(thd, $2, ITEM_CAST_CHAR, NULL, NULL,
&my_charset_bin);
if ($$ == NULL)
MYSQL_YYABORT;
@@ -8602,27 +8557,27 @@ simple_expr:
| CAST_SYM '(' expr AS cast_type ')'
{
LEX *lex= Lex;
- $$= create_func_cast(YYTHD, $3, $5, lex->length, lex->dec,
+ $$= create_func_cast(thd, $3, $5, lex->length, lex->dec,
lex->charset);
if ($$ == NULL)
MYSQL_YYABORT;
}
| CASE_SYM opt_expr when_list opt_else END
{
- $$= new (YYTHD->mem_root) Item_func_case(* $3, $2, $4 );
+ $$= new (thd->mem_root) Item_func_case(* $3, $2, $4 );
if ($$ == NULL)
MYSQL_YYABORT;
}
| CONVERT_SYM '(' expr ',' cast_type ')'
{
- $$= create_func_cast(YYTHD, $3, $5, Lex->length, Lex->dec,
+ $$= create_func_cast(thd, $3, $5, Lex->length, Lex->dec,
Lex->charset);
if ($$ == NULL)
MYSQL_YYABORT;
}
| CONVERT_SYM '(' expr USING charset_name ')'
{
- $$= new (YYTHD->mem_root) Item_func_conv_charset($3,$5);
+ $$= new (thd->mem_root) Item_func_conv_charset($3,$5);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -8635,14 +8590,14 @@ simple_expr:
my_error(ER_WRONG_COLUMN_NAME, MYF(0), il->my_name()->str);
MYSQL_YYABORT;
}
- $$= new (YYTHD->mem_root) Item_default_value(Lex->current_context(),
+ $$= new (thd->mem_root) Item_default_value(Lex->current_context(),
$3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| VALUES '(' simple_ident_nospvar ')'
{
- $$= new (YYTHD->mem_root) Item_insert_value(Lex->current_context(),
+ $$= new (thd->mem_root) Item_insert_value(Lex->current_context(),
$3);
if ($$ == NULL)
MYSQL_YYABORT;
@@ -8650,7 +8605,7 @@ simple_expr:
| INTERVAL_SYM expr interval '+' expr %prec INTERVAL_SYM
/* we cannot put interval before - */
{
- $$= new (YYTHD->mem_root) Item_date_add_interval($5,$2,$3,0);
+ $$= new (thd->mem_root) Item_date_add_interval($5,$2,$3,0);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -8665,19 +8620,19 @@ simple_expr:
function_call_keyword:
CHAR_SYM '(' expr_list ')'
{
- $$= new (YYTHD->mem_root) Item_func_char(*$3);
+ $$= new (thd->mem_root) Item_func_char(*$3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| CHAR_SYM '(' expr_list USING charset_name ')'
{
- $$= new (YYTHD->mem_root) Item_func_char(*$3, $5);
+ $$= new (thd->mem_root) Item_func_char(*$3, $5);
if ($$ == NULL)
MYSQL_YYABORT;
}
| CURRENT_USER optional_braces
{
- $$= new (YYTHD->mem_root) Item_func_current_user(Lex->current_context());
+ $$= new (thd->mem_root) Item_func_current_user(Lex->current_context());
if ($$ == NULL)
MYSQL_YYABORT;
Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION);
@@ -8685,31 +8640,30 @@ function_call_keyword:
}
| DATE_SYM '(' expr ')'
{
- $$= new (YYTHD->mem_root) Item_date_typecast($3);
+ $$= new (thd->mem_root) Item_date_typecast($3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| DAY_SYM '(' expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_dayofmonth($3);
+ $$= new (thd->mem_root) Item_func_dayofmonth($3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| HOUR_SYM '(' expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_hour($3);
+ $$= new (thd->mem_root) Item_func_hour($3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| INSERT '(' expr ',' expr ',' expr ',' expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_insert($3,$5,$7,$9);
+ $$= new (thd->mem_root) Item_func_insert($3,$5,$7,$9);
if ($$ == NULL)
MYSQL_YYABORT;
}
| INTERVAL_SYM '(' expr ',' expr ')' %prec INTERVAL_SYM
{
- THD *thd= YYTHD;
List<Item> *list= new (thd->mem_root) List<Item>;
if (list == NULL)
MYSQL_YYABORT;
@@ -8724,7 +8678,6 @@ function_call_keyword:
}
| INTERVAL_SYM '(' expr ',' expr ',' expr_list ')' %prec INTERVAL_SYM
{
- THD *thd= YYTHD;
$7->push_front($5);
$7->push_front($3);
Item_row *item= new (thd->mem_root) Item_row(*$7);
@@ -8736,103 +8689,103 @@ function_call_keyword:
}
| LEFT '(' expr ',' expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_left($3,$5);
+ $$= new (thd->mem_root) Item_func_left($3,$5);
if ($$ == NULL)
MYSQL_YYABORT;
}
| MINUTE_SYM '(' expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_minute($3);
+ $$= new (thd->mem_root) Item_func_minute($3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| MONTH_SYM '(' expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_month($3);
+ $$= new (thd->mem_root) Item_func_month($3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| RIGHT '(' expr ',' expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_right($3,$5);
+ $$= new (thd->mem_root) Item_func_right($3,$5);
if ($$ == NULL)
MYSQL_YYABORT;
}
| SECOND_SYM '(' expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_second($3);
+ $$= new (thd->mem_root) Item_func_second($3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| TIME_SYM '(' expr ')'
{
- $$= new (YYTHD->mem_root) Item_time_typecast($3, AUTO_SEC_PART_DIGITS);
+ $$= new (thd->mem_root) Item_time_typecast($3, AUTO_SEC_PART_DIGITS);
if ($$ == NULL)
MYSQL_YYABORT;
}
| TIMESTAMP '(' expr ')'
{
- $$= new (YYTHD->mem_root) Item_datetime_typecast($3, AUTO_SEC_PART_DIGITS);
+ $$= new (thd->mem_root) Item_datetime_typecast($3, AUTO_SEC_PART_DIGITS);
if ($$ == NULL)
MYSQL_YYABORT;
}
| TIMESTAMP '(' expr ',' expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_add_time($3, $5, 1, 0);
+ $$= new (thd->mem_root) Item_func_add_time($3, $5, 1, 0);
if ($$ == NULL)
MYSQL_YYABORT;
}
| TRIM '(' expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_trim($3);
+ $$= new (thd->mem_root) Item_func_trim($3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| TRIM '(' LEADING expr FROM expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_ltrim($6,$4);
+ $$= new (thd->mem_root) Item_func_ltrim($6,$4);
if ($$ == NULL)
MYSQL_YYABORT;
}
| TRIM '(' TRAILING expr FROM expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_rtrim($6,$4);
+ $$= new (thd->mem_root) Item_func_rtrim($6,$4);
if ($$ == NULL)
MYSQL_YYABORT;
}
| TRIM '(' BOTH expr FROM expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_trim($6,$4);
+ $$= new (thd->mem_root) Item_func_trim($6,$4);
if ($$ == NULL)
MYSQL_YYABORT;
}
| TRIM '(' LEADING FROM expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_ltrim($5);
+ $$= new (thd->mem_root) Item_func_ltrim($5);
if ($$ == NULL)
MYSQL_YYABORT;
}
| TRIM '(' TRAILING FROM expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_rtrim($5);
+ $$= new (thd->mem_root) Item_func_rtrim($5);
if ($$ == NULL)
MYSQL_YYABORT;
}
| TRIM '(' BOTH FROM expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_trim($5);
+ $$= new (thd->mem_root) Item_func_trim($5);
if ($$ == NULL)
MYSQL_YYABORT;
}
| TRIM '(' expr FROM expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_trim($5,$3);
+ $$= new (thd->mem_root) Item_func_trim($5,$3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| USER '(' ')'
{
- $$= new (YYTHD->mem_root) Item_func_user();
+ $$= new (thd->mem_root) Item_func_user();
if ($$ == NULL)
MYSQL_YYABORT;
Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION);
@@ -8840,7 +8793,7 @@ function_call_keyword:
}
| YEAR_SYM '(' expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_year($3);
+ $$= new (thd->mem_root) Item_func_year($3);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -8861,27 +8814,27 @@ function_call_keyword:
function_call_nonkeyword:
ADDDATE_SYM '(' expr ',' expr ')'
{
- $$= new (YYTHD->mem_root) Item_date_add_interval($3, $5,
+ $$= new (thd->mem_root) Item_date_add_interval($3, $5,
INTERVAL_DAY, 0);
if ($$ == NULL)
MYSQL_YYABORT;
}
| ADDDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')'
{
- $$= new (YYTHD->mem_root) Item_date_add_interval($3, $6, $7, 0);
+ $$= new (thd->mem_root) Item_date_add_interval($3, $6, $7, 0);
if ($$ == NULL)
MYSQL_YYABORT;
}
| CURDATE optional_braces
{
- $$= new (YYTHD->mem_root) Item_func_curdate_local();
+ $$= new (thd->mem_root) Item_func_curdate_local();
if ($$ == NULL)
MYSQL_YYABORT;
Lex->safe_to_cache_query=0;
}
| CURTIME opt_time_precision
{
- $$= new (YYTHD->mem_root) Item_func_curtime_local($2);
+ $$= new (thd->mem_root) Item_func_curtime_local($2);
if ($$ == NULL)
MYSQL_YYABORT;
Lex->safe_to_cache_query=0;
@@ -8889,76 +8842,76 @@ function_call_nonkeyword:
| DATE_ADD_INTERVAL '(' expr ',' INTERVAL_SYM expr interval ')'
%prec INTERVAL_SYM
{
- $$= new (YYTHD->mem_root) Item_date_add_interval($3,$6,$7,0);
+ $$= new (thd->mem_root) Item_date_add_interval($3,$6,$7,0);
if ($$ == NULL)
MYSQL_YYABORT;
}
| DATE_SUB_INTERVAL '(' expr ',' INTERVAL_SYM expr interval ')'
%prec INTERVAL_SYM
{
- $$= new (YYTHD->mem_root) Item_date_add_interval($3,$6,$7,1);
+ $$= new (thd->mem_root) Item_date_add_interval($3,$6,$7,1);
if ($$ == NULL)
MYSQL_YYABORT;
}
| EXTRACT_SYM '(' interval FROM expr ')'
{
- $$=new (YYTHD->mem_root) Item_extract( $3, $5);
+ $$=new (thd->mem_root) Item_extract( $3, $5);
if ($$ == NULL)
MYSQL_YYABORT;
}
| GET_FORMAT '(' date_time_type ',' expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_get_format($3, $5);
+ $$= new (thd->mem_root) Item_func_get_format($3, $5);
if ($$ == NULL)
MYSQL_YYABORT;
}
| NOW_SYM opt_time_precision
{
- $$= new (YYTHD->mem_root) Item_func_now_local($2);
+ $$= new (thd->mem_root) Item_func_now_local($2);
if ($$ == NULL)
MYSQL_YYABORT;
Lex->safe_to_cache_query=0;
}
| POSITION_SYM '(' bit_expr IN_SYM expr ')'
{
- $$ = new (YYTHD->mem_root) Item_func_locate($5,$3);
+ $$ = new (thd->mem_root) Item_func_locate($5,$3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| SUBDATE_SYM '(' expr ',' expr ')'
{
- $$= new (YYTHD->mem_root) Item_date_add_interval($3, $5,
+ $$= new (thd->mem_root) Item_date_add_interval($3, $5,
INTERVAL_DAY, 1);
if ($$ == NULL)
MYSQL_YYABORT;
}
| SUBDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')'
{
- $$= new (YYTHD->mem_root) Item_date_add_interval($3, $6, $7, 1);
+ $$= new (thd->mem_root) Item_date_add_interval($3, $6, $7, 1);
if ($$ == NULL)
MYSQL_YYABORT;
}
| SUBSTRING '(' expr ',' expr ',' expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_substr($3,$5,$7);
+ $$= new (thd->mem_root) Item_func_substr($3,$5,$7);
if ($$ == NULL)
MYSQL_YYABORT;
}
| SUBSTRING '(' expr ',' expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_substr($3,$5);
+ $$= new (thd->mem_root) Item_func_substr($3,$5);
if ($$ == NULL)
MYSQL_YYABORT;
}
| SUBSTRING '(' expr FROM expr FOR_SYM expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_substr($3,$5,$7);
+ $$= new (thd->mem_root) Item_func_substr($3,$5,$7);
if ($$ == NULL)
MYSQL_YYABORT;
}
| SUBSTRING '(' expr FROM expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_substr($3,$5);
+ $$= new (thd->mem_root) Item_func_substr($3,$5);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -8973,42 +8926,42 @@ function_call_nonkeyword:
*/
Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION);
if (global_system_variables.sysdate_is_now == 0)
- $$= new (YYTHD->mem_root) Item_func_sysdate_local($2);
+ $$= new (thd->mem_root) Item_func_sysdate_local($2);
else
- $$= new (YYTHD->mem_root) Item_func_now_local($2);
+ $$= new (thd->mem_root) Item_func_now_local($2);
if ($$ == NULL)
MYSQL_YYABORT;
Lex->safe_to_cache_query=0;
}
| TIMESTAMP_ADD '(' interval_time_stamp ',' expr ',' expr ')'
{
- $$= new (YYTHD->mem_root) Item_date_add_interval($7,$5,$3,0);
+ $$= new (thd->mem_root) Item_date_add_interval($7,$5,$3,0);
if ($$ == NULL)
MYSQL_YYABORT;
}
| TIMESTAMP_DIFF '(' interval_time_stamp ',' expr ',' expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_timestamp_diff($5,$7,$3);
+ $$= new (thd->mem_root) Item_func_timestamp_diff($5,$7,$3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| UTC_DATE_SYM optional_braces
{
- $$= new (YYTHD->mem_root) Item_func_curdate_utc();
+ $$= new (thd->mem_root) Item_func_curdate_utc();
if ($$ == NULL)
MYSQL_YYABORT;
Lex->safe_to_cache_query=0;
}
| UTC_TIME_SYM opt_time_precision
{
- $$= new (YYTHD->mem_root) Item_func_curtime_utc($2);
+ $$= new (thd->mem_root) Item_func_curtime_utc($2);
if ($$ == NULL)
MYSQL_YYABORT;
Lex->safe_to_cache_query=0;
}
| UTC_TIMESTAMP_SYM opt_time_precision
{
- $$= new (YYTHD->mem_root) Item_func_now_utc($2);
+ $$= new (thd->mem_root) Item_func_now_utc($2);
if ($$ == NULL)
MYSQL_YYABORT;
Lex->safe_to_cache_query=0;
@@ -9016,28 +8969,28 @@ function_call_nonkeyword:
|
COLUMN_ADD_SYM '(' expr ',' dyncall_create_list ')'
{
- $$= create_func_dyncol_add(YYTHD, $3, *$5);
+ $$= create_func_dyncol_add(thd, $3, *$5);
if ($$ == NULL)
MYSQL_YYABORT;
}
|
COLUMN_DELETE_SYM '(' expr ',' expr_list ')'
{
- $$= create_func_dyncol_delete(YYTHD, $3, *$5);
+ $$= create_func_dyncol_delete(thd, $3, *$5);
if ($$ == NULL)
MYSQL_YYABORT;
}
|
COLUMN_CHECK_SYM '(' expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_dyncol_check($3);
+ $$= new (thd->mem_root) Item_func_dyncol_check($3);
if ($$ == NULL)
MYSQL_YYABORT;
}
|
COLUMN_CREATE_SYM '(' dyncall_create_list ')'
{
- $$= create_func_dyncol_create(YYTHD, *$3);
+ $$= create_func_dyncol_create(thd, *$3);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -9045,7 +8998,7 @@ function_call_nonkeyword:
COLUMN_GET_SYM '(' expr ',' expr AS cast_type ')'
{
LEX *lex= Lex;
- $$= create_func_dyncol_get(YYTHD, $3, $5, $7,
+ $$= create_func_dyncol_get(thd, $3, $5, $7,
lex->length, lex->dec,
lex->charset);
if ($$ == NULL)
@@ -9061,68 +9014,67 @@ function_call_nonkeyword:
function_call_conflict:
ASCII_SYM '(' expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_ascii($3);
+ $$= new (thd->mem_root) Item_func_ascii($3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| CHARSET '(' expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_charset($3);
+ $$= new (thd->mem_root) Item_func_charset($3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| COALESCE '(' expr_list ')'
{
- $$= new (YYTHD->mem_root) Item_func_coalesce(* $3);
+ $$= new (thd->mem_root) Item_func_coalesce(* $3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| COLLATION_SYM '(' expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_collation($3);
+ $$= new (thd->mem_root) Item_func_collation($3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| DATABASE '(' ')'
{
- $$= new (YYTHD->mem_root) Item_func_database();
+ $$= new (thd->mem_root) Item_func_database();
if ($$ == NULL)
MYSQL_YYABORT;
Lex->safe_to_cache_query=0;
}
| IF '(' expr ',' expr ',' expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_if($3,$5,$7);
+ $$= new (thd->mem_root) Item_func_if($3,$5,$7);
if ($$ == NULL)
MYSQL_YYABORT;
}
| LAST_VALUE '(' expr_list ')'
{
- $$= new (YYTHD->mem_root) Item_func_last_value(* $3);
+ $$= new (thd->mem_root) Item_func_last_value(* $3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| MICROSECOND_SYM '(' expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_microsecond($3);
+ $$= new (thd->mem_root) Item_func_microsecond($3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| MOD_SYM '(' expr ',' expr ')'
{
- $$ = new (YYTHD->mem_root) Item_func_mod($3, $5);
+ $$ = new (thd->mem_root) Item_func_mod($3, $5);
if ($$ == NULL)
MYSQL_YYABORT;
}
| OLD_PASSWORD '(' expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_old_password($3);
+ $$= new (thd->mem_root) Item_func_old_password($3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| PASSWORD '(' expr ')'
{
- THD *thd= YYTHD;
Item* i1;
if (thd->variables.old_passwords)
i1= new (thd->mem_root) Item_func_old_password($3);
@@ -9134,31 +9086,30 @@ function_call_conflict:
}
| QUARTER_SYM '(' expr ')'
{
- $$ = new (YYTHD->mem_root) Item_func_quarter($3);
+ $$ = new (thd->mem_root) Item_func_quarter($3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| REPEAT_SYM '(' expr ',' expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_repeat($3,$5);
+ $$= new (thd->mem_root) Item_func_repeat($3,$5);
if ($$ == NULL)
MYSQL_YYABORT;
}
| REPLACE '(' expr ',' expr ',' expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_replace($3,$5,$7);
+ $$= new (thd->mem_root) Item_func_replace($3,$5,$7);
if ($$ == NULL)
MYSQL_YYABORT;
}
| TRUNCATE_SYM '(' expr ',' expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_round($3,$5,1);
+ $$= new (thd->mem_root) Item_func_round($3,$5,1);
if ($$ == NULL)
MYSQL_YYABORT;
}
| WEEK_SYM '(' expr ')'
{
- THD *thd= YYTHD;
Item *i1= new (thd->mem_root) Item_int((char*) "0",
thd->variables.default_week_format,
1);
@@ -9170,7 +9121,7 @@ function_call_conflict:
}
| WEEK_SYM '(' expr ',' expr ')'
{
- $$= new (YYTHD->mem_root) Item_func_week($3,$5);
+ $$= new (thd->mem_root) Item_func_week($3,$5);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -9192,52 +9143,52 @@ function_call_conflict:
geometry_function:
CONTAINS_SYM '(' expr ',' expr ')'
{
- $$= GEOM_NEW(YYTHD,
+ $$= GEOM_NEW(thd,
Item_func_spatial_rel($3, $5,
Item_func::SP_CONTAINS_FUNC));
}
| GEOMETRYCOLLECTION '(' expr_list ')'
{
- $$= GEOM_NEW(YYTHD,
+ $$= GEOM_NEW(thd,
Item_func_spatial_collection(* $3,
Geometry::wkb_geometrycollection,
Geometry::wkb_point));
}
| LINESTRING '(' expr_list ')'
{
- $$= GEOM_NEW(YYTHD,
+ $$= GEOM_NEW(thd,
Item_func_spatial_collection(* $3,
Geometry::wkb_linestring,
Geometry::wkb_point));
}
| MULTILINESTRING '(' expr_list ')'
{
- $$= GEOM_NEW(YYTHD,
+ $$= GEOM_NEW(thd,
Item_func_spatial_collection(* $3,
Geometry::wkb_multilinestring,
Geometry::wkb_linestring));
}
| MULTIPOINT '(' expr_list ')'
{
- $$= GEOM_NEW(YYTHD,
+ $$= GEOM_NEW(thd,
Item_func_spatial_collection(* $3,
Geometry::wkb_multipoint,
Geometry::wkb_point));
}
| MULTIPOLYGON '(' expr_list ')'
{
- $$= GEOM_NEW(YYTHD,
+ $$= GEOM_NEW(thd,
Item_func_spatial_collection(* $3,
Geometry::wkb_multipolygon,
Geometry::wkb_polygon));
}
| POINT_SYM '(' expr ',' expr ')'
{
- $$= GEOM_NEW(YYTHD, Item_func_point($3,$5));
+ $$= GEOM_NEW(thd, Item_func_point($3,$5));
}
| POLYGON '(' expr_list ')'
{
- $$= GEOM_NEW(YYTHD,
+ $$= GEOM_NEW(thd,
Item_func_spatial_collection(* $3,
Geometry::wkb_polygon,
Geometry::wkb_linestring));
@@ -9275,7 +9226,6 @@ function_call_generic:
}
opt_udf_expr_list ')'
{
- THD *thd= YYTHD;
Create_func *builder;
Item *item= NULL;
@@ -9329,7 +9279,6 @@ function_call_generic:
}
| ident '.' ident '(' opt_expr_list ')'
{
- THD *thd= YYTHD;
Create_qfunc *builder;
Item *item= NULL;
@@ -9393,7 +9342,7 @@ opt_udf_expr_list:
udf_expr_list:
udf_expr
{
- $$= new (YYTHD->mem_root) List<Item>;
+ $$= new (thd->mem_root) List<Item>;
if ($$ == NULL)
MYSQL_YYABORT;
$$->push_back($1);
@@ -9426,7 +9375,7 @@ udf_expr:
remember_name we may get quoted or escaped names.
*/
else if ($2->type() != Item::FIELD_ITEM)
- $2->set_name($1, (uint) ($3 - $1), YYTHD->charset());
+ $2->set_name($1, (uint) ($3 - $1), thd->charset());
$$= $2;
}
;
@@ -9434,46 +9383,46 @@ udf_expr:
sum_expr:
AVG_SYM '(' in_sum_expr ')'
{
- $$= new (YYTHD->mem_root) Item_sum_avg($3, FALSE);
+ $$= new (thd->mem_root) Item_sum_avg($3, FALSE);
if ($$ == NULL)
MYSQL_YYABORT;
}
| AVG_SYM '(' DISTINCT in_sum_expr ')'
{
- $$= new (YYTHD->mem_root) Item_sum_avg($4, TRUE);
+ $$= new (thd->mem_root) Item_sum_avg($4, TRUE);
if ($$ == NULL)
MYSQL_YYABORT;
}
| BIT_AND '(' in_sum_expr ')'
{
- $$= new (YYTHD->mem_root) Item_sum_and($3);
+ $$= new (thd->mem_root) Item_sum_and($3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| BIT_OR '(' in_sum_expr ')'
{
- $$= new (YYTHD->mem_root) Item_sum_or($3);
+ $$= new (thd->mem_root) Item_sum_or($3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| BIT_XOR '(' in_sum_expr ')'
{
- $$= new (YYTHD->mem_root) Item_sum_xor($3);
+ $$= new (thd->mem_root) Item_sum_xor($3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| COUNT_SYM '(' opt_all '*' ')'
{
- Item *item= new (YYTHD->mem_root) Item_int((int32) 0L,1);
+ Item *item= new (thd->mem_root) Item_int((int32) 0L,1);
if (item == NULL)
MYSQL_YYABORT;
- $$= new (YYTHD->mem_root) Item_sum_count(item);
+ $$= new (thd->mem_root) Item_sum_count(item);
if ($$ == NULL)
MYSQL_YYABORT;
}
| COUNT_SYM '(' in_sum_expr ')'
{
- $$= new (YYTHD->mem_root) Item_sum_count($3);
+ $$= new (thd->mem_root) Item_sum_count($3);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -9483,13 +9432,13 @@ sum_expr:
{ Select->in_sum_expr--; }
')'
{
- $$= new (YYTHD->mem_root) Item_sum_count(* $5);
+ $$= new (thd->mem_root) Item_sum_count(* $5);
if ($$ == NULL)
MYSQL_YYABORT;
}
| MIN_SYM '(' in_sum_expr ')'
{
- $$= new (YYTHD->mem_root) Item_sum_min($3);
+ $$= new (thd->mem_root) Item_sum_min($3);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -9500,55 +9449,55 @@ sum_expr:
*/
| MIN_SYM '(' DISTINCT in_sum_expr ')'
{
- $$= new (YYTHD->mem_root) Item_sum_min($4);
+ $$= new (thd->mem_root) Item_sum_min($4);
if ($$ == NULL)
MYSQL_YYABORT;
}
| MAX_SYM '(' in_sum_expr ')'
{
- $$= new (YYTHD->mem_root) Item_sum_max($3);
+ $$= new (thd->mem_root) Item_sum_max($3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| MAX_SYM '(' DISTINCT in_sum_expr ')'
{
- $$= new (YYTHD->mem_root) Item_sum_max($4);
+ $$= new (thd->mem_root) Item_sum_max($4);
if ($$ == NULL)
MYSQL_YYABORT;
}
| STD_SYM '(' in_sum_expr ')'
{
- $$= new (YYTHD->mem_root) Item_sum_std($3, 0);
+ $$= new (thd->mem_root) Item_sum_std($3, 0);
if ($$ == NULL)
MYSQL_YYABORT;
}
| VARIANCE_SYM '(' in_sum_expr ')'
{
- $$= new (YYTHD->mem_root) Item_sum_variance($3, 0);
+ $$= new (thd->mem_root) Item_sum_variance($3, 0);
if ($$ == NULL)
MYSQL_YYABORT;
}
| STDDEV_SAMP_SYM '(' in_sum_expr ')'
{
- $$= new (YYTHD->mem_root) Item_sum_std($3, 1);
+ $$= new (thd->mem_root) Item_sum_std($3, 1);
if ($$ == NULL)
MYSQL_YYABORT;
}
| VAR_SAMP_SYM '(' in_sum_expr ')'
{
- $$= new (YYTHD->mem_root) Item_sum_variance($3, 1);
+ $$= new (thd->mem_root) Item_sum_variance($3, 1);
if ($$ == NULL)
MYSQL_YYABORT;
}
| SUM_SYM '(' in_sum_expr ')'
{
- $$= new (YYTHD->mem_root) Item_sum_sum($3, FALSE);
+ $$= new (thd->mem_root) Item_sum_sum($3, FALSE);
if ($$ == NULL)
MYSQL_YYABORT;
}
| SUM_SYM '(' DISTINCT in_sum_expr ')'
{
- $$= new (YYTHD->mem_root) Item_sum_sum($4, TRUE);
+ $$= new (thd->mem_root) Item_sum_sum($4, TRUE);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -9560,7 +9509,7 @@ sum_expr:
{
SELECT_LEX *sel= Select;
sel->in_sum_expr--;
- $$= new (YYTHD->mem_root)
+ $$= new (thd->mem_root)
Item_func_group_concat(Lex->current_context(), $3, $5,
sel->gorder_list, $7);
if ($$ == NULL)
@@ -9589,7 +9538,7 @@ variable_aux:
ident_or_text SET_VAR expr
{
Item_func_set_user_var *item;
- $$= item= new (YYTHD->mem_root) Item_func_set_user_var($1, $3);
+ $$= item= new (thd->mem_root) Item_func_set_user_var($1, $3);
if ($$ == NULL)
MYSQL_YYABORT;
LEX *lex= Lex;
@@ -9598,7 +9547,7 @@ variable_aux:
}
| ident_or_text
{
- $$= new (YYTHD->mem_root) Item_func_get_user_var($1);
+ $$= new (thd->mem_root) Item_func_get_user_var($1);
if ($$ == NULL)
MYSQL_YYABORT;
LEX *lex= Lex;
@@ -9612,7 +9561,7 @@ variable_aux:
my_parse_error(ER(ER_SYNTAX_ERROR));
MYSQL_YYABORT;
}
- if (!($$= get_system_var(YYTHD, $2, $3, $4)))
+ if (!($$= get_system_var(thd, $2, $3, $4)))
MYSQL_YYABORT;
if (!((Item_func_get_system_var*) $$)->is_written_to_binlog())
Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_VARIABLE);
@@ -9627,7 +9576,7 @@ opt_distinct:
opt_gconcat_separator:
/* empty */
{
- $$= new (YYTHD->mem_root) String(",", 1, &my_charset_latin1);
+ $$= new (thd->mem_root) String(",", 1, &my_charset_latin1);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -9654,9 +9603,9 @@ opt_gorder_clause:
gorder_list:
gorder_list ',' order_ident order_dir
- { if (add_gorder_to_list(YYTHD, $3,(bool) $4)) MYSQL_YYABORT; }
+ { if (add_gorder_to_list(thd, $3,(bool) $4)) MYSQL_YYABORT; }
| order_ident order_dir
- { if (add_gorder_to_list(YYTHD, $1,(bool) $2)) MYSQL_YYABORT; }
+ { if (add_gorder_to_list(thd, $1,(bool) $2)) MYSQL_YYABORT; }
;
in_sum_expr:
@@ -9722,7 +9671,7 @@ opt_expr_list:
expr_list:
expr
{
- $$= new (YYTHD->mem_root) List<Item>;
+ $$= new (thd->mem_root) List<Item>;
if ($$ == NULL)
MYSQL_YYABORT;
$$->push_back($1);
@@ -9742,7 +9691,7 @@ ident_list_arg:
ident_list:
simple_ident
{
- $$= new (YYTHD->mem_root) List<Item>;
+ $$= new (thd->mem_root) List<Item>;
if ($$ == NULL)
MYSQL_YYABORT;
$$->push_back($1);
@@ -9843,7 +9792,7 @@ join_table:
{
MYSQL_YYABORT_UNLESS($1 && $3);
/* Change the current name resolution context to a local context. */
- if (push_new_name_resolution_context(YYTHD, $1, $3))
+ if (push_new_name_resolution_context(thd, $1, $3))
MYSQL_YYABORT;
Select->parsing_place= IN_ON;
}
@@ -9878,7 +9827,7 @@ join_table:
{
MYSQL_YYABORT_UNLESS($1 && $5);
/* Change the current name resolution context to a local context. */
- if (push_new_name_resolution_context(YYTHD, $1, $5))
+ if (push_new_name_resolution_context(thd, $1, $5))
MYSQL_YYABORT;
Select->parsing_place= IN_ON;
}
@@ -9914,7 +9863,7 @@ join_table:
{
MYSQL_YYABORT_UNLESS($1 && $5);
/* Change the current name resolution context to a local context. */
- if (push_new_name_resolution_context(YYTHD, $1, $5))
+ if (push_new_name_resolution_context(thd, $1, $5))
MYSQL_YYABORT;
Select->parsing_place= IN_ON;
}
@@ -9975,7 +9924,7 @@ table_factor:
}
table_ident opt_table_alias opt_key_definition
{
- if (!($$= Select->add_table_to_list(YYTHD, $2, $3,
+ if (!($$= Select->add_table_to_list(thd, $2, $3,
Select->get_table_join_options(),
YYPS->m_lock_type,
YYPS->m_mdl_type,
@@ -10254,7 +10203,7 @@ opt_outer:
index_hint_clause:
/* empty */
{
- $$= YYTHD->variables.old_mode ? INDEX_HINT_MASK_JOIN : INDEX_HINT_MASK_ALL;
+ $$= thd->variables.old_mode ? INDEX_HINT_MASK_JOIN : INDEX_HINT_MASK_ALL;
}
| FOR_SYM JOIN_SYM { $$= INDEX_HINT_MASK_JOIN; }
| FOR_SYM ORDER_SYM BY { $$= INDEX_HINT_MASK_ORDER; }
@@ -10286,7 +10235,7 @@ index_hints_list:
opt_index_hints_list:
/* empty */
- | { Select->alloc_index_hints(YYTHD); } index_hints_list
+ | { Select->alloc_index_hints(thd); } index_hints_list
;
opt_key_definition:
@@ -10295,15 +10244,15 @@ opt_key_definition:
;
opt_key_usage_list:
- /* empty */ { Select->add_index_hint(YYTHD, NULL, 0); }
+ /* empty */ { Select->add_index_hint(thd, NULL, 0); }
| key_usage_list {}
;
key_usage_element:
ident
- { Select->add_index_hint(YYTHD, $1.str, $1.length); }
+ { Select->add_index_hint(thd, $1.str, $1.length); }
| PRIMARY_SYM
- { Select->add_index_hint(YYTHD, (char *)"PRIMARY", 7); }
+ { Select->add_index_hint(thd, (char *)"PRIMARY", 7); }
;
key_usage_list:
@@ -10316,7 +10265,7 @@ using_list:
{
if (!($$= new List<String>))
MYSQL_YYABORT;
- String *s= new (YYTHD->mem_root) String((const char *) $1.str,
+ String *s= new (thd->mem_root) String((const char *) $1.str,
$1.length,
system_charset_info);
if (s == NULL)
@@ -10325,7 +10274,7 @@ using_list:
}
| using_list ',' ident
{
- String *s= new (YYTHD->mem_root) String((const char *) $3.str,
+ String *s= new (thd->mem_root) String((const char *) $3.str,
$3.length,
system_charset_info);
if (s == NULL)
@@ -10430,7 +10379,6 @@ opt_escape:
}
| /* empty */
{
- THD *thd= YYTHD;
Lex->escape_used= FALSE;
$$= ((thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) ?
new (thd->mem_root) Item_string("", 0, &my_charset_latin1) :
@@ -10451,9 +10399,9 @@ group_clause:
group_list:
group_list ',' order_ident order_dir
- { if (add_group_to_list(YYTHD, $3,(bool) $4)) MYSQL_YYABORT; }
+ { if (add_group_to_list(thd, $3,(bool) $4)) MYSQL_YYABORT; }
| order_ident order_dir
- { if (add_group_to_list(YYTHD, $1,(bool) $2)) MYSQL_YYABORT; }
+ { if (add_group_to_list(thd, $1,(bool) $2)) MYSQL_YYABORT; }
;
olap_opt:
@@ -10514,7 +10462,6 @@ alter_order_list:
alter_order_item:
simple_ident_nospvar order_dir
{
- THD *thd= YYTHD;
bool ascending= ($2 == 1) ? true : false;
if (add_order_to_list(thd, $1, ascending))
MYSQL_YYABORT;
@@ -10567,9 +10514,9 @@ order_clause:
order_list:
order_list ',' order_ident order_dir
- { if (add_order_to_list(YYTHD, $3,(bool) $4)) MYSQL_YYABORT; }
+ { if (add_order_to_list(thd, $3,(bool) $4)) MYSQL_YYABORT; }
| order_ident order_dir
- { if (add_order_to_list(YYTHD, $1,(bool) $2)) MYSQL_YYABORT; }
+ { if (add_order_to_list(thd, $1,(bool) $2)) MYSQL_YYABORT; }
;
order_dir:
@@ -10638,7 +10585,6 @@ limit_option:
ident
{
Item_splocal *splocal;
- THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= & thd->m_parser_state->m_lip;
sp_variable_t *spv;
@@ -10675,19 +10621,19 @@ limit_option:
}
| ULONGLONG_NUM
{
- $$= new (YYTHD->mem_root) Item_uint($1.str, $1.length);
+ $$= new (thd->mem_root) Item_uint($1.str, $1.length);
if ($$ == NULL)
MYSQL_YYABORT;
}
| LONG_NUM
{
- $$= new (YYTHD->mem_root) Item_uint($1.str, $1.length);
+ $$= new (thd->mem_root) Item_uint($1.str, $1.length);
if ($$ == NULL)
MYSQL_YYABORT;
}
| NUM
{
- $$= new (YYTHD->mem_root) Item_uint($1.str, $1.length);
+ $$= new (thd->mem_root) Item_uint($1.str, $1.length);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -10791,7 +10737,7 @@ procedure_clause:
lex->proc_list.elements=0;
lex->proc_list.first=0;
lex->proc_list.next= &lex->proc_list.first;
- Item_field *item= new (YYTHD->mem_root)
+ Item_field *item= new (thd->mem_root)
Item_field(&lex->current_select->context,
NULL, NULL, $2.str);
if (item == NULL)
@@ -10816,8 +10762,6 @@ procedure_list2:
procedure_item:
remember_name expr remember_end
{
- THD *thd= YYTHD;
-
if (add_proc_to_list(thd, $2))
MYSQL_YYABORT;
if (!$2->name)
@@ -10991,7 +10935,6 @@ drop:
}
| DROP FUNCTION_SYM opt_if_exists ident '.' ident
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
sp_name *spname;
if ($4.str && check_db_name(&$4))
@@ -11014,7 +10957,6 @@ drop:
}
| DROP FUNCTION_SYM opt_if_exists ident
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
LEX_STRING db= {0, 0};
sp_name *spname;
@@ -11099,7 +11041,7 @@ table_list:
table_name:
table_ident
{
- if (!Select->add_table_to_list(YYTHD, $1, NULL,
+ if (!Select->add_table_to_list(thd, $1, NULL,
TL_OPTION_UPDATING,
YYPS->m_lock_type,
YYPS->m_mdl_type))
@@ -11115,7 +11057,7 @@ table_alias_ref_list:
table_alias_ref:
table_ident_opt_wild
{
- if (!Select->add_table_to_list(YYTHD, $1, NULL,
+ if (!Select->add_table_to_list(thd, $1, NULL,
TL_OPTION_UPDATING | TL_OPTION_ALIAS,
YYPS->m_lock_type,
YYPS->m_mdl_type))
@@ -11193,7 +11135,7 @@ insert_lock_option:
| DELAYED_SYM
{
Lex->keyword_delayed_begin_offset= (uint)(YYLIP->get_tok_start() -
- YYTHD->query());
+ thd->query());
Lex->keyword_delayed_end_offset= Lex->keyword_delayed_begin_offset +
YYLIP->yyLength() + 1;
$$= TL_WRITE_DELAYED;
@@ -11206,7 +11148,7 @@ replace_lock_option:
| DELAYED_SYM
{
Lex->keyword_delayed_begin_offset= (uint)(YYLIP->get_tok_start() -
- YYTHD->query());
+ thd->query());
Lex->keyword_delayed_end_offset= Lex->keyword_delayed_begin_offset +
YYLIP->yyLength() + 1;
$$= TL_WRITE_DELAYED;
@@ -11323,7 +11265,7 @@ expr_or_default:
expr { $$= $1;}
| DEFAULT
{
- $$= new (YYTHD->mem_root) Item_default_value(Lex->current_context());
+ $$= new (thd->mem_root) Item_default_value(Lex->current_context());
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -11376,7 +11318,7 @@ update_list:
update_elem:
simple_ident_nospvar equal expr_or_default
{
- if (add_item_to_list(YYTHD, $1) || add_value_to_list(YYTHD, $3))
+ if (add_item_to_list(thd, $1) || add_value_to_list(thd, $3))
MYSQL_YYABORT;
}
;
@@ -11421,7 +11363,7 @@ delete:
single_multi:
FROM table_ident
{
- if (!Select->add_table_to_list(YYTHD, $2, NULL, TL_OPTION_UPDATING,
+ if (!Select->add_table_to_list(thd, $2, NULL, TL_OPTION_UPDATING,
YYPS->m_lock_type,
YYPS->m_mdl_type))
MYSQL_YYABORT;
@@ -11471,7 +11413,7 @@ table_wild_one:
Table_ident *ti= new Table_ident($1);
if (ti == NULL)
MYSQL_YYABORT;
- if (!Select->add_table_to_list(YYTHD,
+ if (!Select->add_table_to_list(thd,
ti,
NULL,
TL_OPTION_UPDATING | TL_OPTION_ALIAS,
@@ -11481,10 +11423,10 @@ table_wild_one:
}
| ident '.' ident opt_wild
{
- Table_ident *ti= new Table_ident(YYTHD, $1, $3, 0);
+ Table_ident *ti= new Table_ident(thd, $1, $3, 0);
if (ti == NULL)
MYSQL_YYABORT;
- if (!Select->add_table_to_list(YYTHD,
+ if (!Select->add_table_to_list(thd,
ti,
NULL,
TL_OPTION_UPDATING | TL_OPTION_ALIAS,
@@ -11524,7 +11466,6 @@ truncate:
}
table_name
{
- THD *thd= YYTHD;
LEX* lex= thd->lex;
DBUG_ASSERT(!lex->m_stmt);
lex->m_stmt= new (thd->mem_root) Truncate_statement(lex);
@@ -11619,7 +11560,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_DATABASES;
- if (prepare_schema_table(YYTHD, lex, 0, SCH_SCHEMATA))
+ if (prepare_schema_table(thd, lex, 0, SCH_SCHEMATA))
MYSQL_YYABORT;
}
| opt_full TABLES opt_db wild_and_where
@@ -11627,7 +11568,7 @@ show_param:
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_TABLES;
lex->select_lex.db= $3;
- if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLE_NAMES))
+ if (prepare_schema_table(thd, lex, 0, SCH_TABLE_NAMES))
MYSQL_YYABORT;
}
| opt_full TRIGGERS_SYM opt_db wild_and_where
@@ -11635,7 +11576,7 @@ show_param:
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_TRIGGERS;
lex->select_lex.db= $3;
- if (prepare_schema_table(YYTHD, lex, 0, SCH_TRIGGERS))
+ if (prepare_schema_table(thd, lex, 0, SCH_TRIGGERS))
MYSQL_YYABORT;
}
| EVENTS_SYM opt_db wild_and_where
@@ -11643,7 +11584,7 @@ show_param:
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_EVENTS;
lex->select_lex.db= $2;
- if (prepare_schema_table(YYTHD, lex, 0, SCH_EVENTS))
+ if (prepare_schema_table(thd, lex, 0, SCH_EVENTS))
MYSQL_YYABORT;
}
| TABLE_SYM STATUS_SYM opt_db wild_and_where
@@ -11651,7 +11592,7 @@ show_param:
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_TABLE_STATUS;
lex->select_lex.db= $3;
- if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLES))
+ if (prepare_schema_table(thd, lex, 0, SCH_TABLES))
MYSQL_YYABORT;
}
| OPEN_SYM TABLES opt_db wild_and_where
@@ -11659,27 +11600,27 @@ show_param:
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_OPEN_TABLES;
lex->select_lex.db= $3;
- if (prepare_schema_table(YYTHD, lex, 0, SCH_OPEN_TABLES))
+ if (prepare_schema_table(thd, lex, 0, SCH_OPEN_TABLES))
MYSQL_YYABORT;
}
| PLUGINS_SYM
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_PLUGINS;
- if (prepare_schema_table(YYTHD, lex, 0, SCH_PLUGINS))
+ if (prepare_schema_table(thd, lex, 0, SCH_PLUGINS))
MYSQL_YYABORT;
}
| PLUGINS_SYM SONAME_SYM TEXT_STRING_sys
{
Lex->ident= $3;
Lex->sql_command= SQLCOM_SHOW_PLUGINS;
- if (prepare_schema_table(YYTHD, Lex, 0, SCH_ALL_PLUGINS))
+ if (prepare_schema_table(thd, Lex, 0, SCH_ALL_PLUGINS))
MYSQL_YYABORT;
}
| PLUGINS_SYM SONAME_SYM wild_and_where
{
Lex->sql_command= SQLCOM_SHOW_PLUGINS;
- if (prepare_schema_table(YYTHD, Lex, 0, SCH_ALL_PLUGINS))
+ if (prepare_schema_table(thd, Lex, 0, SCH_ALL_PLUGINS))
MYSQL_YYABORT;
}
| ENGINE_SYM known_storage_engines show_engine_param
@@ -11692,7 +11633,7 @@ show_param:
lex->sql_command= SQLCOM_SHOW_FIELDS;
if ($5)
$4->change_db($5);
- if (prepare_schema_table(YYTHD, lex, $4, SCH_COLUMNS))
+ if (prepare_schema_table(thd, lex, $4, SCH_COLUMNS))
MYSQL_YYABORT;
}
| master_or_binary LOGS_SYM
@@ -11719,21 +11660,21 @@ show_param:
lex->sql_command= SQLCOM_SHOW_KEYS;
if ($4)
$3->change_db($4);
- if (prepare_schema_table(YYTHD, lex, $3, SCH_STATISTICS))
+ if (prepare_schema_table(thd, lex, $3, SCH_STATISTICS))
MYSQL_YYABORT;
}
| opt_storage ENGINES_SYM
{
LEX *lex=Lex;
lex->sql_command= SQLCOM_SHOW_STORAGE_ENGINES;
- if (prepare_schema_table(YYTHD, lex, 0, SCH_ENGINES))
+ if (prepare_schema_table(thd, lex, 0, SCH_ENGINES))
MYSQL_YYABORT;
}
| AUTHORS_SYM
{
LEX *lex=Lex;
lex->sql_command= SQLCOM_SHOW_AUTHORS;
- push_warning_printf(YYTHD, MYSQL_ERROR::WARN_LEVEL_WARN,
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT,
ER(ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT),
"SHOW AUTHORS");
@@ -11742,7 +11683,7 @@ show_param:
{
LEX *lex=Lex;
lex->sql_command= SQLCOM_SHOW_CONTRIBUTORS;
- push_warning_printf(YYTHD, MYSQL_ERROR::WARN_LEVEL_WARN,
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT,
ER(ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT),
"SHOW CONTRIBUTORS");
@@ -11766,7 +11707,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_PROFILE;
- if (prepare_schema_table(YYTHD, lex, NULL, SCH_PROFILES) != 0)
+ if (prepare_schema_table(thd, lex, NULL, SCH_PROFILES) != 0)
YYABORT;
}
| opt_var_type STATUS_SYM wild_and_where
@@ -11774,7 +11715,7 @@ show_param:
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_STATUS;
lex->option_type= $1;
- if (prepare_schema_table(YYTHD, lex, 0, SCH_STATUS))
+ if (prepare_schema_table(thd, lex, 0, SCH_STATUS))
MYSQL_YYABORT;
}
| opt_full PROCESSLIST_SYM
@@ -11784,21 +11725,21 @@ show_param:
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_VARIABLES;
lex->option_type= $1;
- if (prepare_schema_table(YYTHD, lex, 0, SCH_VARIABLES))
+ if (prepare_schema_table(thd, lex, 0, SCH_VARIABLES))
MYSQL_YYABORT;
}
| charset wild_and_where
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_CHARSETS;
- if (prepare_schema_table(YYTHD, lex, 0, SCH_CHARSETS))
+ if (prepare_schema_table(thd, lex, 0, SCH_CHARSETS))
MYSQL_YYABORT;
}
| COLLATION_SYM wild_and_where
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_COLLATIONS;
- if (prepare_schema_table(YYTHD, lex, 0, SCH_COLLATIONS))
+ if (prepare_schema_table(thd, lex, 0, SCH_COLLATIONS))
MYSQL_YYABORT;
}
| GRANTS
@@ -11828,7 +11769,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command = SQLCOM_SHOW_CREATE;
- if (!lex->select_lex.add_table_to_list(YYTHD, $3, NULL,0))
+ if (!lex->select_lex.add_table_to_list(thd, $3, NULL,0))
MYSQL_YYABORT;
lex->only_view= 0;
lex->create_info.storage_media= HA_SM_DEFAULT;
@@ -11837,7 +11778,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command = SQLCOM_SHOW_CREATE;
- if (!lex->select_lex.add_table_to_list(YYTHD, $3, NULL, 0))
+ if (!lex->select_lex.add_table_to_list(thd, $3, NULL, 0))
MYSQL_YYABORT;
lex->only_view= 1;
}
@@ -11852,7 +11793,6 @@ show_param:
}
| SLAVE STATUS_SYM
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
lex->mi.connection_name= thd->variables.default_master_connection;
lex->sql_command = SQLCOM_SHOW_SLAVE_STAT;
@@ -11867,28 +11807,28 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_CLIENT_STATS;
- if (prepare_schema_table(YYTHD, lex, 0, SCH_CLIENT_STATS))
+ if (prepare_schema_table(thd, lex, 0, SCH_CLIENT_STATS))
MYSQL_YYABORT;
}
| USER_STATS_SYM
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_USER_STATS;
- if (prepare_schema_table(YYTHD, lex, 0, SCH_USER_STATS))
+ if (prepare_schema_table(thd, lex, 0, SCH_USER_STATS))
MYSQL_YYABORT;
}
| TABLE_STATS_SYM
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_TABLE_STATS;
- if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLE_STATS))
+ if (prepare_schema_table(thd, lex, 0, SCH_TABLE_STATS))
MYSQL_YYABORT;
}
| INDEX_STATS_SYM
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_INDEX_STATS;
- if (prepare_schema_table(YYTHD, lex, 0, SCH_INDEX_STATS))
+ if (prepare_schema_table(thd, lex, 0, SCH_INDEX_STATS))
MYSQL_YYABORT;
}
| CREATE PROCEDURE_SYM sp_name
@@ -11915,14 +11855,14 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_STATUS_PROC;
- if (prepare_schema_table(YYTHD, lex, 0, SCH_PROCEDURES))
+ if (prepare_schema_table(thd, lex, 0, SCH_PROCEDURES))
MYSQL_YYABORT;
}
| FUNCTION_SYM STATUS_SYM wild_and_where
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_STATUS_FUNC;
- if (prepare_schema_table(YYTHD, lex, 0, SCH_PROCEDURES))
+ if (prepare_schema_table(thd, lex, 0, SCH_PROCEDURES))
MYSQL_YYABORT;
}
| PROCEDURE_SYM CODE_SYM sp_name
@@ -11942,7 +11882,6 @@ show_param:
}
| describe_command FOR_SYM expr
{
- THD *thd= YYTHD;
Lex->sql_command= SQLCOM_SHOW_EXPLAIN;
if (prepare_schema_table(thd, Lex, 0, SCH_EXPLAIN))
MYSQL_YYABORT;
@@ -11998,7 +11937,7 @@ wild_and_where:
/* empty */
| LIKE TEXT_STRING_sys
{
- Lex->wild= new (YYTHD->mem_root) String($2.str, $2.length,
+ Lex->wild= new (thd->mem_root) String($2.str, $2.length,
system_charset_info);
if (Lex->wild == NULL)
MYSQL_YYABORT;
@@ -12021,7 +11960,7 @@ describe:
lex->sql_command= SQLCOM_SHOW_FIELDS;
lex->select_lex.db= 0;
lex->verbose= 0;
- if (prepare_schema_table(YYTHD, lex, $2, SCH_COLUMNS))
+ if (prepare_schema_table(thd, lex, $2, SCH_COLUMNS))
MYSQL_YYABORT;
}
opt_describe_column
@@ -12053,7 +11992,7 @@ opt_describe_column:
| text_string { Lex->wild= $1; }
| ident
{
- Lex->wild= new (YYTHD->mem_root) String((const char*) $1.str,
+ Lex->wild= new (thd->mem_root) String((const char*) $1.str,
$1.length,
system_charset_info);
if (Lex->wild == NULL)
@@ -12308,7 +12247,6 @@ use:
load:
LOAD data_or_xml
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
if (lex->sphead)
@@ -12331,7 +12269,7 @@ load:
opt_duplicate INTO TABLE_SYM table_ident
{
LEX *lex=Lex;
- if (!Select->add_table_to_list(YYTHD, $12, NULL, TL_OPTION_UPDATING,
+ if (!Select->add_table_to_list(thd, $12, NULL, TL_OPTION_UPDATING,
$4, MDL_SHARED_WRITE))
MYSQL_YYABORT;
lex->field_list.empty();
@@ -12470,7 +12408,7 @@ field_or_var:
simple_ident_nospvar {$$= $1;}
| '@' ident_or_text
{
- $$= new (YYTHD->mem_root) Item_user_var_as_out_param($2);
+ $$= new (thd->mem_root) Item_user_var_as_out_param($2);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -12493,7 +12431,7 @@ load_data_set_elem:
if (lex->update_list.push_back($1) ||
lex->value_list.push_back($4))
MYSQL_YYABORT;
- $4->set_name_no_truncate($3, (uint) ($5 - $3), YYTHD->charset());
+ $4->set_name_no_truncate($3, (uint) ($5 - $3), thd->charset());
}
;
@@ -12503,7 +12441,6 @@ text_literal:
TEXT_STRING
{
LEX_STRING tmp;
- THD *thd= YYTHD;
CHARSET_INFO *cs_con= thd->variables.collation_connection;
CHARSET_INFO *cs_cli= thd->variables.character_set_client;
uint repertoire= thd->lex->text_string_is_7bit &&
@@ -12529,7 +12466,7 @@ text_literal:
uint repertoire= Lex->text_string_is_7bit ?
MY_REPERTOIRE_ASCII : MY_REPERTOIRE_UNICODE30;
DBUG_ASSERT(my_charset_is_ascii_based(national_charset_info));
- $$= new (YYTHD->mem_root) Item_string($1.str, $1.length,
+ $$= new (thd->mem_root) Item_string($1.str, $1.length,
national_charset_info,
DERIVATION_COERCIBLE,
repertoire);
@@ -12538,7 +12475,7 @@ text_literal:
}
| UNDERSCORE_CHARSET TEXT_STRING
{
- Item_string *str= new (YYTHD->mem_root) Item_string($2.str,
+ Item_string *str= new (thd->mem_root) Item_string($2.str,
$2.length, $1);
if (str == NULL)
MYSQL_YYABORT;
@@ -12557,7 +12494,7 @@ text_literal:
If the string has been pure ASCII so far,
check the new part.
*/
- CHARSET_INFO *cs= YYTHD->variables.collation_connection;
+ CHARSET_INFO *cs= thd->variables.collation_connection;
item->collation.repertoire|= my_string_repertoire(cs,
$2.str,
$2.length);
@@ -12568,15 +12505,15 @@ text_literal:
text_string:
TEXT_STRING_literal
{
- $$= new (YYTHD->mem_root) String($1.str,
+ $$= new (thd->mem_root) String($1.str,
$1.length,
- YYTHD->variables.collation_connection);
+ thd->variables.collation_connection);
if ($$ == NULL)
MYSQL_YYABORT;
}
| HEX_NUM
{
- Item *tmp= new (YYTHD->mem_root) Item_hex_hybrid($1.str, $1.length);
+ Item *tmp= new (thd->mem_root) Item_hex_hybrid($1.str, $1.length);
if (tmp == NULL)
MYSQL_YYABORT;
/*
@@ -12588,7 +12525,7 @@ text_string:
}
| HEX_STRING
{
- Item *tmp= new (YYTHD->mem_root) Item_hex_string($1.str, $1.length);
+ Item *tmp= new (thd->mem_root) Item_hex_string($1.str, $1.length);
if (tmp == NULL)
MYSQL_YYABORT;
tmp->quick_fix_field();
@@ -12596,7 +12533,7 @@ text_string:
}
| BIN_NUM
{
- Item *tmp= new (YYTHD->mem_root) Item_bin_string($1.str, $1.length);
+ Item *tmp= new (thd->mem_root) Item_bin_string($1.str, $1.length);
if (tmp == NULL)
MYSQL_YYABORT;
/*
@@ -12611,7 +12548,6 @@ text_string:
param_marker:
PARAM_MARKER
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= YYLIP;
Item_param *item;
@@ -12644,44 +12580,44 @@ literal:
| NUM_literal { $$ = $1; }
| NULL_SYM
{
- $$ = new (YYTHD->mem_root) Item_null();
+ $$ = new (thd->mem_root) Item_null();
if ($$ == NULL)
MYSQL_YYABORT;
YYLIP->next_state= MY_LEX_OPERATOR_OR_IDENT;
}
| FALSE_SYM
{
- $$= new (YYTHD->mem_root) Item_int((char*) "FALSE",0,1);
+ $$= new (thd->mem_root) Item_int((char*) "FALSE",0,1);
if ($$ == NULL)
MYSQL_YYABORT;
}
| TRUE_SYM
{
- $$= new (YYTHD->mem_root) Item_int((char*) "TRUE",1,1);
+ $$= new (thd->mem_root) Item_int((char*) "TRUE",1,1);
if ($$ == NULL)
MYSQL_YYABORT;
}
| HEX_NUM
{
- $$ = new (YYTHD->mem_root) Item_hex_hybrid($1.str, $1.length);
+ $$ = new (thd->mem_root) Item_hex_hybrid($1.str, $1.length);
if ($$ == NULL)
MYSQL_YYABORT;
}
| HEX_STRING
{
- $$ = new (YYTHD->mem_root) Item_hex_string($1.str, $1.length);
+ $$ = new (thd->mem_root) Item_hex_string($1.str, $1.length);
if ($$ == NULL)
MYSQL_YYABORT;
}
| BIN_NUM
{
- $$= new (YYTHD->mem_root) Item_bin_string($1.str, $1.length);
+ $$= new (thd->mem_root) Item_bin_string($1.str, $1.length);
if ($$ == NULL)
MYSQL_YYABORT;
}
| UNDERSCORE_CHARSET hex_num_or_string
{
- Item *tmp= new (YYTHD->mem_root) Item_hex_string($2.str, $2.length);
+ Item *tmp= new (thd->mem_root) Item_hex_string($2.str, $2.length);
if (tmp == NULL)
MYSQL_YYABORT;
/*
@@ -12692,7 +12628,7 @@ literal:
String *str= tmp->val_str((String*) 0);
Item_string *item_str;
- item_str= new (YYTHD->mem_root)
+ item_str= new (thd->mem_root)
Item_string(NULL, /* name will be set in select_item */
str ? str->ptr() : "",
str ? str->length() : 0,
@@ -12710,7 +12646,7 @@ literal:
}
| UNDERSCORE_CHARSET BIN_NUM
{
- Item *tmp= new (YYTHD->mem_root) Item_bin_string($2.str, $2.length);
+ Item *tmp= new (thd->mem_root) Item_bin_string($2.str, $2.length);
if (tmp == NULL)
MYSQL_YYABORT;
/*
@@ -12721,7 +12657,7 @@ literal:
String *str= tmp->val_str((String*) 0);
Item_string *item_str;
- item_str= new (YYTHD->mem_root)
+ item_str= new (thd->mem_root)
Item_string(NULL, /* name will be set in select_item */
str ? str->ptr() : "",
str ? str->length() : 0,
@@ -12745,7 +12681,7 @@ NUM_literal:
NUM
{
int error;
- $$= new (YYTHD->mem_root)
+ $$= new (thd->mem_root)
Item_int($1.str,
(longlong) my_strtoll10($1.str, NULL, &error),
$1.length);
@@ -12755,7 +12691,7 @@ NUM_literal:
| LONG_NUM
{
int error;
- $$= new (YYTHD->mem_root)
+ $$= new (thd->mem_root)
Item_int($1.str,
(longlong) my_strtoll10($1.str, NULL, &error),
$1.length);
@@ -12764,23 +12700,23 @@ NUM_literal:
}
| ULONGLONG_NUM
{
- $$= new (YYTHD->mem_root) Item_uint($1.str, $1.length);
+ $$= new (thd->mem_root) Item_uint($1.str, $1.length);
if ($$ == NULL)
MYSQL_YYABORT;
}
| DECIMAL_NUM
{
- $$= new (YYTHD->mem_root) Item_decimal($1.str, $1.length,
- YYTHD->charset());
- if (($$ == NULL) || (YYTHD->is_error()))
+ $$= new (thd->mem_root) Item_decimal($1.str, $1.length,
+ thd->charset());
+ if (($$ == NULL) || (thd->is_error()))
{
MYSQL_YYABORT;
}
}
| FLOAT_NUM
{
- $$= new (YYTHD->mem_root) Item_float($1.str, $1.length);
- if (($$ == NULL) || (YYTHD->is_error()))
+ $$= new (thd->mem_root) Item_float($1.str, $1.length);
+ if (($$ == NULL) || (thd->is_error()))
{
MYSQL_YYABORT;
}
@@ -12800,7 +12736,7 @@ table_wild:
ident '.' '*'
{
SELECT_LEX *sel= Select;
- $$= new (YYTHD->mem_root) Item_field(Lex->current_context(),
+ $$= new (thd->mem_root) Item_field(Lex->current_context(),
NullS, $1.str, "*");
if ($$ == NULL)
MYSQL_YYABORT;
@@ -12808,7 +12744,6 @@ table_wild:
}
| ident '.' ident '.' '*'
{
- THD *thd= YYTHD;
SELECT_LEX *sel= Select;
const char* schema= thd->client_capabilities & CLIENT_NO_SCHEMA ?
NullS : $1.str;
@@ -12828,7 +12763,6 @@ order_ident:
simple_ident:
ident
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= YYLIP;
sp_variable_t *spv;
@@ -12879,7 +12813,6 @@ simple_ident:
simple_ident_nospvar:
ident
{
- THD *thd= YYTHD;
SELECT_LEX *sel=Select;
if ((sel->parsing_place != IN_HAVING) ||
(sel->get_in_sum_expr() > 0))
@@ -12901,7 +12834,6 @@ simple_ident_nospvar:
simple_ident_q:
ident '.' ident
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
/*
@@ -12980,7 +12912,6 @@ simple_ident_q:
}
| '.' ident '.' ident
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
SELECT_LEX *sel= lex->current_select;
if (sel->no_table_names_allowed)
@@ -13005,7 +12936,6 @@ simple_ident_q:
}
| ident '.' ident '.' ident
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
SELECT_LEX *sel= lex->current_select;
const char* schema= (thd->client_capabilities & CLIENT_NO_SCHEMA ?
@@ -13073,7 +13003,7 @@ table_ident:
}
| ident '.' ident
{
- $$= new Table_ident(YYTHD, $1,$3,0);
+ $$= new Table_ident(thd, $1,$3,0);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -13095,7 +13025,7 @@ table_ident_opt_wild:
}
| ident '.' ident opt_wild
{
- $$= new Table_ident(YYTHD, $1,$3,0);
+ $$= new Table_ident(thd, $1,$3,0);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -13105,7 +13035,7 @@ table_ident_nodb:
ident
{
LEX_STRING db={(char*) any_db,3};
- $$= new Table_ident(YYTHD, db,$1,0);
+ $$= new Table_ident(thd, db,$1,0);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -13115,8 +13045,6 @@ IDENT_sys:
IDENT { $$= $1; }
| IDENT_QUOTED
{
- THD *thd= YYTHD;
-
if (thd->charset_is_system_charset)
{
CHARSET_INFO *cs= system_charset_info;
@@ -13145,8 +13073,6 @@ IDENT_sys:
TEXT_STRING_sys:
TEXT_STRING
{
- THD *thd= YYTHD;
-
if (thd->charset_is_system_charset)
$$= $1;
else
@@ -13161,8 +13087,6 @@ TEXT_STRING_sys:
TEXT_STRING_literal:
TEXT_STRING
{
- THD *thd= YYTHD;
-
if (thd->charset_is_collation_connection)
$$= $1;
else
@@ -13177,8 +13101,6 @@ TEXT_STRING_literal:
TEXT_STRING_filesystem:
TEXT_STRING
{
- THD *thd= YYTHD;
-
if (thd->charset_is_character_set_filesystem)
$$= $1;
else
@@ -13195,7 +13117,6 @@ ident:
IDENT_sys { $$=$1; }
| keyword
{
- THD *thd= YYTHD;
$$.str= thd->strmake($1.str, $1.length);
if ($$.str == NULL)
MYSQL_YYABORT;
@@ -13207,7 +13128,6 @@ label_ident:
IDENT_sys { $$=$1; }
| keyword_sp
{
- THD *thd= YYTHD;
$$.str= thd->strmake($1.str, $1.length);
if ($$.str == NULL)
MYSQL_YYABORT;
@@ -13224,7 +13144,6 @@ ident_or_text:
user:
ident_or_text
{
- THD *thd= YYTHD;
if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
MYSQL_YYABORT;
$$->user = $1;
@@ -13241,7 +13160,6 @@ user:
}
| ident_or_text '@' ident_or_text
{
- THD *thd= YYTHD;
if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
MYSQL_YYABORT;
$$->user = $1; $$->host=$3;
@@ -13263,7 +13181,7 @@ user:
}
| CURRENT_USER optional_braces
{
- if (!($$=(LEX_USER*) YYTHD->alloc(sizeof(st_lex_user))))
+ if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
MYSQL_YYABORT;
/*
empty LEX_USER means current_user and
@@ -13673,7 +13591,6 @@ option_value_list:
option_type_value:
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= YYLIP;
@@ -13704,7 +13621,6 @@ option_type_value:
}
ext_option_value
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= YYLIP;
@@ -13787,7 +13703,6 @@ ext_option_value:
sys_option_value:
option_type internal_variable_name equal set_expr_or_default
{
- THD *thd= YYTHD;
LEX *lex= Lex;
LEX_STRING *name= &$2.base_name;
@@ -13799,7 +13714,7 @@ sys_option_value:
my_parse_error(ER(ER_SYNTAX_ERROR));
MYSQL_YYABORT;
}
- if (set_trigger_new_row(YYTHD, name, $4))
+ if (set_trigger_new_row(thd, name, $4))
MYSQL_YYABORT;
}
else if ($2.var)
@@ -13829,7 +13744,6 @@ sys_option_value:
}
| option_type TRANSACTION_SYM ISOLATION LEVEL_SYM isolation_types
{
- THD *thd= YYTHD;
LEX *lex=Lex;
lex->option_type= $1;
Item *item= new (thd->mem_root) Item_int((int32) $5);
@@ -13849,7 +13763,7 @@ option_value:
'@' ident_or_text equal expr
{
Item_func_set_user_var *item;
- item= new (YYTHD->mem_root) Item_func_set_user_var($2, $4);
+ item= new (thd->mem_root) Item_func_set_user_var($2, $4);
if (item == NULL)
MYSQL_YYABORT;
set_var_user *var= new set_var_user(item);
@@ -13859,7 +13773,6 @@ option_value:
}
| '@' '@' opt_var_ident_type internal_variable_name equal set_expr_or_default
{
- THD *thd= YYTHD;
struct sys_var_with_base tmp= $4;
/* Lookup if necessary: must be a system variable. */
if (tmp.var == NULL)
@@ -13872,7 +13785,6 @@ option_value:
}
| charset old_or_new_charset_name_or_default
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
CHARSET_INFO *cs2;
cs2= $2 ? $2: global_system_variables.character_set_client;
@@ -13920,7 +13832,6 @@ option_value:
}
| PASSWORD equal text_or_password
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
LEX_USER *user;
sp_pcontext *spc= lex->spcont;
@@ -13960,7 +13871,6 @@ option_value:
internal_variable_name:
ident
{
- THD *thd= YYTHD;
sp_pcontext *spc= thd->lex->spcont;
sp_variable_t *spv;
@@ -14019,7 +13929,7 @@ internal_variable_name:
}
else
{
- sys_var *tmp=find_sys_var(YYTHD, $3.str, $3.length);
+ sys_var *tmp=find_sys_var(thd, $3.str, $3.length);
if (!tmp)
MYSQL_YYABORT;
if (!tmp->is_struct())
@@ -14030,7 +13940,7 @@ internal_variable_name:
}
| DEFAULT '.' ident
{
- sys_var *tmp=find_sys_var(YYTHD, $3.str, $3.length);
+ sys_var *tmp=find_sys_var(thd, $3.str, $3.length);
if (!tmp)
MYSQL_YYABORT;
if (!tmp->is_struct())
@@ -14052,16 +13962,16 @@ text_or_password:
TEXT_STRING { $$=$1.str;}
| PASSWORD '(' TEXT_STRING ')'
{
- $$= $3.length ? YYTHD->variables.old_passwords ?
- Item_func_old_password::alloc(YYTHD, $3.str, $3.length) :
- Item_func_password::alloc(YYTHD, $3.str, $3.length) :
+ $$= $3.length ? thd->variables.old_passwords ?
+ Item_func_old_password::alloc(thd, $3.str, $3.length) :
+ Item_func_password::alloc(thd, $3.str, $3.length) :
$3.str;
if ($$ == NULL)
MYSQL_YYABORT;
}
| OLD_PASSWORD '(' TEXT_STRING ')'
{
- $$= $3.length ? Item_func_old_password::alloc(YYTHD, $3.str,
+ $$= $3.length ? Item_func_old_password::alloc(thd, $3.str,
$3.length) :
$3.str;
if ($$ == NULL)
@@ -14075,19 +13985,19 @@ set_expr_or_default:
| DEFAULT { $$=0; }
| ON
{
- $$=new (YYTHD->mem_root) Item_string("ON", 2, system_charset_info);
+ $$=new (thd->mem_root) Item_string("ON", 2, system_charset_info);
if ($$ == NULL)
MYSQL_YYABORT;
}
| ALL
{
- $$=new (YYTHD->mem_root) Item_string("ALL", 3, system_charset_info);
+ $$=new (thd->mem_root) Item_string("ALL", 3, system_charset_info);
if ($$ == NULL)
MYSQL_YYABORT;
}
| BINARY
{
- $$=new (YYTHD->mem_root) Item_string("binary", 6, system_charset_info);
+ $$=new (thd->mem_root) Item_string("binary", 6, system_charset_info);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -14126,7 +14036,7 @@ table_lock:
{
thr_lock_type lock_type= (thr_lock_type) $3;
bool lock_for_write= (lock_type >= TL_WRITE_ALLOW_WRITE);
- if (!Select->add_table_to_list(YYTHD, $1, $2, 0, lock_type,
+ if (!Select->add_table_to_list(thd, $1, $2, 0, lock_type,
(lock_for_write ?
lock_type == TL_WRITE_CONCURRENT_INSERT ?
MDL_SHARED_WRITE :
@@ -14204,7 +14114,7 @@ handler:
lex->expr_allows_subselect= FALSE;
lex->sql_command = SQLCOM_HA_READ;
lex->ha_rkey_mode= HA_READ_KEY_EXACT; /* Avoid purify warnings */
- Item *one= new (YYTHD->mem_root) Item_int((int32) 1);
+ Item *one= new (thd->mem_root) Item_int((int32) 1);
if (one == NULL)
MYSQL_YYABORT;
lex->current_select->select_limit= one;
@@ -14552,10 +14462,10 @@ grant_user:
$$=$1; $1->password=$4;
if ($4.length)
{
- if (YYTHD->variables.old_passwords)
+ if (thd->variables.old_passwords)
{
char *buff=
- (char *) YYTHD->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH_323+1);
+ (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH_323+1);
if (buff == NULL)
MYSQL_YYABORT;
my_make_scrambled_password_323(buff, $4.str, $4.length);
@@ -14565,7 +14475,7 @@ grant_user:
else
{
char *buff=
- (char *) YYTHD->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH+1);
+ (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH+1);
if (buff == NULL)
MYSQL_YYABORT;
my_make_scrambled_password(buff, $4.str, $4.length);
@@ -14612,7 +14522,7 @@ column_list:
column_list_id:
ident
{
- String *new_str = new (YYTHD->mem_root) String((const char*) $1.str,$1.length,system_charset_info);
+ String *new_str = new (thd->mem_root) String((const char*) $1.str,$1.length,system_charset_info);
if (new_str == NULL)
MYSQL_YYABORT;
List_iterator <LEX_COLUMN> iter(Lex->columns);
@@ -14822,7 +14732,6 @@ opt_union_order_or_limit:
union_order_or_limit:
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
DBUG_ASSERT(lex->current_select->linkage != GLOBAL_OPTIONS_TYPE);
SELECT_LEX *sel= lex->current_select;
@@ -14838,7 +14747,6 @@ union_order_or_limit:
}
order_or_limit
{
- THD *thd= YYTHD;
thd->lex->current_select->no_table_names_allowed= 0;
thd->where= "";
}
@@ -15020,14 +14928,14 @@ no_definer:
from older master servers (i.e. to create non-suid trigger in this
case).
*/
- YYTHD->lex->definer= 0;
+ thd->lex->definer= 0;
}
;
definer:
DEFINER_SYM EQ user
{
- YYTHD->lex->definer= get_current_user(YYTHD, $3);
+ thd->lex->definer= get_current_user(thd, $3);
}
;
@@ -15072,7 +14980,6 @@ view_suid:
view_tail:
view_suid VIEW_SYM table_ident
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
lex->sql_command= SQLCOM_CREATE_VIEW;
/* first table in list is target VIEW name */
@@ -15116,7 +15023,6 @@ view_select:
}
view_select_aux view_check_option
{
- THD *thd= YYTHD;
LEX *lex= Lex;
uint len= YYLIP->get_cpp_ptr() - lex->create_view_select.str;
void *create_view_select= thd->memdup(lex->create_view_select.str, len);
@@ -15172,7 +15078,6 @@ trigger_tail:
EACH_SYM
ROW_SYM
{ /* $15 */
- THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= YYLIP;
sp_head *sp;
@@ -15206,8 +15111,8 @@ trigger_tail:
sp_head *sp= lex->sphead;
lex->sql_command= SQLCOM_CREATE_TRIGGER;
- sp->set_stmt_end(YYTHD);
- sp->restore_thd_mem_root(YYTHD);
+ sp->set_stmt_end(thd);
+ sp->restore_thd_mem_root(thd);
if (sp->is_not_allowed_in_function("trigger"))
MYSQL_YYABORT;
@@ -15217,7 +15122,7 @@ trigger_tail:
sp_proc_stmt alternatives are not saving/restoring LEX, so
lex->query_tables can be wiped out.
*/
- if (!lex->select_lex.add_table_to_list(YYTHD, $9,
+ if (!lex->select_lex.add_table_to_list(thd, $9,
(LEX_STRING*) 0,
TL_OPTION_UPDATING,
TL_READ_NO_INSERT,
@@ -15236,7 +15141,6 @@ udf_tail:
AGGREGATE_SYM remember_name FUNCTION_SYM ident
RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
if (is_native_function(thd, & $4))
{
@@ -15254,7 +15158,6 @@ udf_tail:
| remember_name FUNCTION_SYM ident
RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
if (is_native_function(thd, & $3))
{
@@ -15277,7 +15180,6 @@ sf_tail:
sp_name /* $3 */
'(' /* $4 */
{ /* $5 */
- THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= YYLIP;
sp_head *sp;
@@ -15336,7 +15238,7 @@ sf_tail:
MYSQL_YYABORT;
}
- if (sp->fill_field_definition(YYTHD, lex,
+ if (sp->fill_field_definition(thd, lex,
(enum enum_field_types) $11,
&sp->m_return_field_def))
MYSQL_YYABORT;
@@ -15345,7 +15247,6 @@ sf_tail:
}
sp_c_chistics /* $13 */
{ /* $14 */
- THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= YYLIP;
@@ -15354,7 +15255,6 @@ sf_tail:
}
sp_proc_stmt /* $15 */
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
sp_head *sp= lex->sphead;
@@ -15425,10 +15325,10 @@ sp_tail:
sp= new sp_head();
if (sp == NULL)
MYSQL_YYABORT;
- sp->reset_thd_mem_root(YYTHD);
+ sp->reset_thd_mem_root(thd);
sp->init(lex);
sp->m_type= TYPE_ENUM_PROCEDURE;
- sp->init_sp_name(YYTHD, $3);
+ sp->init_sp_name(thd, $3);
lex->sphead= sp;
}
@@ -15443,7 +15343,6 @@ sp_tail:
sp_pdparam_list
')'
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
lex->sphead->m_param_end= YYLIP->get_cpp_tok_start();
@@ -15451,7 +15350,6 @@ sp_tail:
}
sp_c_chistics
{
- THD *thd= YYTHD;
LEX *lex= thd->lex;
lex->sphead->m_chistics= &lex->sp_chistics;
@@ -15462,9 +15360,9 @@ sp_tail:
LEX *lex= Lex;
sp_head *sp= lex->sphead;
- sp->set_stmt_end(YYTHD);
+ sp->set_stmt_end(thd);
lex->sql_command= SQLCOM_CREATE_PROCEDURE;
- sp->restore_thd_mem_root(YYTHD);
+ sp->restore_thd_mem_root(thd);
}
;
@@ -15501,21 +15399,21 @@ xid:
text_string
{
MYSQL_YYABORT_UNLESS($1->length() <= MAXGTRIDSIZE);
- if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID))))
+ if (!(Lex->xid=(XID *)thd->alloc(sizeof(XID))))
MYSQL_YYABORT;
Lex->xid->set(1L, $1->ptr(), $1->length(), 0, 0);
}
| text_string ',' text_string
{
MYSQL_YYABORT_UNLESS($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE);
- if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID))))
+ if (!(Lex->xid=(XID *)thd->alloc(sizeof(XID))))
MYSQL_YYABORT;
Lex->xid->set(1L, $1->ptr(), $1->length(), $3->ptr(), $3->length());
}
| text_string ',' text_string ',' ulong_num
{
MYSQL_YYABORT_UNLESS($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE);
- if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID))))
+ if (!(Lex->xid=(XID *)thd->alloc(sizeof(XID))))
MYSQL_YYABORT;
Lex->xid->set($5, $1->ptr(), $1->length(), $3->ptr(), $3->length());
}
diff --git a/sql/sys_vars.h b/sql/sys_vars.h
index e1c2201da31..3cc4da32811 100644
--- a/sql/sys_vars.h
+++ b/sql/sys_vars.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2002, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2010, 2013, Monty Program Ab.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -139,6 +140,7 @@ public:
option.u_max_value= (uchar**)max_var_ptr();
if (max_var_ptr())
*max_var_ptr()= max_val;
+
global_var(T)= def_val;
SYSVAR_ASSERT(size == sizeof(T));
SYSVAR_ASSERT(min_val < max_val);
@@ -993,13 +995,14 @@ public:
on_update_function on_update_func=0,
const char *substitute=0)
: sys_var(&all_sys_vars, name_arg, comment, flag_args, off, getopt.id,
- getopt.arg_type, SHOW_DOUBLE, (longlong) double2ulonglong(def_val),
+ getopt.arg_type, SHOW_DOUBLE,
+ (longlong) getopt_double2ulonglong(def_val),
lock, binlog_status_arg, on_check_func, on_update_func,
substitute)
{
option.var_type= GET_DOUBLE;
- option.min_value= (longlong) double2ulonglong(min_val);
- option.max_value= (longlong) double2ulonglong(max_val);
+ option.min_value= (longlong) getopt_double2ulonglong(min_val);
+ option.max_value= (longlong) getopt_double2ulonglong(max_val);
global_var(double)= (double)option.def_value;
SYSVAR_ASSERT(min_val < max_val);
SYSVAR_ASSERT(min_val <= def_val);
@@ -1031,7 +1034,7 @@ public:
void session_save_default(THD *thd, set_var *var)
{ var->save_result.double_value= global_var(double); }
void global_save_default(THD *thd, set_var *var)
- { var->save_result.double_value= (double)option.def_value; }
+ { var->save_result.double_value= getopt_ulonglong2double(option.def_value); }
};
/**
diff --git a/sql/table.cc b/sql/table.cc
index c2cc2070347..b81c9c2dcb6 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -690,6 +690,179 @@ err_not_open:
DBUG_RETURN(share->error);
}
+static bool create_key_infos(const uchar *strpos, const uchar *frm_image_end,
+ uint keys, KEY *keyinfo,
+ uint new_frm_ver, uint &ext_key_parts,
+ TABLE_SHARE *share, uint len,
+ KEY *first_keyinfo, char* &keynames)
+{
+ uint i, j, n_length;
+ KEY_PART_INFO *key_part= NULL;
+ ulong *rec_per_key= NULL;
+ KEY_PART_INFO *first_key_part= NULL;
+ uint first_key_parts= 0;
+
+ if (!keys)
+ {
+ if (!(keyinfo = (KEY*) alloc_root(&share->mem_root, len)))
+ return 1;
+ bzero((char*) keyinfo, len);
+ key_part= reinterpret_cast<KEY_PART_INFO*> (keyinfo);
+ }
+
+ /*
+ If share->use_ext_keys is set to TRUE we assume that any key
+ can be extended by the components of the primary key whose
+ definition is read first from the frm file.
+ For each key only those fields of the assumed primary key are
+ added that are not included in the proper key definition.
+ If after all it turns out that there is no primary key the
+ added components are removed from each key.
+
+ When in the future we support others schemes of extending of
+ secondary keys with components of the primary key we'll have
+ to change the type of this flag for an enumeration type.
+ */
+
+ for (i=0 ; i < keys ; i++, keyinfo++)
+ {
+ if (new_frm_ver >= 3)
+ {
+ if (strpos + 8 >= frm_image_end)
+ return 1;
+ keyinfo->flags= (uint) uint2korr(strpos) ^ HA_NOSAME;
+ keyinfo->key_length= (uint) uint2korr(strpos+2);
+ keyinfo->key_parts= (uint) strpos[4];
+ keyinfo->algorithm= (enum ha_key_alg) strpos[5];
+ keyinfo->block_size= uint2korr(strpos+6);
+ strpos+=8;
+ }
+ else
+ {
+ if (strpos + 4 >= frm_image_end)
+ return 1;
+ keyinfo->flags= ((uint) strpos[0]) ^ HA_NOSAME;
+ keyinfo->key_length= (uint) uint2korr(strpos+1);
+ keyinfo->key_parts= (uint) strpos[3];
+ keyinfo->algorithm= HA_KEY_ALG_UNDEF;
+ strpos+=4;
+ }
+
+ if (i == 0)
+ {
+ ext_key_parts+= (share->use_ext_keys ? first_keyinfo->key_parts*(keys-1) : 0);
+ n_length=keys * sizeof(KEY) + ext_key_parts * sizeof(KEY_PART_INFO);
+ if (!(keyinfo= (KEY*) alloc_root(&share->mem_root,
+ n_length + len)))
+ return 1;
+ bzero((char*) keyinfo,n_length);
+ share->key_info= keyinfo;
+ key_part= reinterpret_cast<KEY_PART_INFO*> (keyinfo + keys);
+
+ if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root,
+ sizeof(ulong) * ext_key_parts)))
+ return 1;
+ first_key_part= key_part;
+ first_key_parts= first_keyinfo->key_parts;
+ keyinfo->flags= first_keyinfo->flags;
+ keyinfo->key_length= first_keyinfo->key_length;
+ keyinfo->key_parts= first_keyinfo->key_parts;
+ keyinfo->algorithm= first_keyinfo->algorithm;
+ if (new_frm_ver >= 3)
+ keyinfo->block_size= first_keyinfo->block_size;
+ }
+
+ keyinfo->key_part= key_part;
+ keyinfo->rec_per_key= rec_per_key;
+ for (j=keyinfo->key_parts ; j-- ; key_part++)
+ {
+ if (strpos + (new_frm_ver >= 1 ? 9 : 7) >= frm_image_end)
+ return 1;
+ *rec_per_key++=0;
+ key_part->fieldnr= (uint16) (uint2korr(strpos) & FIELD_NR_MASK);
+ key_part->offset= (uint) uint2korr(strpos+2)-1;
+ key_part->key_type= (uint) uint2korr(strpos+5);
+ // key_part->field= (Field*) 0; // Will be fixed later
+ if (new_frm_ver >= 1)
+ {
+ key_part->key_part_flag= *(strpos+4);
+ key_part->length= (uint) uint2korr(strpos+7);
+ strpos+=9;
+ }
+ else
+ {
+ key_part->length= *(strpos+4);
+ key_part->key_part_flag=0;
+ if (key_part->length > 128)
+ {
+ key_part->length&=127; /* purecov: inspected */
+ key_part->key_part_flag=HA_REVERSE_SORT; /* purecov: inspected */
+ }
+ strpos+=7;
+ }
+ key_part->store_length=key_part->length;
+ }
+ keyinfo->ext_key_parts= keyinfo->key_parts;
+ keyinfo->ext_key_flags= keyinfo->flags;
+ keyinfo->ext_key_part_map= 0;
+ if (share->use_ext_keys && i)
+ {
+ keyinfo->ext_key_part_map= 0;
+ for (j= 0;
+ j < first_key_parts && keyinfo->ext_key_parts < MAX_REF_PARTS;
+ j++)
+ {
+ uint key_parts= keyinfo->key_parts;
+ KEY_PART_INFO* curr_key_part= keyinfo->key_part;
+ KEY_PART_INFO* curr_key_part_end= curr_key_part+key_parts;
+ for ( ; curr_key_part < curr_key_part_end; curr_key_part++)
+ {
+ if (curr_key_part->fieldnr == first_key_part[j].fieldnr)
+ break;
+ }
+ if (curr_key_part == curr_key_part_end)
+ {
+ *key_part++= first_key_part[j];
+ *rec_per_key++= 0;
+ keyinfo->ext_key_parts++;
+ keyinfo->ext_key_part_map|= 1 << j;
+ }
+ }
+ if (j == first_key_parts)
+ keyinfo->ext_key_flags= keyinfo->flags | HA_EXT_NOSAME;
+ }
+ share->ext_key_parts+= keyinfo->ext_key_parts;
+ }
+ keynames=(char*) key_part;
+ strpos+= strnmov(keynames, (char *) strpos, frm_image_end - strpos) - keynames;
+ if (*strpos++) // key names are \0-terminated
+ return 1;
+
+ //reading index comments
+ for (keyinfo= share->key_info, i=0; i < keys; i++, keyinfo++)
+ {
+ if (keyinfo->flags & HA_USES_COMMENT)
+ {
+ if (strpos + 2 >= frm_image_end)
+ return 1;
+ keyinfo->comment.length= uint2korr(strpos);
+ strpos+= 2;
+
+ if (strpos + keyinfo->comment.length >= frm_image_end)
+ return 1;
+ keyinfo->comment.str= strmake_root(&share->mem_root, (char*) strpos,
+ keyinfo->comment.length);
+ strpos+= keyinfo->comment.length;
+ }
+ DBUG_ASSERT(test(keyinfo->flags & HA_USES_COMMENT) ==
+ (keyinfo->comment.length > 0));
+ }
+
+ share->keys= keys; // do it *after* all key_info's are initialized
+
+ return 0;
+}
+
/**
Read data from a binary .frm file image into a TABLE_SHARE
@@ -717,7 +890,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
uint db_create_options, keys, key_parts, n_length;
uint com_length, null_bit_pos;
uint extra_rec_buf_length;
- uint i,j;
+ uint i;
bool use_hash;
char *keynames, *names, *comment_pos;
const uchar *forminfo, *extra2;
@@ -725,7 +898,6 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
uchar *record, *null_flags, *null_pos;
const uchar *disk_buff, *strpos;
ulong pos, record_offset;
- ulong *rec_per_key= NULL;
ulong rec_buff_length;
handler *handler_file= 0;
KEY *keyinfo;
@@ -740,9 +912,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
const uchar *options= 0;
KEY first_keyinfo;
uint len;
- KEY_PART_INFO *first_key_part= NULL;
uint ext_key_parts= 0;
- uint first_key_parts= 0;
plugin_ref se_plugin= 0;
keyinfo= &first_keyinfo;
share->ext_key_parts= 0;
@@ -906,186 +1076,21 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
if (disk_buff[0] & 0x80)
{
- share->keys= keys= (disk_buff[1] << 7) | (disk_buff[0] & 0x7f);
+ keys= (disk_buff[1] << 7) | (disk_buff[0] & 0x7f);
share->key_parts= key_parts= uint2korr(disk_buff+2);
}
else
{
- share->keys= keys= disk_buff[0];
+ keys= disk_buff[0];
share->key_parts= key_parts= disk_buff[1];
}
share->keys_for_keyread.init(0);
share->keys_in_use.init(keys);
-
- /*
- At this point we don't have enough information read from the frm file
- to get a proper handlerton for the interesting engine in order to get
- properties of this engine.
- */
- /* Currently only InnoDB can use extended keys */
- share->set_use_ext_keys_flag(legacy_db_type == DB_TYPE_INNODB);
+ ext_key_parts= key_parts;
len= (uint) uint2korr(disk_buff+4);
- if (!keys)
- {
- if (!(keyinfo = (KEY*) alloc_root(&share->mem_root, len)))
- goto err;
- bzero((char*) keyinfo, len);
- key_part= reinterpret_cast<KEY_PART_INFO*> (keyinfo+keys);
- }
- strpos= disk_buff+6;
- /*
- If share->use_ext_keys is set to TRUE we assume that any key
- can be extended by the components of the primary key whose
- definition is read first from the frm file.
- For each key only those fields of the assumed primary key are
- added that are not included in the proper key definition.
- If after all it turns out that there is no primary key the
- added components are removed from each key.
-
- When in the future we support others schemes of extending of
- secondary keys with components of the primary key we'll have
- to change the type of this flag for an enumeration type.
- */
-
- for (i=0 ; i < keys ; i++, keyinfo++)
- {
- if (new_frm_ver >= 3)
- {
- if (strpos + 8 >= frm_image_end)
- goto err;
- keyinfo->flags= (uint) uint2korr(strpos) ^ HA_NOSAME;
- keyinfo->key_length= (uint) uint2korr(strpos+2);
- keyinfo->key_parts= (uint) strpos[4];
- keyinfo->algorithm= (enum ha_key_alg) strpos[5];
- keyinfo->block_size= uint2korr(strpos+6);
- strpos+=8;
- }
- else
- {
- if (strpos + 4 >= frm_image_end)
- goto err;
- keyinfo->flags= ((uint) strpos[0]) ^ HA_NOSAME;
- keyinfo->key_length= (uint) uint2korr(strpos+1);
- keyinfo->key_parts= (uint) strpos[3];
- keyinfo->algorithm= HA_KEY_ALG_UNDEF;
- strpos+=4;
- }
-
- if (i == 0)
- {
- ext_key_parts= key_parts +
- (share->use_ext_keys ? first_keyinfo.key_parts*(keys-1) : 0);
-
- n_length=keys * sizeof(KEY) + ext_key_parts * sizeof(KEY_PART_INFO);
- if (!(keyinfo= (KEY*) alloc_root(&share->mem_root,
- n_length + len)))
- goto err; /* purecov: inspected */
- bzero((char*) keyinfo,n_length);
- share->key_info= keyinfo;
- key_part= reinterpret_cast<KEY_PART_INFO*> (keyinfo + keys);
-
- if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root,
- sizeof(ulong) * ext_key_parts)))
- goto err;
- first_key_part= key_part;
- first_key_parts= first_keyinfo.key_parts;
- keyinfo->flags= first_keyinfo.flags;
- keyinfo->key_length= first_keyinfo.key_length;
- keyinfo->key_parts= first_keyinfo.key_parts;
- keyinfo->algorithm= first_keyinfo.algorithm;
- if (new_frm_ver >= 3)
- keyinfo->block_size= first_keyinfo.block_size;
- }
-
- keyinfo->key_part= key_part;
- keyinfo->rec_per_key= rec_per_key;
- for (j=keyinfo->key_parts ; j-- ; key_part++)
- {
- if (strpos + (new_frm_ver >= 1 ? 9 : 7) >= frm_image_end)
- goto err;
- *rec_per_key++=0;
- key_part->fieldnr= (uint16) (uint2korr(strpos) & FIELD_NR_MASK);
- key_part->offset= (uint) uint2korr(strpos+2)-1;
- key_part->key_type= (uint) uint2korr(strpos+5);
- // key_part->field= (Field*) 0; // Will be fixed later
- if (new_frm_ver >= 1)
- {
- key_part->key_part_flag= *(strpos+4);
- key_part->length= (uint) uint2korr(strpos+7);
- strpos+=9;
- }
- else
- {
- key_part->length= *(strpos+4);
- key_part->key_part_flag=0;
- if (key_part->length > 128)
- {
- key_part->length&=127; /* purecov: inspected */
- key_part->key_part_flag=HA_REVERSE_SORT; /* purecov: inspected */
- }
- strpos+=7;
- }
- key_part->store_length=key_part->length;
- }
- keyinfo->ext_key_parts= keyinfo->key_parts;
- keyinfo->ext_key_flags= keyinfo->flags;
- keyinfo->ext_key_part_map= 0;
- if (share->use_ext_keys && i)
- {
- keyinfo->ext_key_part_map= 0;
- for (j= 0;
- j < first_key_parts && keyinfo->ext_key_parts < MAX_REF_PARTS;
- j++)
- {
- uint key_parts= keyinfo->key_parts;
- KEY_PART_INFO* curr_key_part= keyinfo->key_part;
- KEY_PART_INFO* curr_key_part_end= curr_key_part+key_parts;
- for ( ; curr_key_part < curr_key_part_end; curr_key_part++)
- {
- if (curr_key_part->fieldnr == first_key_part[j].fieldnr)
- break;
- }
- if (curr_key_part == curr_key_part_end)
- {
- *key_part++= first_key_part[j];
- *rec_per_key++= 0;
- keyinfo->ext_key_parts++;
- keyinfo->ext_key_part_map|= 1 << j;
- }
- }
- if (j == first_key_parts)
- keyinfo->ext_key_flags= keyinfo->flags | HA_EXT_NOSAME;
- }
- share->ext_key_parts+= keyinfo->ext_key_parts;
- }
- keynames=(char*) key_part;
- strpos+= strnmov(keynames, (char *) strpos, frm_image_end - strpos) - keynames;
- if (*strpos++) // key names are \0-terminated
- goto err;
-
- //reading index comments
- for (keyinfo= share->key_info, i=0; i < keys; i++, keyinfo++)
- {
- if (keyinfo->flags & HA_USES_COMMENT)
- {
- if (strpos + 2 >= frm_image_end)
- goto err;
- keyinfo->comment.length= uint2korr(strpos);
- strpos+= 2;
-
- if (strpos + keyinfo->comment.length >= frm_image_end)
- goto err;
- keyinfo->comment.str= strmake_root(&share->mem_root, (char*) strpos,
- keyinfo->comment.length);
- strpos+= keyinfo->comment.length;
- }
- DBUG_ASSERT(test(keyinfo->flags & HA_USES_COMMENT) ==
- (keyinfo->comment.length > 0));
- }
-
- share->reclength = uint2korr((frm_image+16));
+ share->reclength = uint2korr(frm_image+16);
share->stored_rec_length= share->reclength;
if (frm_image[26] == 1)
share->system= 1; /* one-record-database */
@@ -1171,6 +1176,14 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
}
next_chunk+= str_db_type_length + 2;
}
+
+ share->set_use_ext_keys_flag(plugin_hton(se_plugin)->flags & HTON_EXTENDED_KEYS);
+
+ if (create_key_infos(disk_buff + 6, frm_image_end, keys, keyinfo,
+ new_frm_ver, ext_key_parts,
+ share, len, &first_keyinfo, keynames))
+ goto err;
+
if (next_chunk + 5 < buff_end)
{
uint32 partition_info_str_len = uint4korr(next_chunk);
@@ -1257,6 +1270,14 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
}
DBUG_ASSERT(next_chunk <= buff_end);
}
+ else
+ {
+ if (create_key_infos(disk_buff + 6, frm_image_end, keys, keyinfo,
+ new_frm_ver, ext_key_parts,
+ share, len, &first_keyinfo, keynames))
+ goto err;
+ }
+
share->key_block_size= uint2korr(frm_image+62);
if (share->db_plugin && !plugin_equals(share->db_plugin, se_plugin))
@@ -1292,7 +1313,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
share->comment.length);
}
- DBUG_PRINT("info",("i_count: %d i_parts: %d index: %d n_length: %d int_length: %d com_length: %d vcol_screen_length: %d", interval_count,interval_parts, share->keys,n_length,int_length, com_length, vcol_screen_length));
+ DBUG_PRINT("info",("i_count: %d i_parts: %d index: %d n_length: %d int_length: %d com_length: %d vcol_screen_length: %d", interval_count,interval_parts, keys,n_length,int_length, com_length, vcol_screen_length));
if (!(field_ptr = (Field **)
@@ -1643,12 +1664,12 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
}
else
{
- add_first_key_parts= first_key_parts;
+ add_first_key_parts= first_keyinfo.key_parts;
/*
Do not add components of the primary key starting from
the major component defined over the beginning of a field.
*/
- for (i= 0; i < first_key_parts; i++)
+ for (i= 0; i < first_keyinfo.key_parts; i++)
{
uint fieldnr= keyinfo[0].key_part[i].fieldnr;
if (share->field[fieldnr-1]->key_length() !=
@@ -1661,7 +1682,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
}
}
- for (uint key=0 ; key < share->keys ; key++,keyinfo++)
+ for (uint key=0 ; key < keys ; key++,keyinfo++)
{
uint usable_parts= 0;
keyinfo->name=(char*) share->keynames.type_names[key];
@@ -1931,7 +1952,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
{
reg_field= *share->found_next_number_field;
if ((int) (share->next_number_index= (uint)
- find_ref_key(share->key_info, share->keys,
+ find_ref_key(share->key_info, keys,
share->default_values, reg_field,
&share->next_number_key_offset,
&share->next_number_keypart)) < 0)
@@ -2230,7 +2251,7 @@ bool fix_vcol_expr(THD *thd,
Item* func_expr= vcol_info->expr_item;
bool result= TRUE;
TABLE_LIST tables;
- int error;
+ int error= 0;
const char *save_where;
Field **ptr, *field;
enum_mark_columns save_mark_used_columns= thd->mark_used_columns;
@@ -2243,7 +2264,11 @@ bool fix_vcol_expr(THD *thd,
thd->where= "virtual column function";
/* Fix fields referenced to by the virtual column function */
- error= func_expr->fix_fields(thd, (Item**)0);
+ if (!func_expr->fixed)
+ error= func_expr->fix_fields(thd, &vcol_info->expr_item);
+ /* fix_fields could change the expression */
+ func_expr= vcol_info->expr_item;
+ /* Number of columns will be checked later */
if (unlikely(error))
{
diff --git a/sql/table.h b/sql/table.h
index c7282cee093..ffbe88602f9 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -1042,6 +1042,9 @@ struct st_cond_statistic;
#define CHECK_ROW_FOR_NULLS_TO_REJECT (1 << 0)
#define REJECT_ROW_DUE_TO_NULL_FIELDS (1 << 1)
+/* Bitmap of table's fields */
+typedef Bitmap<MAX_FIELDS> Field_map;
+
struct TABLE
{
TABLE() {} /* Remove gcc warning */
@@ -1241,6 +1244,10 @@ public:
*/
bool distinct;
bool const_table,no_rows, used_for_duplicate_elimination;
+ /**
+ Forces DYNAMIC Aria row format for internal temporary tables.
+ */
+ bool keep_row_order;
/**
If set, the optimizer has found that row retrieval should access index
@@ -2226,6 +2233,16 @@ struct TABLE_LIST
bool single_table_updatable();
+ bool is_inner_table_of_outer_join()
+ {
+ for (TABLE_LIST *tbl= this; tbl; tbl= tbl->embedding)
+ {
+ if (tbl->outer_join)
+ return true;
+ }
+ return false;
+ }
+
private:
bool prep_check_option(THD *thd, uint8 check_opt_type);
bool prep_where(THD *thd, Item **conds, bool no_where_clause);