summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/derived_handler.cc5
-rw-r--r--sql/field.h21
-rw-r--r--sql/ha_partition.cc29
-rw-r--r--sql/ha_partition.h12
-rw-r--r--sql/handler.cc9
-rw-r--r--sql/handler.h14
-rw-r--r--sql/mysqld.cc4
-rw-r--r--sql/partition_info.h5
-rw-r--r--sql/share/errmsg-utf8.txt6
-rw-r--r--sql/sql_derived.cc5
-rw-r--r--sql/sql_lex.cc4
-rw-r--r--sql/sql_partition.cc122
-rw-r--r--sql/sql_select.cc34
-rw-r--r--sql/sql_select.h3
-rw-r--r--sql/sql_table.cc2
-rw-r--r--sql/sql_type_geom.h8
16 files changed, 142 insertions, 141 deletions
diff --git a/sql/derived_handler.cc b/sql/derived_handler.cc
index f48b95cbf76..70cc04bf9c7 100644
--- a/sql/derived_handler.cc
+++ b/sql/derived_handler.cc
@@ -44,11 +44,6 @@ Pushdown_derived::Pushdown_derived(TABLE_LIST *tbl, derived_handler *h)
}
-Pushdown_derived::~Pushdown_derived()
-{
- delete handler;
-}
-
int Pushdown_derived::execute()
{
diff --git a/sql/field.h b/sql/field.h
index ace51b792ad..feed7206678 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1775,12 +1775,6 @@ public:
Used by the ALTER TABLE
*/
virtual bool is_equal(const Column_definition &new_field) const= 0;
- // Used as double dispatch pattern: calls virtual method of handler
- virtual bool
- can_be_converted_by_engine(const Column_definition &new_type) const
- {
- return false;
- }
/* convert decimal to longlong with overflow check */
longlong convert_decimal2longlong(const my_decimal *val, bool unsigned_flag,
int *err);
@@ -4070,11 +4064,6 @@ public:
void sql_type(String &str) const override;
void sql_rpl_type(String*) const override;
bool is_equal(const Column_definition &new_field) const override;
- bool can_be_converted_by_engine(const Column_definition &new_type) const
- override
- {
- return table->file->can_convert_string(this, new_type);
- }
uchar *pack(uchar *to, const uchar *from, uint max_length) override;
const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end,
uint param_data) override;
@@ -4229,11 +4218,6 @@ public:
uchar *new_ptr, uint32 length,
uchar *new_null_ptr, uint new_null_bit) override;
bool is_equal(const Column_definition &new_field) const override;
- bool can_be_converted_by_engine(const Column_definition &new_type) const
- override
- {
- return table->file->can_convert_varstring(this, new_type);
- }
void hash(ulong *nr, ulong *nr2) override;
uint length_size() const override { return length_bytes; }
void print_key_value(String *out, uint32 length) override;
@@ -4672,11 +4656,6 @@ public:
uint32 char_length() const override;
uint32 character_octet_length() const override;
bool is_equal(const Column_definition &new_field) const override;
- bool can_be_converted_by_engine(const Column_definition &new_type) const
- override
- {
- return table->file->can_convert_blob(this, new_type);
- }
void print_key_value(String *out, uint32 length) override;
Binlog_type_info binlog_type_info() const override;
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index d91c4dee8b1..063a65a6ee1 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -12130,35 +12130,12 @@ int ha_partition::info_push(uint info_type, void *info)
bool
-ha_partition::can_convert_string(const Field_string* field,
- const Column_definition& new_type) const
+ha_partition::can_convert_nocopy(const Field &field,
+ const Column_definition &new_type) const
{
for (uint index= 0; index < m_tot_parts; index++)
{
- if (!m_file[index]->can_convert_string(field, new_type))
- return false;
- }
- return true;
-}
-
-bool
-ha_partition::can_convert_varstring(const Field_varstring* field,
- const Column_definition& new_type) const{
- for (uint index= 0; index < m_tot_parts; index++)
- {
- if (!m_file[index]->can_convert_varstring(field, new_type))
- return false;
- }
- return true;
-}
-
-bool
-ha_partition::can_convert_blob(const Field_blob* field,
- const Column_definition& new_type) const
-{
- for (uint index= 0; index < m_tot_parts; index++)
- {
- if (!m_file[index]->can_convert_blob(field, new_type))
+ if (!m_file[index]->can_convert_nocopy(field, new_type))
return false;
}
return true;
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index 4a4b899708e..437280d6d5d 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -1629,16 +1629,8 @@ public:
friend int cmp_key_rowid_part_id(void *ptr, uchar *ref1, uchar *ref2);
friend int cmp_key_part_id(void *key_p, uchar *ref1, uchar *ref2);
- bool can_convert_string(
- const Field_string* field,
- const Column_definition& new_field) const override;
- bool can_convert_varstring(
- const Field_varstring* field,
- const Column_definition& new_field) const override;
-
- bool can_convert_blob(
- const Field_blob* field,
- const Column_definition& new_field) const override;
+ bool can_convert_nocopy(const Field &field,
+ const Column_definition &new_field) const override;
};
#endif /* HA_PARTITION_INCLUDED */
diff --git a/sql/handler.cc b/sql/handler.cc
index 577d6ef9e26..90e3b20e3fb 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -7320,8 +7320,13 @@ int handler::check_duplicate_long_entries_update(const uchar *new_rec)
{
int error;
field= keypart->field;
- /* Compare fields if they are different then check for duplicates */
- if (field->cmp_binary_offset(reclength))
+ /*
+ Compare fields if they are different then check for duplicates
+ cmp_binary_offset cannot differentiate between null and empty string
+ So also check for that too
+ */
+ if((field->is_null(0) != field->is_null(reclength)) ||
+ field->cmp_binary_offset(reclength))
{
if((error= check_duplicate_long_entry_key(new_rec, i)))
return error;
diff --git a/sql/handler.h b/sql/handler.h
index ed24f160385..ad18ad8b9e4 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -5097,18 +5097,8 @@ public:
These functions check for such possibility.
Implementation could be based on Field_xxx::is_equal()
*/
- virtual bool can_convert_string(const Field_string *field,
- const Column_definition &new_type) const
- {
- return false;
- }
- virtual bool can_convert_varstring(const Field_varstring *field,
- const Column_definition &new_type) const
- {
- return false;
- }
- virtual bool can_convert_blob(const Field_blob *field,
- const Column_definition &new_type) const
+ virtual bool can_convert_nocopy(const Field &,
+ const Column_definition &) const
{
return false;
}
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 1722b1e188a..c25ae883e74 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -4125,8 +4125,8 @@ static int init_common_variables()
files= my_set_max_open_files(max_open_files);
SYSVAR_AUTOSIZE_IF_CHANGED(open_files_limit, files, ulong);
- if (files < wanted_files && global_system_variables.log_warnings)
- sql_print_warning("Could not increase number of max_open_files to more than %u (request: %u)", files, wanted_files);
+ if (files < max_open_files && global_system_variables.log_warnings)
+ sql_print_warning("Could not increase number of max_open_files to more than %u (request: %u)", files, max_open_files);
/* If we required too much tc_instances than we reduce */
SYSVAR_AUTOSIZE_IF_CHANGED(tc_instances,
diff --git a/sql/partition_info.h b/sql/partition_info.h
index e95daec7d31..287aa6d2200 100644
--- a/sql/partition_info.h
+++ b/sql/partition_info.h
@@ -429,8 +429,13 @@ public:
return NULL;
}
uint next_part_no(uint new_parts) const;
+
+ int gen_part_type(THD *thd, String *str) const;
};
+void part_type_error(THD *thd, partition_info *work_part_info,
+ const char *part_type, partition_info *tab_part_info);
+
uint32 get_next_partition_id_range(struct st_partition_iter* part_iter);
bool check_partition_dirs(partition_info *part_info);
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index 4c7f71f4718..de5117e0246 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -9773,9 +9773,9 @@ ER_UNUSED_23
spa "Nunca debería vd de ver esto"
ER_PARTITION_WRONG_TYPE
- chi "错误的分区类型,预期类型:%`s"
- eng "Wrong partitioning type, expected type: %`s"
- spa "Tipo de partición equivocada, tipo esperado: %`s"
+ chi "错误的分区类型,预期类型:%`s for partitioning by %`s"
+ eng "Wrong partition type %`s for partitioning by %`s"
+ spa "Tipo de partición equivocada, tipo esperado: %`s for partitioning by %`s"
WARN_VERS_PART_FULL
chi "版本化表%`s.%`s:partition%`s已满,添加更多历史分区(out of %s)"
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index 579ea34b8e4..6f0857239dd 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -1016,11 +1016,7 @@ bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived)
/* Create an object for execution of the query specifying the table */
if (!(derived->pushdown_derived=
new (thd->mem_root) Pushdown_derived(derived, derived->dt_handler)))
- {
- delete derived->dt_handler;
- derived->dt_handler= NULL;
DBUG_RETURN(TRUE);
- }
}
lex->current_select= first_select;
@@ -1245,7 +1241,6 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
/* Execute the query that specifies the derived table by a foreign engine */
res= derived->pushdown_derived->execute();
unit->executed= true;
- delete derived->pushdown_derived;
DBUG_RETURN(res);
}
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 57f7cfac595..b81ace9a2cc 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -9761,7 +9761,7 @@ bool LEX::part_values_current(THD *thd)
{
if (unlikely(part_info->part_type != VERSIONING_PARTITION))
{
- my_error(ER_PARTITION_WRONG_TYPE, MYF(0), "SYSTEM_TIME");
+ part_type_error(thd, NULL, "CURRENT", part_info);
return true;
}
}
@@ -9788,7 +9788,7 @@ bool LEX::part_values_history(THD *thd)
{
if (unlikely(part_info->part_type != VERSIONING_PARTITION))
{
- my_error(ER_PARTITION_WRONG_TYPE, MYF(0), "SYSTEM_TIME");
+ part_type_error(thd, NULL, "HISTORY", part_info);
return true;
}
}
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 0db40c4f55c..9c7f25e8808 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -2470,7 +2470,7 @@ end:
@retval != 0 Failure
*/
-static int add_key_with_algorithm(String *str, partition_info *part_info)
+static int add_key_with_algorithm(String *str, const partition_info *part_info)
{
int err= 0;
err+= str->append(STRING_WITH_LEN("KEY "));
@@ -2499,6 +2499,78 @@ char *generate_partition_syntax_for_frm(THD *thd, partition_info *part_info,
return res;
}
+
+/*
+ Generate the partition type syntax from the partition data structure.
+
+ @return Operation status.
+ @retval 0 Success
+ @retval > 0 Failure
+ @retval -1 Fatal error
+*/
+
+int partition_info::gen_part_type(THD *thd, String *str) const
+{
+ int err= 0;
+ switch (part_type)
+ {
+ case RANGE_PARTITION:
+ err+= str->append(STRING_WITH_LEN("RANGE "));
+ break;
+ case LIST_PARTITION:
+ err+= str->append(STRING_WITH_LEN("LIST "));
+ break;
+ case HASH_PARTITION:
+ if (linear_hash_ind)
+ err+= str->append(STRING_WITH_LEN("LINEAR "));
+ if (list_of_part_fields)
+ {
+ err+= add_key_with_algorithm(str, this);
+ err+= add_part_field_list(thd, str, part_field_list);
+ }
+ else
+ err+= str->append(STRING_WITH_LEN("HASH "));
+ break;
+ case VERSIONING_PARTITION:
+ err+= str->append(STRING_WITH_LEN("SYSTEM_TIME "));
+ break;
+ default:
+ DBUG_ASSERT(0);
+ /* We really shouldn't get here, no use in continuing from here */
+ my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATAL));
+ return -1;
+ }
+ return err;
+}
+
+
+void part_type_error(THD *thd, partition_info *work_part_info,
+ const char *part_type,
+ partition_info *tab_part_info)
+{
+ StringBuffer<256> tab_part_type;
+ if (tab_part_info->gen_part_type(thd, &tab_part_type) < 0)
+ return;
+ tab_part_type.length(tab_part_type.length() - 1);
+ if (work_part_info)
+ {
+ DBUG_ASSERT(!part_type);
+ StringBuffer<256> work_part_type;
+ if (work_part_info->gen_part_type(thd, &work_part_type) < 0)
+ return;
+ work_part_type.length(work_part_type.length() - 1);
+ my_error(ER_PARTITION_WRONG_TYPE, MYF(0), work_part_type.c_ptr(),
+ tab_part_type.c_ptr());
+ }
+ else
+ {
+ DBUG_ASSERT(part_type);
+ my_error(ER_PARTITION_WRONG_TYPE, MYF(0), part_type,
+ tab_part_type.c_ptr());
+ }
+}
+
+
/*
Generate the partition syntax from the partition data structure.
Useful for support of generating defaults, SHOW CREATE TABLES
@@ -2542,34 +2614,10 @@ char *generate_partition_syntax(THD *thd, partition_info *part_info,
DBUG_ENTER("generate_partition_syntax");
err+= str.append(STRING_WITH_LEN(" PARTITION BY "));
- switch (part_info->part_type)
- {
- case RANGE_PARTITION:
- err+= str.append(STRING_WITH_LEN("RANGE "));
- break;
- case LIST_PARTITION:
- err+= str.append(STRING_WITH_LEN("LIST "));
- break;
- case HASH_PARTITION:
- if (part_info->linear_hash_ind)
- err+= str.append(STRING_WITH_LEN("LINEAR "));
- if (part_info->list_of_part_fields)
- {
- err+= add_key_with_algorithm(&str, part_info);
- err+= add_part_field_list(thd, &str, part_info->part_field_list);
- }
- else
- err+= str.append(STRING_WITH_LEN("HASH "));
- break;
- case VERSIONING_PARTITION:
- err+= str.append(STRING_WITH_LEN("SYSTEM_TIME "));
- break;
- default:
- DBUG_ASSERT(0);
- /* We really shouldn't get here, no use in continuing from here */
- my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATAL));
- DBUG_RETURN(NULL);
- }
+ int err2= part_info->gen_part_type(thd, &str);
+ if (err2 < 0)
+ DBUG_RETURN(NULL);
+ err+= err2;
if (part_info->part_type == VERSIONING_PARTITION)
{
Vers_part_info *vers_info= part_info->vers_info;
@@ -5027,6 +5075,13 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
if ((alter_info->partition_flags & ALTER_PARTITION_ADD) ||
(alter_info->partition_flags & ALTER_PARTITION_REORGANIZE))
{
+ if ((alter_info->partition_flags & ALTER_PARTITION_CONVERT_IN) &&
+ !(tab_part_info->part_type == RANGE_PARTITION ||
+ tab_part_info->part_type == LIST_PARTITION))
+ {
+ my_error(ER_ONLY_ON_RANGE_LIST_PARTITION, MYF(0), "CONVERT TABLE TO");
+ goto err;
+ }
if (thd->work_part_info->part_type != tab_part_info->part_type)
{
if (thd->work_part_info->part_type == NOT_A_PARTITION)
@@ -5062,7 +5117,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
else if (thd->work_part_info->part_type == VERSIONING_PARTITION ||
tab_part_info->part_type == VERSIONING_PARTITION)
{
- my_error(ER_PARTITION_WRONG_TYPE, MYF(0), "SYSTEM_TIME");
+ part_type_error(thd, thd->work_part_info, NULL, tab_part_info);
}
else
{
@@ -5096,13 +5151,6 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
}
if (alter_info->partition_flags & ALTER_PARTITION_ADD)
{
- if ((alter_info->partition_flags & ALTER_PARTITION_CONVERT_IN) &&
- !(tab_part_info->part_type == RANGE_PARTITION ||
- tab_part_info->part_type == LIST_PARTITION))
- {
- my_error(ER_ONLY_ON_RANGE_LIST_PARTITION, MYF(0), "CONVERT TABLE TO");
- goto err;
- }
if (*fast_alter_table && thd->locked_tables_mode)
{
MEM_ROOT *old_root= thd->mem_root;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index e8874a5ea78..f7861873192 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -67,6 +67,7 @@
#include "select_handler.h"
#include "my_json_writer.h"
#include "opt_trace.h"
+#include "derived_handler.h"
#include "create_tmp_table.h"
/*
@@ -14574,6 +14575,7 @@ void JOIN::cleanup(bool full)
}
}
}
+ free_pushdown_handlers(*join_list);
}
/* Restore ref array to original state */
if (current_ref_ptrs != items0)
@@ -14584,6 +14586,32 @@ void JOIN::cleanup(bool full)
DBUG_VOID_RETURN;
}
+/**
+ Clean up all derived pushdown handlers in this join.
+
+ @detail
+ Note that dt_handler is picked at the prepare stage (as opposed
+ to optimization stage where one could expect this).
+ Because of that, we have to do cleanups in this function that is called
+ from JOIN::cleanup() and not in JOIN_TAB::cleanup.
+ */
+void JOIN::free_pushdown_handlers(List<TABLE_LIST>& join_list)
+{
+ List_iterator<TABLE_LIST> li(join_list);
+ TABLE_LIST *table_ref;
+ while ((table_ref= li++))
+ {
+ if (table_ref->nested_join)
+ free_pushdown_handlers(table_ref->nested_join->join_list);
+ if (table_ref->pushdown_derived)
+ {
+ delete table_ref->pushdown_derived;
+ table_ref->pushdown_derived= NULL;
+ }
+ delete table_ref->dt_handler;
+ table_ref->dt_handler= NULL;
+ }
+}
/**
Remove the following expressions from ORDER BY and GROUP BY:
@@ -28065,12 +28093,6 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
result, unit, first);
}
- if (unit->derived && unit->derived->pushdown_derived)
- {
- delete unit->derived->pushdown_derived;
- unit->derived->pushdown_derived= NULL;
- }
-
DBUG_RETURN(res || thd->is_error());
}
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 5aa775f4a2d..c9e0fa25421 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -1791,6 +1791,7 @@ private:
bool add_having_as_table_cond(JOIN_TAB *tab);
bool make_aggr_tables_info();
bool add_fields_for_current_rowid(JOIN_TAB *cur, List<Item> *fields);
+ void free_pushdown_handlers(List<TABLE_LIST>& join_list);
void init_join_cache_and_keyread();
bool transform_in_predicates_into_equalities(THD *thd);
bool transform_all_conds_and_on_exprs(THD *thd,
@@ -2471,8 +2472,6 @@ public:
Pushdown_derived(TABLE_LIST *tbl, derived_handler *h);
- ~Pushdown_derived();
-
int execute();
};
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 7e35c17bb64..3cab075b944 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -6582,7 +6582,7 @@ static bool fill_alter_inplace_info(THD *thd, TABLE *table, bool varchar,
bool is_equal= field->is_equal(*new_field);
if (!is_equal)
{
- if (field->can_be_converted_by_engine(*new_field))
+ if (field->table->file->can_convert_nocopy(*field, *new_field))
{
/*
New column type differs from the old one, but storage engine can
diff --git a/sql/sql_type_geom.h b/sql/sql_type_geom.h
index a2bcd45e0e8..3bc25808bc3 100644
--- a/sql/sql_type_geom.h
+++ b/sql/sql_type_geom.h
@@ -2,7 +2,7 @@
#define SQL_TYPE_GEOM_H_INCLUDED
/*
Copyright (c) 2015 MariaDB Foundation
- Copyright (c) 2019 MariaDB
+ Copyright (c) 2019, 2022, MariaDB Corporation.
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
@@ -397,12 +397,6 @@ public:
!table->copy_blobs;
}
bool is_equal(const Column_definition &new_field) const override;
- bool can_be_converted_by_engine(const Column_definition &new_type)
- const override
- {
- return false; // Override the Field_blob behavior
- }
-
int store(const char *to, size_t length, CHARSET_INFO *charset) override;
int store(double nr) override;
int store(longlong nr, bool unsigned_val) override;