summaryrefslogtreecommitdiff
path: root/sql/create_options.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/create_options.cc')
-rw-r--r--sql/create_options.cc113
1 files changed, 95 insertions, 18 deletions
diff --git a/sql/create_options.cc b/sql/create_options.cc
index 5437de0f0c3..cea5d7af950 100644
--- a/sql/create_options.cc
+++ b/sql/create_options.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2010, 2020, MariaDB Corporation.
+/* Copyright (C) 2010, 2020, 2021, 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
@@ -21,6 +21,7 @@
#include "mariadb.h"
#include "create_options.h"
+#include "partition_info.h"
#include <my_getopt.h>
#include "set_var.h"
@@ -339,8 +340,11 @@ bool parse_option_list(THD* thd, handlerton *hton, void *option_struct_arg,
LEX_CSTRING name= { opt->name, opt->name_length };
default_val.str= strmake_root(root, str->ptr(), str->length());
default_val.length= str->length();
- val= new (root) engine_option_value(name, default_val,
- opt->type != HA_OPTION_TYPE_ULL, option_list, &last);
+ val= new (root) engine_option_value(
+ name, default_val, opt->type != HA_OPTION_TYPE_ULL);
+ if (!val)
+ DBUG_RETURN(TRUE);
+ val->link(option_list, &last);
val->parsed= true;
}
}
@@ -497,6 +501,61 @@ bool parse_engine_table_options(THD *thd, handlerton *ht, TABLE_SHARE *share)
DBUG_RETURN(FALSE);
}
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+/**
+ Parses engine-defined partition options
+
+ @param [in] thd thread handler
+ @parem [in] table table with part_info
+
+ @retval TRUE Error
+ @retval FALSE OK
+
+ In the case of ALTER TABLE statements, table->part_info is set up
+ by mysql_unpack_partition(). So, one should not call the present
+ function before the call of mysql_unpack_partition().
+*/
+bool parse_engine_part_options(THD *thd, TABLE *table)
+{
+ MEM_ROOT *root= &table->mem_root;
+ TABLE_SHARE *share= table->s;
+ partition_info *part_info= table->part_info;
+ engine_option_value *tmp_option_list;
+ handlerton *ht;
+ DBUG_ENTER("parse_engine_part_options");
+
+ if (!part_info)
+ DBUG_RETURN(FALSE);
+
+ List_iterator<partition_element> it(part_info->partitions);
+ while (partition_element *part_elem= it++)
+ {
+ if (merge_engine_options(share->option_list, part_elem->option_list,
+ &tmp_option_list, root))
+ DBUG_RETURN(TRUE);
+
+ if (!part_info->is_sub_partitioned())
+ {
+ ht= part_elem->engine_type;
+ if (parse_option_list(thd, ht, &part_elem->option_struct,
+ &tmp_option_list, ht->table_options, TRUE, root))
+ DBUG_RETURN(TRUE);
+ }
+ else
+ {
+ List_iterator<partition_element> sub_it(part_elem->subpartitions);
+ while (partition_element *sub_part_elem= sub_it++)
+ {
+ ht= sub_part_elem->engine_type;
+ if (parse_option_list(thd, ht, &sub_part_elem->option_struct,
+ &tmp_option_list, ht->table_options, TRUE, root))
+ DBUG_RETURN(TRUE);
+ }
+ }
+ }
+ DBUG_RETURN(FALSE);
+}
+#endif
bool engine_options_differ(void *old_struct, void *new_struct,
ha_create_table_option *rules)
@@ -694,10 +753,11 @@ uchar *engine_option_value::frm_read(const uchar *buff, const uchar *buff_end,
return NULL;
buff+= value.length;
- engine_option_value *ptr=new (root)
- engine_option_value(name, value, len & FRM_QUOTED_VALUE, start, end);
+ engine_option_value *ptr=
+ new (root) engine_option_value(name, value, len & FRM_QUOTED_VALUE);
if (!ptr)
return NULL;
+ ptr->link(start, end);
return (uchar *)buff;
}
@@ -766,23 +826,40 @@ bool engine_table_options_frm_read(const uchar *buff, size_t length,
/**
Merges two lists of engine_option_value's with duplicate removal.
-*/
-engine_option_value *merge_engine_table_options(engine_option_value *first,
- engine_option_value *second,
- MEM_ROOT *root)
+ @param [in] source option list
+ @param [in] changes option list whose options overwrite source's
+ @param [out] out new option list created by merging given two
+ @param [in] root MEM_ROOT for allocating memory
+
+ @retval TRUE Error
+ @retval FALSE OK
+*/
+bool merge_engine_options(engine_option_value *source,
+ engine_option_value *changes,
+ engine_option_value **out, MEM_ROOT *root)
{
- engine_option_value *UNINIT_VAR(end), *opt;
- DBUG_ENTER("merge_engine_table_options");
+ engine_option_value *UNINIT_VAR(end), *opt, *opt_copy;
+ *out= 0;
+ DBUG_ENTER("merge_engine_options");
- /* Create copy of first list */
- for (opt= first, first= 0; opt; opt= opt->next)
- new (root) engine_option_value(opt, &first, &end);
+ /* Create copy of source list */
+ for (opt= source; opt; opt= opt->next)
+ {
+ opt_copy= new (root) engine_option_value(opt);
+ if (!opt_copy)
+ DBUG_RETURN(TRUE);
+ opt_copy->link(out, &end);
+ }
- for (opt= second; opt; opt= opt->next)
- new (root) engine_option_value(opt->name, opt->value, opt->quoted_value,
- &first, &end);
- DBUG_RETURN(first);
+ for (opt= changes; opt; opt= opt->next)
+ {
+ opt_copy= new (root) engine_option_value(opt);
+ if (!opt_copy)
+ DBUG_RETURN(TRUE);
+ opt_copy->link(out, &end);
+ }
+ DBUG_RETURN(FALSE);
}
bool is_engine_option_known(engine_option_value *opt,