Commit dd1c1c1b authored by Otto Kekäläinen's avatar Otto Kekäläinen
Browse files

Merge tag 'upstream/5.5.57' into ubuntu-14.04

Upstream version 5.5.57

# gpg: Signature made su 23. heinäkuuta 2017 23.35.34 EEST
# gpg:                using RSA key BED8449FCEE8DA88
# gpg: Good signature from "Otto Kekäläinen <otto@seravo.fi>" [full]
# gpg:                 aka "Otto Kekäläinen <otto@kekalainen.net>" [full]
# gpg:                 aka "Otto Kekäläinen <otto@fsfe.org>" [full]
# gpg:                 aka "Otto Kekäläinen <otto@linux.com>" [full]
# gpg:                 aka "Otto Kekäläinen <otto.kekalainen@seravo.fi>" [full]
# gpg:                 aka "Otto Kekäläinen <otto@mariadb.org>" [undefined]
# gpg:                 aka "Otto Kekäläinen <otto@debian.org>" [undefined]
# gpg:                 aka "Otto Kekäläinen <otto@sange.fi>" [full]
parents fb3d7b9e 69b6b895
#!/usr/bin/perl #!@PERL_PATH@
# -*- cperl -*- # -*- cperl -*-
# #
# Copyright (c) 2007, 2013, Oracle and/or its affiliates. # Copyright (c) 2007, 2017, Oracle and/or its affiliates.
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
......
#!/usr/bin/perl #!@PERL_PATH@
# -*- cperl -*- # -*- cperl -*-
# #
# Copyright (c) 2007, 2012, Oracle and/or its affiliates. # Copyright (c) 2007, 2017, Oracle and/or its affiliates.
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -388,6 +388,3 @@ Thanks for using MySQL! ...@@ -388,6 +388,3 @@ Thanks for using MySQL!
HERE HERE
#!/usr/bin/perl #!@PERL_PATH@
## Emacs, this is -*- perl -*- mode? :-) ## Emacs, this is -*- perl -*- mode? :-)
# Copyright (c) 2000, 2007 MySQL AB, 2009 Sun Microsystems, Inc. # Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
# Use is subject to license terms.
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public # modify it under the terms of the GNU Library General Public
......
#!/usr/bin/perl #!@PERL_PATH@
# Copyright (c) 2000-2002, 2004, 2006 MySQL AB, 2009 Sun Microsystems, Inc. # Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
# Use is subject to license terms.
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
......
#!/usr/bin/perl #!@PERL_PATH@
# Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public # modify it under the terms of the GNU Library General Public
...@@ -477,15 +477,22 @@ MySQLaccess::Report::Print_Header(); ...@@ -477,15 +477,22 @@ MySQLaccess::Report::Print_Header();
# ***************************** # *****************************
# Read configuration-file # Read configuration-file
MySQLaccess::Debug::Print(1, "Reading configuration file..."); MySQLaccess::Debug::Print(1, "Reading configuration file...");
if (-f "./$script_conf") { if (-f "@sysconfdir@/$script_conf") {
require "./$script_conf"; print "Configuration file '$script_conf' is found in '@sysconfdir@/'\n";
}
elsif (-f "@sysconfdir@/$script_conf") {
require "@sysconfdir@/$script_conf"; require "@sysconfdir@/$script_conf";
} }
elsif (-f "/etc/$script_conf") { elsif (-f "/etc/$script_conf") {
print "Configuration file '$script_conf' is found in '/etc/'\n";
require "/etc/$script_conf"; require "/etc/$script_conf";
} }
elsif (-f "./$script_conf") {
print "\nERROR! Configuration file '$script_conf' is found in the current ";
print "directory.\nThe permissible locations for this file are either ";
print "@sysconfdir@/ or /etc/\n";
print "Please move it to one of these locations and retry.\n\n";
exit 0;
}
# **************************** # ****************************
# Read in all parameters # Read in all parameters
......
#!/usr/bin/perl #!@PERL_PATH@
# Copyright (c) 2000, 2010, Oracle and/or its affiliates.
# Copyright (c) 2000-2011 Monty Program Ab, Jani Tolonen
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; version 2
# of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this library; if not, write to the Free
# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
# MA 02110-1301, USA
# Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2000, 2017, Oracle and/or its affiliates.
# Copyright (c) 2010, 2017, MariaDB Corporation
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public # modify it under the terms of the GNU Library General Public
......
#!/usr/bin/perl #!@PERL_PATH@
# Copyright (c) 2000-2002, 2005-2008 MySQL AB, 2008, 2009 Sun Microsystems, Inc. # Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
# Use is subject to license terms.
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public # modify it under the terms of the GNU Library General Public
......
#!/usr/bin/perl #!@PERL_PATH@
# Copyright (c) 2000, 2010, Oracle and/or its affiliates # Copyright (c) 2000, 2017, Oracle and/or its affiliates.
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public # modify it under the terms of the GNU Library General Public
......
...@@ -634,7 +634,7 @@ int ha_partition::create(const char *name, TABLE *table_arg, ...@@ -634,7 +634,7 @@ int ha_partition::create(const char *name, TABLE *table_arg,
int ha_partition::drop_partitions(const char *path) int ha_partition::drop_partitions(const char *path)
{ {
List_iterator<partition_element> part_it(m_part_info->partitions); List_iterator<partition_element> part_it(m_part_info->partitions);
char part_name_buff[FN_REFLEN]; char part_name_buff[FN_REFLEN + 1];
uint num_parts= m_part_info->partitions.elements; uint num_parts= m_part_info->partitions.elements;
uint num_subparts= m_part_info->num_subparts; uint num_subparts= m_part_info->num_subparts;
uint i= 0; uint i= 0;
...@@ -667,9 +667,11 @@ int ha_partition::drop_partitions(const char *path) ...@@ -667,9 +667,11 @@ int ha_partition::drop_partitions(const char *path)
{ {
partition_element *sub_elem= sub_it++; partition_element *sub_elem= sub_it++;
part= i * num_subparts + j; part= i * num_subparts + j;
create_subpartition_name(part_name_buff, path, if ((ret_error= create_subpartition_name(part_name_buff,
sizeof(part_name_buff), path,
part_elem->partition_name, part_elem->partition_name,
sub_elem->partition_name, name_variant); sub_elem->partition_name, name_variant)))
error= ret_error;
file= m_file[part]; file= m_file[part];
DBUG_PRINT("info", ("Drop subpartition %s", part_name_buff)); DBUG_PRINT("info", ("Drop subpartition %s", part_name_buff));
if ((ret_error= file->ha_delete_table(part_name_buff))) if ((ret_error= file->ha_delete_table(part_name_buff)))
...@@ -680,9 +682,12 @@ int ha_partition::drop_partitions(const char *path) ...@@ -680,9 +682,12 @@ int ha_partition::drop_partitions(const char *path)
} }
else else
{ {
create_partition_name(part_name_buff, path, if ((ret_error= create_partition_name(part_name_buff,
part_elem->partition_name, name_variant, sizeof(part_name_buff), path,
TRUE); part_elem->partition_name, name_variant, TRUE)))
error= ret_error;
else
{
file= m_file[i]; file= m_file[i];
DBUG_PRINT("info", ("Drop partition %s", part_name_buff)); DBUG_PRINT("info", ("Drop partition %s", part_name_buff));
if ((ret_error= file->ha_delete_table(part_name_buff))) if ((ret_error= file->ha_delete_table(part_name_buff)))
...@@ -690,6 +695,7 @@ int ha_partition::drop_partitions(const char *path) ...@@ -690,6 +695,7 @@ int ha_partition::drop_partitions(const char *path)
if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos)) if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos))
error= 1; error= 1;
} }
}
if (part_elem->part_state == PART_IS_CHANGED) if (part_elem->part_state == PART_IS_CHANGED)
part_elem->part_state= PART_NORMAL; part_elem->part_state= PART_NORMAL;
else else
...@@ -724,8 +730,8 @@ int ha_partition::rename_partitions(const char *path) ...@@ -724,8 +730,8 @@ int ha_partition::rename_partitions(const char *path)
{ {
List_iterator<partition_element> part_it(m_part_info->partitions); List_iterator<partition_element> part_it(m_part_info->partitions);
List_iterator<partition_element> temp_it(m_part_info->temp_partitions); List_iterator<partition_element> temp_it(m_part_info->temp_partitions);
char part_name_buff[FN_REFLEN]; char part_name_buff[FN_REFLEN + 1];
char norm_name_buff[FN_REFLEN]; char norm_name_buff[FN_REFLEN + 1];
uint num_parts= m_part_info->partitions.elements; uint num_parts= m_part_info->partitions.elements;
uint part_count= 0; uint part_count= 0;
uint num_subparts= m_part_info->num_subparts; uint num_subparts= m_part_info->num_subparts;
...@@ -767,10 +773,11 @@ int ha_partition::rename_partitions(const char *path) ...@@ -767,10 +773,11 @@ int ha_partition::rename_partitions(const char *path)
{ {
sub_elem= sub_it++; sub_elem= sub_it++;
file= m_reorged_file[part_count++]; file= m_reorged_file[part_count++];
create_subpartition_name(norm_name_buff, path, if ((ret_error= create_subpartition_name(norm_name_buff,
sizeof(norm_name_buff), path,
part_elem->partition_name, part_elem->partition_name,
sub_elem->partition_name, sub_elem->partition_name, NORMAL_PART_NAME)))
NORMAL_PART_NAME); error= ret_error;
DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff)); DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff));
if ((ret_error= file->ha_delete_table(norm_name_buff))) if ((ret_error= file->ha_delete_table(norm_name_buff)))
error= ret_error; error= ret_error;
...@@ -783,9 +790,12 @@ int ha_partition::rename_partitions(const char *path) ...@@ -783,9 +790,12 @@ int ha_partition::rename_partitions(const char *path)
else else
{ {
file= m_reorged_file[part_count++]; file= m_reorged_file[part_count++];
create_partition_name(norm_name_buff, path, if ((ret_error= create_partition_name(norm_name_buff,
part_elem->partition_name, NORMAL_PART_NAME, sizeof(norm_name_buff), path,
TRUE); part_elem->partition_name, NORMAL_PART_NAME, TRUE)))
error= ret_error;
else
{
DBUG_PRINT("info", ("Delete partition %s", norm_name_buff)); DBUG_PRINT("info", ("Delete partition %s", norm_name_buff));
if ((ret_error= file->ha_delete_table(norm_name_buff))) if ((ret_error= file->ha_delete_table(norm_name_buff)))
error= ret_error; error= ret_error;
...@@ -794,6 +804,7 @@ int ha_partition::rename_partitions(const char *path) ...@@ -794,6 +804,7 @@ int ha_partition::rename_partitions(const char *path)
else else
part_elem->log_entry= NULL; /* Indicate success */ part_elem->log_entry= NULL; /* Indicate success */
} }
}
} while (++i < temp_partitions); } while (++i < temp_partitions);
(void) sync_ddl_log(); (void) sync_ddl_log();
} }
...@@ -835,10 +846,11 @@ int ha_partition::rename_partitions(const char *path) ...@@ -835,10 +846,11 @@ int ha_partition::rename_partitions(const char *path)
{ {
sub_elem= sub_it++; sub_elem= sub_it++;
part= i * num_subparts + j; part= i * num_subparts + j;
create_subpartition_name(norm_name_buff, path, if ((ret_error= create_subpartition_name(norm_name_buff,
sizeof(norm_name_buff), path,
part_elem->partition_name, part_elem->partition_name,
sub_elem->partition_name, sub_elem->partition_name, NORMAL_PART_NAME)))
NORMAL_PART_NAME); error= ret_error;
if (part_elem->part_state == PART_IS_CHANGED) if (part_elem->part_state == PART_IS_CHANGED)
{ {
file= m_reorged_file[part_count++]; file= m_reorged_file[part_count++];
...@@ -850,10 +862,11 @@ int ha_partition::rename_partitions(const char *path) ...@@ -850,10 +862,11 @@ int ha_partition::rename_partitions(const char *path)
(void) sync_ddl_log(); (void) sync_ddl_log();
} }
file= m_new_file[part]; file= m_new_file[part];
create_subpartition_name(part_name_buff, path, if ((ret_error= create_subpartition_name(part_name_buff,
sizeof(part_name_buff), path,
part_elem->partition_name, part_elem->partition_name,
sub_elem->partition_name, sub_elem->partition_name, TEMP_PART_NAME)))
TEMP_PART_NAME); error= ret_error;
DBUG_PRINT("info", ("Rename subpartition from %s to %s", DBUG_PRINT("info", ("Rename subpartition from %s to %s",
part_name_buff, norm_name_buff)); part_name_buff, norm_name_buff));
if ((ret_error= file->ha_rename_table(part_name_buff, if ((ret_error= file->ha_rename_table(part_name_buff,
...@@ -867,9 +880,15 @@ int ha_partition::rename_partitions(const char *path) ...@@ -867,9 +880,15 @@ int ha_partition::rename_partitions(const char *path)
} }
else else
{ {
create_partition_name(norm_name_buff, path, if ((ret_error= create_partition_name(norm_name_buff,
part_elem->partition_name, NORMAL_PART_NAME, sizeof(norm_name_buff), path,
TRUE); part_elem->partition_name, NORMAL_PART_NAME, TRUE)) ||
(ret_error= create_partition_name(part_name_buff,
sizeof(part_name_buff), path,
part_elem->partition_name, TEMP_PART_NAME, TRUE)))
error= ret_error;
else
{
if (part_elem->part_state == PART_IS_CHANGED) if (part_elem->part_state == PART_IS_CHANGED)
{ {
file= m_reorged_file[part_count++]; file= m_reorged_file[part_count++];
...@@ -881,9 +900,6 @@ int ha_partition::rename_partitions(const char *path) ...@@ -881,9 +900,6 @@ int ha_partition::rename_partitions(const char *path)
(void) sync_ddl_log(); (void) sync_ddl_log();
} }
file= m_new_file[i]; file= m_new_file[i];
create_partition_name(part_name_buff, path,
part_elem->partition_name, TEMP_PART_NAME,
TRUE);
DBUG_PRINT("info", ("Rename partition from %s to %s", DBUG_PRINT("info", ("Rename partition from %s to %s",
part_name_buff, norm_name_buff)); part_name_buff, norm_name_buff));
if ((ret_error= file->ha_rename_table(part_name_buff, if ((ret_error= file->ha_rename_table(part_name_buff,
...@@ -895,6 +911,7 @@ int ha_partition::rename_partitions(const char *path) ...@@ -895,6 +911,7 @@ int ha_partition::rename_partitions(const char *path)
part_elem->log_entry= NULL; part_elem->log_entry= NULL;
} }
} }
}
} while (++i < num_parts); } while (++i < num_parts);
(void) sync_ddl_log(); (void) sync_ddl_log();
DBUG_RETURN(error); DBUG_RETURN(error);
...@@ -1488,7 +1505,7 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info, ...@@ -1488,7 +1505,7 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info,
{ {
List_iterator<partition_element> part_it(m_part_info->partitions); List_iterator<partition_element> part_it(m_part_info->partitions);
List_iterator <partition_element> t_it(m_part_info->temp_partitions); List_iterator <partition_element> t_it(m_part_info->temp_partitions);
char part_name_buff[FN_REFLEN]; char part_name_buff[FN_REFLEN + 1];
uint num_parts= m_part_info->partitions.elements; uint num_parts= m_part_info->partitions.elements;
uint num_subparts= m_part_info->num_subparts; uint num_subparts= m_part_info->num_subparts;
uint i= 0; uint i= 0;
...@@ -1698,10 +1715,14 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info, ...@@ -1698,10 +1715,14 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info,
do do
{ {
partition_element *sub_elem= sub_it++; partition_element *sub_elem= sub_it++;
create_subpartition_name(part_name_buff, path, if ((error= create_subpartition_name(part_name_buff,
part_elem->partition_name, sizeof(part_name_buff), path,
sub_elem->partition_name, part_elem->partition_name, sub_elem->partition_name,
name_variant); name_variant)))
{
cleanup_new_partition(part_count);
DBUG_RETURN(error);
}
part= i * num_subparts + j; part= i * num_subparts + j;
DBUG_PRINT("info", ("Add subpartition %s", part_name_buff)); DBUG_PRINT("info", ("Add subpartition %s", part_name_buff));
if ((error= prepare_new_partition(table, create_info, if ((error= prepare_new_partition(table, create_info,
...@@ -1719,9 +1740,14 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info, ...@@ -1719,9 +1740,14 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info,
} }
else else
{ {
create_partition_name(part_name_buff, path, if ((error= create_partition_name(part_name_buff,
part_elem->partition_name, name_variant, sizeof(part_name_buff), path, part_elem->partition_name,
TRUE); name_variant, TRUE)))
{
cleanup_new_partition(part_count);
DBUG_RETURN(error);
}
DBUG_PRINT("info", ("Add partition %s", part_name_buff)); DBUG_PRINT("info", ("Add partition %s", part_name_buff));
if ((error= prepare_new_partition(table, create_info, if ((error= prepare_new_partition(table, create_info,
new_file_array[i], new_file_array[i],
...@@ -1980,8 +2006,8 @@ int ha_partition::del_ren_cre_table(const char *from, ...@@ -1980,8 +2006,8 @@ int ha_partition::del_ren_cre_table(const char *from,
{ {
int save_error= 0; int save_error= 0;
int error= HA_ERR_INTERNAL_ERROR; int error= HA_ERR_INTERNAL_ERROR;
char from_buff[FN_REFLEN], to_buff[FN_REFLEN], from_lc_buff[FN_REFLEN], char from_buff[FN_REFLEN + 1], to_buff[FN_REFLEN + 1],
to_lc_buff[FN_REFLEN], buff[FN_REFLEN]; from_lc_buff[FN_REFLEN], to_lc_buff[FN_REFLEN], buff[FN_REFLEN];
char *name_buffer_ptr; char *name_buffer_ptr;
const char *from_path; const char *from_path;
const char *to_path= NULL; const char *to_path= NULL;
...@@ -2028,13 +2054,15 @@ int ha_partition::del_ren_cre_table(const char *from, ...@@ -2028,13 +2054,15 @@ int ha_partition::del_ren_cre_table(const char *from,
i= 0; i= 0;
do do
{ {
create_partition_name(from_buff, from_path, name_buffer_ptr, if ((error= create_partition_name(from_buff, sizeof(from_buff), from_path,
NORMAL_PART_NAME, FALSE); name_buffer_ptr, NORMAL_PART_NAME, FALSE)))
goto rename_error;
if (to != NULL) if (to != NULL)
{ // Rename branch { // Rename branch
create_partition_name(to_buff, to_path, name_buffer_ptr, if ((error= create_partition_name(to_buff, sizeof(to_buff), to_path,
NORMAL_PART_NAME, FALSE); name_buffer_ptr, NORMAL_PART_NAME, FALSE)))
goto rename_error;
error= (*file)->ha_rename_table(from_buff, to_buff); error= (*file)->ha_rename_table(from_buff, to_buff);
if (error) if (error)
goto rename_error; goto rename_error;
...@@ -2081,9 +2109,9 @@ int ha_partition::del_ren_cre_table(const char *from, ...@@ -2081,9 +2109,9 @@ int ha_partition::del_ren_cre_table(const char *from,
name_buffer_ptr= m_name_buffer_ptr; name_buffer_ptr= m_name_buffer_ptr;
for (abort_file= file, file= m_file; file < abort_file; file++) for (abort_file= file, file= m_file; file < abort_file; file++)
{ {
create_partition_name(from_buff, from_path, name_buffer_ptr, NORMAL_PART_NAME, if (!create_partition_name(from_buff, sizeof(from_buff), from_path,
FALSE); name_buffer_ptr, NORMAL_PART_NAME, FALSE))
(void) (*file)->ha_delete_table((const char*) from_buff); (void) (*file)->ha_delete_table(from_buff);
name_buffer_ptr= strend(name_buffer_ptr) + 1; name_buffer_ptr= strend(name_buffer_ptr) + 1;
} }
DBUG_RETURN(error); DBUG_RETURN(error);
...@@ -2092,11 +2120,10 @@ int ha_partition::del_ren_cre_table(const char *from, ...@@ -2092,11 +2120,10 @@ int ha_partition::del_ren_cre_table(const char *from,
for (abort_file= file, file= m_file; file < abort_file; file++) for (abort_file= file, file= m_file; file < abort_file; file++)
{ {
/* Revert the rename, back from 'to' to the original 'from' */ /* Revert the rename, back from 'to' to the original 'from' */
create_partition_name(from_buff, from_path, name_buffer_ptr, if (!create_partition_name(from_buff, sizeof(from_buff), from_path,
NORMAL_PART_NAME, FALSE); name_buffer_ptr, NORMAL_PART_NAME, FALSE) &&
create_partition_name(to_buff, to_path, name_buffer_ptr, !create_partition_name(to_buff, sizeof(to_buff), to_path, name_buffer_ptr,
NORMAL_PART_NAME, FALSE); NORMAL_PART_NAME, FALSE))
/* Ignore error here */
(void) (*file)->ha_rename_table(to_buff, from_buff); (void) (*file)->ha_rename_table(to_buff, from_buff);
name_buffer_ptr= strend(name_buffer_ptr) + 1; name_buffer_ptr= strend(name_buffer_ptr) + 1;
} }
...@@ -2895,7 +2922,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked) ...@@ -2895,7 +2922,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
char *name_buffer_ptr; char *name_buffer_ptr;
int error= HA_ERR_INITIALIZATION; int error= HA_ERR_INITIALIZATION;
handler **file; handler **file;
char name_buff[FN_REFLEN]; char name_buff[FN_REFLEN + 1];
bool is_not_tmp_table= (table_share->tmp_table == NO_TMP_TABLE); bool is_not_tmp_table= (table_share->tmp_table == NO_TMP_TABLE);
ulonglong check_table_flags; ulonglong check_table_flags;
DBUG_ENTER("ha_partition::open"); DBUG_ENTER("ha_partition::open");
...@@ -2965,8 +2992,9 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked) ...@@ -2965,8 +2992,9 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
file= m_is_clone_of->m_file; file= m_is_clone_of->m_file;
for (i= 0; i < m_tot_parts; i++) for (i= 0; i < m_tot_parts; i++)
{ {
create_partition_name(name_buff, name, name_buffer_ptr, NORMAL_PART_NAME, if ((error= create_partition_name(name_buff, sizeof(name_buff), name,
FALSE); name_buffer_ptr, NORMAL_PART_NAME, FALSE)))
goto err_handler;
if (!(m_file[i]= file[i]->clone(name_buff, m_clone_mem_root))) if (!(m_file[i]= file[i]->clone(name_buff, m_clone_mem_root)))
{ {
error= HA_ERR_INITIALIZATION; error= HA_ERR_INITIALIZATION;
...@@ -2981,8 +3009,9 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked) ...@@ -2981,8 +3009,9 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
file= m_file; file= m_file;
do do
{ {
create_partition_name(name_buff, name, name_buffer_ptr, NORMAL_PART_NAME, if ((error= create_partition_name(name_buff, sizeof(name_buff), name,
FALSE); name_buffer_ptr, NORMAL_PART_NAME, FALSE)))
goto err_handler;
table->s->connect_string = m_connect_string[(uint)(file-m_file)]; table->s->connect_string = m_connect_string[(uint)(file-m_file)];
if ((error= (*file)->ha_open(table, name_buff, mode, test_if_locked))) if ((error= (*file)->ha_open(table, name_buff, mode, test_if_locked)))
goto err_handler; goto err_handler;
......
/* /*
Copyright (c) 2000, 2016, Oracle and/or its affiliates. Copyright (c) 2000, 2016, Oracle and/or its affiliates.
Copyright (c) 2010, 2016, MariaDB Copyright (c) 2010, 2017, MariaDB Corporation
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -817,6 +817,7 @@ Item_ident::Item_ident(Name_resolution_context *context_arg, ...@@ -817,6 +817,7 @@ Item_ident::Item_ident(Name_resolution_context *context_arg,
cached_table(0), depended_from(0), can_be_depended(TRUE) cached_table(0), depended_from(0), can_be_depended(TRUE)
{ {
name = (char*) field_name_arg; name = (char*) field_name_arg;
name_length= name ? strlen(name) : 0;
} }
...@@ -829,6 +830,7 @@ Item_ident::Item_ident(TABLE_LIST *view_arg, const char *field_name_arg) ...@@ -829,6 +830,7 @@ Item_ident::Item_ident(TABLE_LIST *view_arg, const char *field_name_arg)
cached_table(NULL), depended_from(NULL), can_be_depended(TRUE) cached_table(NULL), depended_from(NULL), can_be_depended(TRUE)
{ {
name = (char*) field_name_arg; name = (char*) field_name_arg;
name_length= name ? strlen(name) : 0;
} }
...@@ -4622,7 +4624,7 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) ...@@ -4622,7 +4624,7 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list)
int cur_match_degree= 0; int cur_match_degree= 0;
/* SELECT list element with explicit alias */ /* SELECT list element with explicit alias */
if ((*(cur_group->item))->name && if ((*(cur_group->item))->name && !table_name &&
!(*(cur_group->item))->is_autogenerated_name && !(*(cur_group->item))->is_autogenerated_name &&
!my_strcasecmp(system_charset_info, !my_strcasecmp(system_charset_info,
(*(cur_group->item))->name, field_name)) (*(cur_group->item))->name, field_name))
...@@ -5045,6 +5047,12 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) ...@@ -5045,6 +5047,12 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
((ref_type == REF_ITEM || ref_type == FIELD_ITEM) ? ((ref_type == REF_ITEM || ref_type == FIELD_ITEM) ?
(Item_ident*) (*reference) : (Item_ident*) (*reference) :
0)); 0));
if (thd->lex->in_sum_func &&
thd->lex->in_sum_func->nest_level >= select->nest_level)
{
set_if_bigger(thd->lex->in_sum_func->max_arg_level,
select->nest_level);
}
/* /*
A reference to a view field had been found and we A reference to a view field had been found and we
substituted it instead of this Item (find_field_in_tables substituted it instead of this Item (find_field_in_tables
......
...@@ -1165,7 +1165,11 @@ class Item_func_coercibility :public Item_int_func ...@@ -1165,7 +1165,11 @@ class Item_func_coercibility :public Item_int_func
longlong val_int(); longlong val_int();
const char *func_name() const { return "coercibility"; } const char *func_name() const { return "coercibility"; }
void fix_length_and_dec() { max_length=10; maybe_null= 0; } void fix_length_and_dec() { max_length=10; maybe_null= 0; }
table_map not_null_tables() const { return 0; } bool eval_not_null_tables(uchar *opt_arg)
{
not_null_tables_cache= 0;
return 0;
}
}; };
class Item_func_locate :public Item_int_func class Item_func_locate :public Item_int_func
...@@ -1433,7 +1437,11 @@ class Item_udf_func :public Item_func ...@@ -1433,7 +1437,11 @@ class Item_udf_func :public Item_func
} }
void cleanup(); void cleanup();
Item_result result_type () const { return udf.result_type(); } Item_result result_type () const { return udf.result_type(); }
table_map not_null_tables() const { return 0; } bool eval_not_null_tables(uchar *opt_arg)
{
not_null_tables_cache= 0;
return 0;
}
bool is_expensive() { return 1; } bool is_expensive() { return 1; }
virtual void print(String *str, enum_query_type query_type); virtual void print(String *str, enum_query_type query_type);
}; };
...@@ -1889,7 +1897,11 @@ class Item_func_match :public Item_real_func ...@@ -1889,7 +1897,11 @@ class Item_func_match :public Item_real_func
bool is_expensive_processor(uchar *arg) { return TRUE; } bool is_expensive_processor(uchar *arg) { return TRUE; }
enum Functype functype() const { return FT_FUNC; } enum Functype functype() const { return FT_FUNC; }
const char *func_name() const { return "match"; } const char *func_name() const { return "match"; }
table_map not_null_tables() const { return 0; } bool eval_not_null_tables(uchar *opt_arg)
{
not_null_tables_cache= 0;
return 0;
}
bool fix_fields(THD *thd, Item **ref); bool fix_fields(THD *thd, Item **ref);
bool eq(const Item *, bool binary_cmp) const; bool eq(const Item *, bool binary_cmp) const;
/* The following should be safe, even if we compare doubles */ /* The following should be safe, even if we compare doubles */
...@@ -2091,6 +2103,11 @@ class Item_func_sp :public Item_func ...@@ -2091,6 +2103,11 @@ class Item_func_sp :public Item_func
{ {
return TRUE; return TRUE;
} }
bool eval_not_null_tables(uchar *opt_arg)
{
not_null_tables_cache= 0;
return 0;
}
}; };
...@@ -2138,7 +2155,11 @@ class Item_func_last_value :public Item_func ...@@ -2138,7 +2155,11 @@ class Item_func_last_value :public Item_func
void fix_length_and_dec(); void fix_length_and_dec();
enum Item_result result_type () const { return last_value->result_type(); } enum Item_result result_type () const { return last_value->result_type(); }
const char *func_name() const { return "last_value"; } const char *func_name() const { return "last_value"; }
table_map not_null_tables() const { return 0; } bool eval_not_null_tables(uchar *opt_arg)
{
not_null_tables_cache= 0;
return 0;
}
enum_field_types field_type() const { return last_value->field_type(); } enum_field_types field_type() const { return last_value->field_type(); }
bool const_item() const { return 0; } bool const_item() const { return 0; }
void evaluate_sideeffects(); void evaluate_sideeffects();
......
...@@ -316,7 +316,8 @@ bool Item_subselect::enumerate_field_refs_processor(uchar *arg) ...@@ -316,7 +316,8 @@ bool Item_subselect::enumerate_field_refs_processor(uchar *arg)
while ((upper= it++)) while ((upper= it++))
{ {
if (upper->item->walk(&Item::enumerate_field_refs_processor, FALSE, arg)) if (upper->item &&
upper->item->walk(&Item::enumerate_field_refs_processor, FALSE, arg))
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
...@@ -1366,7 +1367,7 @@ Item_in_subselect::Item_in_subselect(Item * left_exp, ...@@ -1366,7 +1367,7 @@ Item_in_subselect::Item_in_subselect(Item * left_exp,
Item_exists_subselect(), Item_exists_subselect(),
left_expr_cache(0), first_execution(TRUE), in_strategy(SUBS_NOT_TRANSFORMED), left_expr_cache(0), first_execution(TRUE), in_strategy(SUBS_NOT_TRANSFORMED),
optimizer(0), pushed_cond_guards(NULL), emb_on_expr_nest(NULL), optimizer(0), pushed_cond_guards(NULL), emb_on_expr_nest(NULL),
is_jtbm_merged(FALSE), is_jtbm_const_tab(FALSE), do_not_convert_to_sj(FALSE), is_jtbm_merged(FALSE), is_jtbm_const_tab(FALSE),
is_flattenable_semijoin(FALSE), is_flattenable_semijoin(FALSE),
is_registered_semijoin(FALSE), is_registered_semijoin(FALSE),
upper_item(0) upper_item(0)
...@@ -2493,6 +2494,27 @@ bool Item_in_subselect::inject_in_to_exists_cond(JOIN *join_arg) ...@@ -2493,6 +2494,27 @@ bool Item_in_subselect::inject_in_to_exists_cond(JOIN *join_arg)
DBUG_ENTER("Item_in_subselect::inject_in_to_exists_cond"); DBUG_ENTER("Item_in_subselect::inject_in_to_exists_cond");
DBUG_ASSERT(thd == join_arg->thd); DBUG_ASSERT(thd == join_arg->thd);
if (select_lex->min_max_opt_list.elements)
{
/*
MIN/MAX optimizations have been applied to Item_sum objects
of the subquery this subquery predicate in opt_sum_query().
Injection of new condition invalidates this optimizations.
Thus those optimizations must be rolled back.
*/
List_iterator_fast<Item_sum> it(select_lex->min_max_opt_list);
Item_sum *item;
while ((item= it++))
{
item->clear();
item->reset_forced_const();
}
if (where_item)
where_item->update_used_tables();
if (having_item)
having_item->update_used_tables();
}
if (where_item) if (where_item)
{ {
List<Item> *and_args= NULL; List<Item> *and_args= NULL;
...@@ -2850,7 +2872,8 @@ bool Item_in_subselect::init_cond_guards() ...@@ -2850,7 +2872,8 @@ bool Item_in_subselect::init_cond_guards()
{ {
DBUG_ASSERT(thd); DBUG_ASSERT(thd);
uint cols_num= left_expr->cols(); uint cols_num= left_expr->cols();
if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards) if (!abort_on_null && !pushed_cond_guards &&
(left_expr->maybe_null || cols_num > 1))
{ {
if (!(pushed_cond_guards= (bool*)thd->alloc(sizeof(bool) * cols_num))) if (!(pushed_cond_guards= (bool*)thd->alloc(sizeof(bool) * cols_num)))
return TRUE; return TRUE;
......
...@@ -466,6 +466,8 @@ class Item_in_subselect :public Item_exists_subselect ...@@ -466,6 +466,8 @@ class Item_in_subselect :public Item_exists_subselect
NULL - for all other locations NULL - for all other locations
*/ */
TABLE_LIST *emb_on_expr_nest; TABLE_LIST *emb_on_expr_nest;
/* May be TRUE only for the candidates to semi-join conversion */
bool do_not_convert_to_sj;
/* /*
Types of left_expr and subquery's select list allow to perform subquery Types of left_expr and subquery's select list allow to perform subquery
materialization. Currently, we set this to FALSE when it as well could materialization. Currently, we set this to FALSE when it as well could
...@@ -555,8 +557,8 @@ class Item_in_subselect :public Item_exists_subselect ...@@ -555,8 +557,8 @@ class Item_in_subselect :public Item_exists_subselect
:Item_exists_subselect(), left_expr_cache(0), first_execution(TRUE), :Item_exists_subselect(), left_expr_cache(0), first_execution(TRUE),
abort_on_null(0), in_strategy(SUBS_NOT_TRANSFORMED), optimizer(0), abort_on_null(0), in_strategy(SUBS_NOT_TRANSFORMED), optimizer(0),
pushed_cond_guards(NULL), func(NULL), emb_on_expr_nest(NULL), pushed_cond_guards(NULL), func(NULL), emb_on_expr_nest(NULL),
is_jtbm_merged(FALSE), is_jtbm_const_tab(FALSE), do_not_convert_to_sj(FALSE), is_jtbm_merged(FALSE),
upper_item(0) is_jtbm_const_tab(FALSE), upper_item(0)
{} {}
void cleanup(); void cleanup();
subs_type substype() { return IN_SUBS; } subs_type substype() { return IN_SUBS; }
...@@ -617,6 +619,8 @@ class Item_in_subselect :public Item_exists_subselect ...@@ -617,6 +619,8 @@ class Item_in_subselect :public Item_exists_subselect
emb_on_expr_nest= embedding; emb_on_expr_nest= embedding;
} }
void block_conversion_to_sj () { do_not_convert_to_sj= TRUE; }
bool test_strategy(uchar strategy) bool test_strategy(uchar strategy)
{ return test(in_strategy & strategy); } { return test(in_strategy & strategy); }
......
...@@ -454,6 +454,7 @@ class Item_sum :public Item_result_field ...@@ -454,6 +454,7 @@ class Item_sum :public Item_result_field
used_tables_cache= 0; used_tables_cache= 0;
forced_const= TRUE; forced_const= TRUE;
} }
void reset_forced_const() { forced_const= FALSE; }
virtual bool const_item() const { return forced_const; } virtual bool const_item() const { return forced_const; }
virtual bool const_during_execution() const { return false; } virtual bool const_during_execution() const { return false; }
virtual void print(String *str, enum_query_type query_type); virtual void print(String *str, enum_query_type query_type);
......
...@@ -3041,7 +3041,7 @@ get_date_time_result_type(const char *format, uint length) ...@@ -3041,7 +3041,7 @@ get_date_time_result_type(const char *format, uint length)
const char *val= format; const char *val= format;
const char *end= format + length; const char *end= format + length;
for (; val != end && val != end; val++) for (; val != end; val++)
{ {
if (*val == '%' && val+1 != end) if (*val == '%' && val+1 != end)
{ {
......
...@@ -4887,14 +4887,21 @@ int THD::binlog_write_table_map(TABLE *table, bool is_transactional, ...@@ -4887,14 +4887,21 @@ int THD::binlog_write_table_map(TABLE *table, bool is_transactional,
IO_CACHE *file= IO_CACHE *file=
cache_mngr->get_binlog_cache_log(use_trans_cache(this, is_transactional)); cache_mngr->get_binlog_cache_log(use_trans_cache(this, is_transactional));
binlog_cache_data *cache_data=
cache_mngr->get_binlog_cache_data(use_trans_cache(this, is_transactional));
if (with_annotate && *with_annotate) if (with_annotate && *with_annotate)
{ {
Annotate_rows_log_event anno(current_thd, is_transactional, false); Annotate_rows_log_event anno(current_thd, is_transactional, false);
/* Annotate event should be written not more than once */ /* Annotate event should be written not more than once */
*with_annotate= 0; *with_annotate= 0;
if ((error= anno.write(file))) if ((error= anno.write(file)))
{
if (my_errno == EFBIG)
cache_data->set_incident();
DBUG_RETURN(error); DBUG_RETURN(error);
} }
}
if ((error= the_event.write(file))) if ((error= the_event.write(file)))
DBUG_RETURN(error); DBUG_RETURN(error);
......
/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. /* Copyright (c) 2000, 2016, Oracle and/or its affiliates.
Copyright (c) 2012, 2016, MariaDB Copyright (c) 2012, 2017, MariaDB Corporation
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
......
...@@ -678,6 +678,7 @@ int check_and_do_in_subquery_rewrites(JOIN *join) ...@@ -678,6 +678,7 @@ int check_and_do_in_subquery_rewrites(JOIN *join)
!((join->select_options | // 10 !((join->select_options | // 10
select_lex->outer_select()->join->select_options) // 10 select_lex->outer_select()->join->select_options) // 10
& SELECT_STRAIGHT_JOIN)) // 10 & SELECT_STRAIGHT_JOIN)) // 10
{ {
DBUG_PRINT("info", ("Subquery is semi-join conversion candidate")); DBUG_PRINT("info", ("Subquery is semi-join conversion candidate"));
...@@ -1000,6 +1001,25 @@ bool check_for_outer_joins(List<TABLE_LIST> *join_list) ...@@ -1000,6 +1001,25 @@ bool check_for_outer_joins(List<TABLE_LIST> *join_list)
} }
void find_and_block_conversion_to_sj(Item *to_find,
List_iterator_fast<Item_in_subselect> &li)
{
if (to_find->type() != Item::SUBSELECT_ITEM ||
((Item_subselect *) to_find)->substype() != Item_subselect::IN_SUBS)
return;
Item_in_subselect *in_subq;
li.rewind();
while ((in_subq= li++))
{
if (in_subq == to_find)
{
in_subq->block_conversion_to_sj();
return;
}
}
}
/* /*
Convert semi-join subquery predicates into semi-join join nests Convert semi-join subquery predicates into semi-join join nests
...@@ -1052,7 +1072,6 @@ bool convert_join_subqueries_to_semijoins(JOIN *join) ...@@ -1052,7 +1072,6 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
Query_arena *arena, backup; Query_arena *arena, backup;
Item_in_subselect *in_subq; Item_in_subselect *in_subq;
THD *thd= join->thd; THD *thd= join->thd;
List_iterator<TABLE_LIST> ti(join->select_lex->leaf_tables);
DBUG_ENTER("convert_join_subqueries_to_semijoins"); DBUG_ENTER("convert_join_subqueries_to_semijoins");
if (join->select_lex->sj_subselects.is_empty()) if (join->select_lex->sj_subselects.is_empty())
...@@ -1070,6 +1089,89 @@ bool convert_join_subqueries_to_semijoins(JOIN *join) ...@@ -1070,6 +1089,89 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
subq_sel->update_used_tables(); subq_sel->update_used_tables();
} }
/*
Check all candidates to semi-join conversion that occur
in ON expressions of outer join. Set the flag blocking
this conversion for them.
*/
TABLE_LIST *tbl;
List_iterator<TABLE_LIST> ti(join->select_lex->leaf_tables);
while ((tbl= ti++))
{
TABLE_LIST *embedded;
TABLE_LIST *embedding= tbl;
do
{
embedded= embedding;
bool block_conversion_to_sj= false;
if (embedded->on_expr)
{
/*
Conversion of an IN subquery predicate into semi-join
is blocked now if the predicate occurs:
- in the ON expression of an outer join
- in the ON expression of an inner join embedded directly
or indirectly in the inner nest of an outer join
*/
for (TABLE_LIST *tl= embedded; tl; tl= tl->embedding)
{
if (tl->outer_join)
{
block_conversion_to_sj= true;
break;
}
}
}
if (block_conversion_to_sj)
{
Item *cond= embedded->on_expr;
if (!cond)
;
else if (cond->type() != Item::COND_ITEM)
find_and_block_conversion_to_sj(cond, li);
else if (((Item_cond*) cond)->functype() ==
Item_func::COND_AND_FUNC)
{
Item *item;
List_iterator<Item> it(*(((Item_cond*) cond)->argument_list()));
while ((item= it++))
{
find_and_block_conversion_to_sj(item, li);
}
}
}
embedding= embedded->embedding;
}
while (embedding &&
embedding->nested_join->join_list.head() == embedded);
}
/*
Block conversion to semi-joins for those candidates that
are encountered in the WHERE condition of the multi-table view
with CHECK OPTION if this view is used in UPDATE/DELETE.
(This limitation can be, probably, easily lifted.)
*/
li.rewind();
while ((in_subq= li++))
{
if (in_subq->emb_on_expr_nest != NO_JOIN_NEST &&
in_subq->emb_on_expr_nest->effective_with_check)
{
in_subq->block_conversion_to_sj();
}
}
if (join->select_options & SELECT_STRAIGHT_JOIN)
{
/* Block conversion to semijoins for all candidates */
li.rewind();
while ((in_subq= li++))
{
in_subq->block_conversion_to_sj();
}
}
li.rewind(); li.rewind();
/* First, convert child join's subqueries. We proceed bottom-up here */ /* First, convert child join's subqueries. We proceed bottom-up here */
while ((in_subq= li++)) while ((in_subq= li++))
...@@ -1088,8 +1190,10 @@ bool convert_join_subqueries_to_semijoins(JOIN *join) ...@@ -1088,8 +1190,10 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
if (convert_join_subqueries_to_semijoins(child_join)) if (convert_join_subqueries_to_semijoins(child_join))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
in_subq->sj_convert_priority= in_subq->sj_convert_priority=
test(in_subq->emb_on_expr_nest != NO_JOIN_NEST) * MAX_TABLES * 2 + test(in_subq->do_not_convert_to_sj) * MAX_TABLES * 2 +
in_subq->is_correlated * MAX_TABLES + child_join->outer_tables; in_subq->is_correlated * MAX_TABLES + child_join->outer_tables;
} }
...@@ -1122,7 +1226,7 @@ bool convert_join_subqueries_to_semijoins(JOIN *join) ...@@ -1122,7 +1226,7 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
bool remove_item= TRUE; bool remove_item= TRUE;
/* Stop processing if we've reached a subquery that's attached to the ON clause */ /* Stop processing if we've reached a subquery that's attached to the ON clause */
if (in_subq->emb_on_expr_nest != NO_JOIN_NEST) if (in_subq->do_not_convert_to_sj)
break; break;
if (in_subq->is_flattenable_semijoin) if (in_subq->is_flattenable_semijoin)
...@@ -3325,6 +3429,7 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join) ...@@ -3325,6 +3429,7 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
table_map remaining_tables= 0; table_map remaining_tables= 0;
table_map handled_tabs= 0; table_map handled_tabs= 0;
join->sjm_lookup_tables= 0; join->sjm_lookup_tables= 0;
join->sjm_scan_tables= 0;
for (tablenr= table_count - 1 ; tablenr != join->const_tables - 1; tablenr--) for (tablenr= table_count - 1 ; tablenr != join->const_tables - 1; tablenr--)
{ {
POSITION *pos= join->best_positions + tablenr; POSITION *pos= join->best_positions + tablenr;
...@@ -3383,6 +3488,9 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join) ...@@ -3383,6 +3488,9 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
for (i= tablenr; i != (first + sjm->tables - 1); i--) for (i= tablenr; i != (first + sjm->tables - 1); i--)
rem_tables |= join->best_positions[i].table->table->map; rem_tables |= join->best_positions[i].table->table->map;
for (i= first; i < first+ sjm->tables; i++)
join->sjm_scan_tables |= join->best_positions[i].table->table->map;
POSITION dummy; POSITION dummy;
join->cur_sj_inner_tables= 0; join->cur_sj_inner_tables= 0;
for (i= first + sjm->tables; i <= tablenr; i++) for (i= first + sjm->tables; i <= tablenr; i++)
......
...@@ -253,6 +253,8 @@ int opt_sum_query(THD *thd, ...@@ -253,6 +253,8 @@ int opt_sum_query(THD *thd,
int error= 0; int error= 0;
DBUG_ENTER("opt_sum_query"); DBUG_ENTER("opt_sum_query");
thd->lex->current_select->min_max_opt_list.empty();
if (conds) if (conds)
where_tables= conds->used_tables(); where_tables= conds->used_tables();
...@@ -444,7 +446,14 @@ int opt_sum_query(THD *thd, ...@@ -444,7 +446,14 @@ int opt_sum_query(THD *thd,
item_sum->aggregator_clear(); item_sum->aggregator_clear();
} }
else else
{
item_sum->reset_and_add(); item_sum->reset_and_add();
/*
Save a reference to the item for possible rollback
of the min/max optimizations for this select
*/
thd->lex->current_select->min_max_opt_list.push_back(item_sum);
}
item_sum->make_const(); item_sum->make_const();
recalc_const_item= 1; recalc_const_item= 1;
break; break;
......
/* /*
Copyright (c) 2000, 2010, Oracle and/or its affiliates. Copyright (c) 2000, 2010, Oracle and/or its affiliates.
Copyright (c) 2009, 2017, MariaDB Corporation
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment