mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
BUG#16613004 PARTITIONING DDL, CRASH IN FIELD_VARSTRING::CMP_MAX
Problem : --------- The specific issue reported in this bug is with range/list column value that is allocated and initialized by evaluating partition expression(item tree) during execution. After evaluation the range list value is marked fixed [part_column_list_val]. During next execution, we don't re-evaluate the expression and use the old value since it is marked fixed. Solution : ---------- One way to solve the issue is to mark all column values as not fixed during clone so that the expression is always re-evaluated once we attempt partition_info::fix_column_value_functions() after cloning the part_info object during execution of DDL on partitioned table. Reviewed-by: Jimmy Yang <Jimmy.Yang@oracle.com> Reviewed-by: Mattias Jonsson <mattias.jonsson@oracle.com> RB: 9424
This commit is contained in:
@ -31,7 +31,7 @@
|
|||||||
#include "ha_partition.h"
|
#include "ha_partition.h"
|
||||||
|
|
||||||
|
|
||||||
partition_info *partition_info::get_clone()
|
partition_info *partition_info::get_clone(bool reset /* = false */)
|
||||||
{
|
{
|
||||||
if (!this)
|
if (!this)
|
||||||
return 0;
|
return 0;
|
||||||
@ -57,6 +57,26 @@ partition_info *partition_info::get_clone()
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
memcpy(part_clone, part, sizeof(partition_element));
|
memcpy(part_clone, part, sizeof(partition_element));
|
||||||
|
|
||||||
|
/*
|
||||||
|
Mark that RANGE and LIST values needs to be fixed so that we don't
|
||||||
|
use old values. fix_column_value_functions would evaluate the values
|
||||||
|
from Item expression.
|
||||||
|
*/
|
||||||
|
if (reset)
|
||||||
|
{
|
||||||
|
clone->defined_max_value = false;
|
||||||
|
List_iterator<part_elem_value> list_it(part_clone->list_val_list);
|
||||||
|
while (part_elem_value *list_value= list_it++)
|
||||||
|
{
|
||||||
|
part_column_list_val *col_val= list_value->col_val_array;
|
||||||
|
for (uint i= 0; i < num_columns; col_val++, i++)
|
||||||
|
{
|
||||||
|
col_val->fixed= 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
part_clone->subpartitions.empty();
|
part_clone->subpartitions.empty();
|
||||||
while ((subpart= (subpart_it++)))
|
while ((subpart= (subpart_it++)))
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef PARTITION_INFO_INCLUDED
|
#ifndef PARTITION_INFO_INCLUDED
|
||||||
#define PARTITION_INFO_INCLUDED
|
#define PARTITION_INFO_INCLUDED
|
||||||
|
|
||||||
/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
|
/* Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -265,7 +265,7 @@ public:
|
|||||||
}
|
}
|
||||||
~partition_info() {}
|
~partition_info() {}
|
||||||
|
|
||||||
partition_info *get_clone();
|
partition_info *get_clone(bool reset = false);
|
||||||
/* Answers the question if subpartitioning is used for a certain table */
|
/* Answers the question if subpartitioning is used for a certain table */
|
||||||
bool is_sub_partitioned()
|
bool is_sub_partitioned()
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
|
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -2428,7 +2428,7 @@ case SQLCOM_PREPARE:
|
|||||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||||
{
|
{
|
||||||
partition_info *part_info= thd->lex->part_info;
|
partition_info *part_info= thd->lex->part_info;
|
||||||
if (part_info && !(part_info= thd->lex->part_info->get_clone()))
|
if (part_info && !(part_info= thd->lex->part_info->get_clone(true)))
|
||||||
{
|
{
|
||||||
res= -1;
|
res= -1;
|
||||||
goto end_with_restore_list;
|
goto end_with_restore_list;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
|
/* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -4718,7 +4718,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
|
|||||||
thd->work_part_info= thd->lex->part_info;
|
thd->work_part_info= thd->lex->part_info;
|
||||||
|
|
||||||
if (thd->work_part_info &&
|
if (thd->work_part_info &&
|
||||||
!(thd->work_part_info= thd->lex->part_info->get_clone()))
|
!(thd->work_part_info= thd->lex->part_info->get_clone(true)))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
/* ALTER_ADMIN_PARTITION is handled in mysql_admin_table */
|
/* ALTER_ADMIN_PARTITION is handled in mysql_admin_table */
|
||||||
|
Reference in New Issue
Block a user