Skip to content

Commit 82bcf2f

Browse files
author
Martin Hansson
committed
Bug#27776973: SIMPLIFY MAKE_FIELD
Complements the 18-argument make_field() function with multiple specialized overloads that take fewer arguments Change-Id: I0544ea2332a032dcb8ad6cc4343bfe69e7c3bad0
1 parent 37cb705 commit 82bcf2f

9 files changed

+348
-218
lines changed

sql/dd/dd_table.cc

+4-17
Original file line numberDiff line numberDiff line change
@@ -219,12 +219,7 @@ dd::String_type get_sql_type_by_create_field(TABLE *table,
219219
Create_field *field) {
220220
DBUG_ENTER("get_sql_type_by_create_field");
221221

222-
// Create Field object from Create_field
223-
std::unique_ptr<Field, Destroy_only<Field>> fld(make_field(
224-
table->s, 0, field->length, NULL, 0, field->sql_type, field->charset,
225-
field->geom_type, field->auto_flags, field->interval, field->field_name,
226-
field->maybe_null, field->is_zerofill, field->is_unsigned,
227-
field->decimals, field->treat_bit_as_char, 0, field->m_srid));
222+
unique_ptr_destroy_only<Field> fld(make_field(*field, table->s));
228223
fld->init(table);
229224

230225
// Read column display type.
@@ -261,11 +256,8 @@ static void prepare_default_value_string(uchar *buf, TABLE *table,
261256
dd::Column *col_obj,
262257
String *def_value) {
263258
// Create a fake field with the default value buffer 'buf'.
264-
std::unique_ptr<Field, Destroy_only<Field>> f(make_field(
265-
table->s, buf + 1, field.length, buf, 0, field.sql_type, field.charset,
266-
field.geom_type, field.auto_flags, field.interval, field.field_name,
267-
field.maybe_null, field.is_zerofill, field.is_unsigned, field.decimals,
268-
field.treat_bit_as_char, 0, field.m_srid));
259+
unique_ptr_destroy_only<Field> f(
260+
make_field(field, table->s, buf + 1, buf, 0));
269261
f->init(table);
270262

271263
if (col_obj->has_no_default()) f->flags |= NO_DEFAULT_VALUE_FLAG;
@@ -906,12 +898,7 @@ static bool is_candidate_primary_key(THD *thd, KEY *key,
906898

907899
/* Prepare Field* object from Create_field */
908900

909-
std::unique_ptr<Field, Destroy_only<Field>> table_field(
910-
make_field(table.s, 0, cfield->length, nullptr, 0, cfield->sql_type,
911-
cfield->charset, cfield->geom_type, cfield->auto_flags,
912-
cfield->interval, cfield->field_name, cfield->maybe_null,
913-
cfield->is_zerofill, cfield->is_unsigned, cfield->decimals,
914-
cfield->treat_bit_as_char, 0, cfield->m_srid));
901+
unique_ptr_destroy_only<Field> table_field(make_field(*cfield, table.s));
915902
table_field->init(&table);
916903

917904
if (is_suitable_for_primary_key(key_part, table_field.get()) == false)

sql/dd_sp.cc

+23-18
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
1+
/* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
22
33
This program is free software; you can redistribute it and/or modify
44
it under the terms of the GNU General Public License, version 2.0,
@@ -43,7 +43,7 @@
4343
#include "sql/dd/types/parameter.h" // dd::Parameter
4444
#include "sql/dd/types/parameter_type_element.h" // dd::Parameter_type_element
4545
#include "sql/dd/types/view.h"
46-
#include "sql/dd_table_share.h" // dd_get_mysql_charset
46+
#include "sql/dd_table_share.h" // dd_get_mysql_charset, dd_get_old_field_type
4747
#include "sql/field.h"
4848
#include "sql/gis/srid.h"
4949
#include "sql/sp.h" // SP_DEFAULT_ACCESS_MAPPING
@@ -94,6 +94,25 @@ void prepare_sp_chistics_from_dd_routine(const dd::Routine *routine,
9494
DBUG_VOID_RETURN;
9595
}
9696

97+
static Field *make_field(const dd::Parameter &param, TABLE_SHARE *share,
98+
Field::geometry_type geom_type, TYPELIB *interval) {
99+
// Decimals
100+
uint numeric_scale = 0;
101+
if (param.data_type() == dd::enum_column_types::DECIMAL ||
102+
param.data_type() == dd::enum_column_types::NEWDECIMAL)
103+
numeric_scale = param.numeric_scale();
104+
else if (param.data_type() == dd::enum_column_types::FLOAT ||
105+
param.data_type() == dd::enum_column_types::DOUBLE)
106+
numeric_scale =
107+
param.is_numeric_scale_null() ? NOT_FIXED_DEC : param.numeric_scale();
108+
109+
return make_field(share, (uchar *)0, param.char_length(), (uchar *)"", 0,
110+
dd_get_old_field_type(param.data_type()),
111+
dd_get_mysql_charset(param.collation_id()), geom_type,
112+
Field::NONE, interval, "", false, param.is_zerofill(),
113+
param.is_unsigned(), numeric_scale, 0, 0, {});
114+
}
115+
97116
/**
98117
Helper method to prepare type in string format from the dd::Parameter's
99118
object.
@@ -111,16 +130,6 @@ static void prepare_type_string_from_dd_param(THD *thd,
111130
String *type_str) {
112131
DBUG_ENTER("prepare_type_string_from_dd_param");
113132

114-
// Decimals
115-
uint numeric_scale = 0;
116-
if (param->data_type() == dd::enum_column_types::DECIMAL ||
117-
param->data_type() == dd::enum_column_types::NEWDECIMAL)
118-
numeric_scale = param->numeric_scale();
119-
else if (param->data_type() == dd::enum_column_types::FLOAT ||
120-
param->data_type() == dd::enum_column_types::DOUBLE)
121-
numeric_scale =
122-
param->is_numeric_scale_null() ? NOT_FIXED_DEC : param->numeric_scale();
123-
124133
// ENUM/SET elements.
125134
TYPELIB *interval = NULL;
126135
if (param->data_type() == dd::enum_column_types::ENUM ||
@@ -165,12 +174,8 @@ static void prepare_type_string_from_dd_param(THD *thd,
165174
table.in_use = thd;
166175
table.s = &share;
167176

168-
std::unique_ptr<Field, Destroy_only<Field>> field(
169-
::make_field(table.s, (uchar *)0, param->char_length(), (uchar *)"", 0,
170-
dd_get_old_field_type(param->data_type()),
171-
dd_get_mysql_charset(param->collation_id()), geom_type,
172-
Field::NONE, interval, "", false, param->is_zerofill(),
173-
param->is_unsigned(), numeric_scale, 0, 0, {}));
177+
unique_ptr_destroy_only<Field> field(
178+
make_field(*param, table.s, geom_type, interval));
174179

175180
field->init(&table);
176181
field->sql_type(*type_str);

sql/dd_table_share.cc

+102-20
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,105 @@ static uint column_preamble_bits(const dd::Column *col_obj) {
747747
return result;
748748
}
749749

750+
static Field *make_field(const dd::Column &col_obj, TABLE_SHARE *share,
751+
uchar *ptr, uchar *null_pos, size_t null_bit) {
752+
auto field_type = dd_get_old_field_type(col_obj.type());
753+
auto field_length = col_obj.char_length();
754+
auto charset = get_charset(static_cast<uint>(col_obj.collation_id()), MYF(0));
755+
756+
auto column_options = const_cast<dd::Properties *>(&col_obj.options());
757+
758+
// Reconstruct auto_flags
759+
auto auto_flags = static_cast<uint>(Field::NONE);
760+
761+
/*
762+
The only value for DEFAULT and ON UPDATE options which we support
763+
at this point is CURRENT_TIMESTAMP.
764+
*/
765+
if (!col_obj.default_option().empty()) auto_flags |= Field::DEFAULT_NOW;
766+
if (!col_obj.update_option().empty()) auto_flags |= Field::ON_UPDATE_NOW;
767+
768+
if (col_obj.is_auto_increment()) auto_flags |= Field::NEXT_NUMBER;
769+
770+
/*
771+
Columns can't have AUTO_INCREMENT and DEFAULT/ON UPDATE CURRENT_TIMESTAMP at
772+
the same time.
773+
*/
774+
DBUG_ASSERT(
775+
!((auto_flags & (Field::DEFAULT_NOW | Field::ON_UPDATE_NOW)) != 0 &&
776+
(auto_flags & Field::NEXT_NUMBER) != 0));
777+
778+
// Read Interval TYPELIB
779+
TYPELIB *interval = nullptr;
780+
781+
if (field_type == MYSQL_TYPE_ENUM || field_type == MYSQL_TYPE_SET) {
782+
//
783+
// Allocate space for interval (column elements)
784+
//
785+
size_t interval_parts = col_obj.elements_count();
786+
787+
interval = (TYPELIB *)alloc_root(&share->mem_root, sizeof(TYPELIB));
788+
interval->type_names = (const char **)alloc_root(
789+
&share->mem_root, sizeof(char *) * (interval_parts + 1));
790+
interval->type_names[interval_parts] = 0;
791+
792+
interval->type_lengths =
793+
(uint *)alloc_root(&share->mem_root, sizeof(uint) * interval_parts);
794+
interval->count = interval_parts;
795+
interval->name = NULL;
796+
797+
//
798+
// Iterate through all the column elements
799+
//
800+
for (const dd::Column_type_element *ce : col_obj.elements()) {
801+
// Read the enum/set element name
802+
dd::String_type element_name = ce->name();
803+
804+
uint pos = ce->index() - 1;
805+
interval->type_lengths[pos] = static_cast<uint>(element_name.length());
806+
interval->type_names[pos] = strmake_root(
807+
&share->mem_root, element_name.c_str(), element_name.length());
808+
}
809+
}
810+
811+
// Column name
812+
char *name = nullptr;
813+
dd::String_type s = col_obj.name();
814+
DBUG_ASSERT(!s.empty());
815+
name = strmake_root(&share->mem_root, s.c_str(), s.length());
816+
name[s.length()] = '\0';
817+
818+
uint decimals;
819+
// Decimals
820+
if (field_type == MYSQL_TYPE_DECIMAL || field_type == MYSQL_TYPE_NEWDECIMAL) {
821+
DBUG_ASSERT(col_obj.is_numeric_scale_null() == false);
822+
decimals = col_obj.numeric_scale();
823+
} else if (field_type == MYSQL_TYPE_FLOAT ||
824+
field_type == MYSQL_TYPE_DOUBLE) {
825+
decimals = col_obj.is_numeric_scale_null() ? NOT_FIXED_DEC
826+
: col_obj.numeric_scale();
827+
} else
828+
decimals = 0;
829+
830+
auto geom_type = Field::GEOM_GEOMETRY;
831+
// Read geometry sub type
832+
if (field_type == MYSQL_TYPE_GEOMETRY) {
833+
uint32 sub_type;
834+
column_options->get_uint32("geom_type", &sub_type);
835+
geom_type = static_cast<Field::geometry_type>(sub_type);
836+
}
837+
838+
bool treat_bit_as_char = false;
839+
if (field_type == MYSQL_TYPE_BIT)
840+
column_options->get_bool("treat_bit_as_char", &treat_bit_as_char);
841+
842+
return make_field(share, ptr, field_length, null_pos, null_bit, field_type,
843+
charset, geom_type, auto_flags, interval, name,
844+
col_obj.is_nullable(), col_obj.is_zerofill(),
845+
col_obj.is_unsigned(), decimals, treat_bit_as_char, 0,
846+
col_obj.srs_id());
847+
}
848+
750849
/**
751850
Add Field constructed according to column metadata from dd::Column
752851
object to TABLE_SHARE.
@@ -758,12 +857,9 @@ static bool fill_column_from_dd(THD *thd, TABLE_SHARE *share,
758857
uint field_nr) {
759858
char *name = NULL;
760859
uchar auto_flags;
761-
size_t field_length;
762860
enum_field_types field_type;
763861
const CHARSET_INFO *charset = NULL;
764-
Field::geometry_type geom_type = Field::GEOM_GEOMETRY;
765862
Field *reg_field;
766-
uint decimals;
767863
ha_storage_media field_storage;
768864
column_format_type field_column_format;
769865

@@ -783,9 +879,6 @@ static bool fill_column_from_dd(THD *thd, TABLE_SHARE *share,
783879
// Type
784880
field_type = dd_get_old_field_type(col_obj->type());
785881

786-
// Char length
787-
field_length = col_obj->char_length();
788-
789882
// Reconstruct auto_flags
790883
auto_flags = Field::NONE;
791884

@@ -820,21 +913,13 @@ static bool fill_column_from_dd(THD *thd, TABLE_SHARE *share,
820913
}
821914

822915
// Decimals
823-
if (field_type == MYSQL_TYPE_DECIMAL || field_type == MYSQL_TYPE_NEWDECIMAL) {
916+
if (field_type == MYSQL_TYPE_DECIMAL || field_type == MYSQL_TYPE_NEWDECIMAL)
824917
DBUG_ASSERT(col_obj->is_numeric_scale_null() == false);
825-
decimals = col_obj->numeric_scale();
826-
} else if (field_type == MYSQL_TYPE_FLOAT ||
827-
field_type == MYSQL_TYPE_DOUBLE) {
828-
decimals = col_obj->is_numeric_scale_null() ? NOT_FIXED_DEC
829-
: col_obj->numeric_scale();
830-
} else
831-
decimals = 0;
832918

833919
// Read geometry sub type
834920
if (field_type == MYSQL_TYPE_GEOMETRY) {
835921
uint32 sub_type;
836922
column_options->get_uint32("geom_type", &sub_type);
837-
geom_type = (Field::geometry_type)sub_type;
838923
}
839924

840925
// Read values of storage media and column format options
@@ -910,11 +995,8 @@ static bool fill_column_from_dd(THD *thd, TABLE_SHARE *share,
910995
//
911996
// Create FIELD
912997
//
913-
reg_field = make_field(share, rec_pos, (uint32)field_length, null_pos,
914-
null_bit_pos, field_type, charset, geom_type,
915-
auto_flags, interval, name, col_obj->is_nullable(),
916-
col_obj->is_zerofill(), col_obj->is_unsigned(),
917-
decimals, treat_bit_as_char, 0, col_obj->srs_id());
998+
999+
reg_field = make_field(*col_obj, share, rec_pos, null_pos, null_bit_pos);
9181000

9191001
reg_field->field_index = field_nr;
9201002
reg_field->gcol_info = gcol_info;

sql/default_values.cc

+2-5
Original file line numberDiff line numberDiff line change
@@ -226,11 +226,8 @@ size_t max_pack_length(const List<Create_field> &create_fields) {
226226
bool prepare_default_value(THD *thd, uchar *buf, const TABLE &table,
227227
const Create_field &field, dd::Column *col_obj) {
228228
// Create a fake field with a real data buffer in which to store the value.
229-
Field *regfield = make_field(
230-
table.s, buf + 1, field.length, buf, 0, field.sql_type, field.charset,
231-
field.geom_type, field.auto_flags, field.interval, field.field_name,
232-
field.maybe_null, field.is_zerofill, field.is_unsigned, field.decimals,
233-
field.treat_bit_as_char, field.pack_length_override, {field.m_srid});
229+
Field *regfield = make_field(field, table.s, buf + 1, buf, 0 /* null_bit */);
230+
234231
bool retval = true;
235232
if (!regfield) goto err;
236233

0 commit comments

Comments
 (0)