MDEV-16309 Split ::create_tmp_field() into virtual methods in Item
Detailed: changes: 1. Moving Field specific code into new methods on Field: - Field *Field::create_tmp_field(...) - virtual void init_for_tmp_table(...) 2. Removing virtual Item::create_tmp_field(). Adding instead a new virtual method Item::create_tmp_field_ex(). Note, a virtual create_tmp_field() still exists, but only for Item_sum. This resembles 10.0 code structure. Perhaps create_tmp_field() should be removed from Item_sum and Item_sum descendants should override create_tmp_field_ex() directly. This can be done in a separate commit. 3. Adding helper classes Tmp_field_src and Tmp_field_param, to make the API for Item::create_tmp_field_ex() smaller and easier to extend in the future. 4. Decomposing the public function create_tmp_field() into virtual implementations for Item and a number of its descendants: - Item_basic_value - Item_sp_variable - Item_name_const - Item_result_field - Item_field - Item_ref - Item_type_holder - Item_row - Item_func_sp - Item_func_user_var - Item_sum - Item_sum_field - Item_proc 5. Adding DBUG_ASSERT-only virtual implementations for Item types that should not appear in create_tmp_table_ex(), for easier debugging: - Item_nodeset_func - Item_nodeset_to_const_comparator - Item_null_result - Item_copy - Item_ident_for_show - Item_user_var_as_out_param 6. Moving public function create_tmp_field_from_field() as a method to Item_field. 7. Removing Item::set_result_field(). It's not needed any more. 8. Cleanup: Removing the enum value "EXPR_CACHE_ITEM", as it's not used for a very long time.
This commit is contained in:
parent
13f7ac2269
commit
637af78383
@ -171,3 +171,48 @@ SELECT (SELECT 1 FROM t1 PROCEDURE ANALYSE()) FROM t2;
|
|||||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'PROCEDURE ANALYSE()) FROM t2' at line 1
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'PROCEDURE ANALYSE()) FROM t2' at line 1
|
||||||
SELECT ((SELECT 1 FROM t1 PROCEDURE ANALYSE())) FROM t2;
|
SELECT ((SELECT 1 FROM t1 PROCEDURE ANALYSE())) FROM t2;
|
||||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'PROCEDURE ANALYSE())) FROM t2' at line 1
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'PROCEDURE ANALYSE())) FROM t2' at line 1
|
||||||
|
#
|
||||||
|
# Start of 10.4 tests
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# MDEV-16309 Split ::create_tmp_field() into virtual methods in Item
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
INSERT INTO t1 VALUES (1),(2),(3);
|
||||||
|
BEGIN NOT ATOMIC
|
||||||
|
DECLARE rec ROW(Field_name TEXT,
|
||||||
|
Min_value TEXT,
|
||||||
|
Max_value TEXT,
|
||||||
|
Min_length TEXT,
|
||||||
|
Max_length TEXT,
|
||||||
|
Empties_or_zeros TEXT,
|
||||||
|
Nulls TEXT,
|
||||||
|
Avg_value_or_avg_length TEXT,
|
||||||
|
Std TEXT,
|
||||||
|
Optimal_fieldtype TEXT);
|
||||||
|
DECLARE c CURSOR FOR SELECT * FROM t1 PROCEDURE analyse();
|
||||||
|
OPEN c;
|
||||||
|
FETCH c INTO rec;
|
||||||
|
CLOSE c;
|
||||||
|
SELECT rec.field_name,
|
||||||
|
rec.Min_value, rec.Max_value,
|
||||||
|
rec.Min_length, rec. Max_length,
|
||||||
|
rec.Empties_or_zeros, rec.Nulls,
|
||||||
|
rec.Avg_value_or_avg_length, rec.Std,
|
||||||
|
rec.Optimal_fieldtype;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
rec.field_name test.t1.a
|
||||||
|
rec.Min_value 1
|
||||||
|
rec.Max_value 3
|
||||||
|
rec.Min_length 1
|
||||||
|
rec. Max_length 1
|
||||||
|
rec.Empties_or_zeros 0
|
||||||
|
rec.Nulls 0
|
||||||
|
rec.Avg_value_or_avg_length 2.0000
|
||||||
|
rec.Std 0.8165
|
||||||
|
rec.Optimal_fieldtype ENUM('1','2','3') NOT NULL
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# End of 10.4 tests
|
||||||
|
#
|
||||||
|
@ -181,3 +181,47 @@ SELECT * FROM t1 NATURAL JOIN (SELECT * FROM t2 PROCEDURE ANALYSE());
|
|||||||
SELECT (SELECT 1 FROM t1 PROCEDURE ANALYSE()) FROM t2;
|
SELECT (SELECT 1 FROM t1 PROCEDURE ANALYSE()) FROM t2;
|
||||||
--error ER_PARSE_ERROR
|
--error ER_PARSE_ERROR
|
||||||
SELECT ((SELECT 1 FROM t1 PROCEDURE ANALYSE())) FROM t2;
|
SELECT ((SELECT 1 FROM t1 PROCEDURE ANALYSE())) FROM t2;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Start of 10.4 tests
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-16309 Split ::create_tmp_field() into virtual methods in Item
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
INSERT INTO t1 VALUES (1),(2),(3);
|
||||||
|
--vertical_results
|
||||||
|
DELIMITER $$;
|
||||||
|
BEGIN NOT ATOMIC
|
||||||
|
DECLARE rec ROW(Field_name TEXT,
|
||||||
|
Min_value TEXT,
|
||||||
|
Max_value TEXT,
|
||||||
|
Min_length TEXT,
|
||||||
|
Max_length TEXT,
|
||||||
|
Empties_or_zeros TEXT,
|
||||||
|
Nulls TEXT,
|
||||||
|
Avg_value_or_avg_length TEXT,
|
||||||
|
Std TEXT,
|
||||||
|
Optimal_fieldtype TEXT);
|
||||||
|
DECLARE c CURSOR FOR SELECT * FROM t1 PROCEDURE analyse();
|
||||||
|
OPEN c;
|
||||||
|
FETCH c INTO rec;
|
||||||
|
CLOSE c;
|
||||||
|
SELECT rec.field_name,
|
||||||
|
rec.Min_value, rec.Max_value,
|
||||||
|
rec.Min_length, rec. Max_length,
|
||||||
|
rec.Empties_or_zeros, rec.Nulls,
|
||||||
|
rec.Avg_value_or_avg_length, rec.Std,
|
||||||
|
rec.Optimal_fieldtype;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
--horizontal_results
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of 10.4 tests
|
||||||
|
--echo #
|
||||||
|
@ -1562,3 +1562,29 @@ Catalog Database Table Table_alias Column Column_alias Type Length Max length Is
|
|||||||
def INET_ATON("255.255.255.255.255.255.255.255") 8 21 20 Y 32928 0 63
|
def INET_ATON("255.255.255.255.255.255.255.255") 8 21 20 Y 32928 0 63
|
||||||
INET_ATON("255.255.255.255.255.255.255.255")
|
INET_ATON("255.255.255.255.255.255.255.255")
|
||||||
18446744073709551615
|
18446744073709551615
|
||||||
|
#
|
||||||
|
# End of 10.3 tests
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Start of 10.4 tests
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# MDEV-16309 Split ::create_tmp_field() into virtual methods in Item
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
INSERT INTO t1 VALUES (1),(2),(3);
|
||||||
|
BEGIN NOT ATOMIC
|
||||||
|
DECLARE a TEXT;
|
||||||
|
DECLARE c CURSOR FOR SELECT NAME_CONST('x','y') FROM t1;
|
||||||
|
OPEN c;
|
||||||
|
FETCH c INTO a;
|
||||||
|
CLOSE c;
|
||||||
|
SELECT a;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
a
|
||||||
|
y
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# End of 10.4 tests
|
||||||
|
#
|
||||||
|
@ -1203,3 +1203,34 @@ SELECT INET_ATON("255.255.255.255.255.255.255.255");
|
|||||||
|
|
||||||
--enable_ps_protocol
|
--enable_ps_protocol
|
||||||
--disable_metadata
|
--disable_metadata
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of 10.3 tests
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Start of 10.4 tests
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-16309 Split ::create_tmp_field() into virtual methods in Item
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
INSERT INTO t1 VALUES (1),(2),(3);
|
||||||
|
DELIMITER $$;
|
||||||
|
BEGIN NOT ATOMIC
|
||||||
|
DECLARE a TEXT;
|
||||||
|
DECLARE c CURSOR FOR SELECT NAME_CONST('x','y') FROM t1;
|
||||||
|
OPEN c;
|
||||||
|
FETCH c INTO a;
|
||||||
|
CLOSE c;
|
||||||
|
SELECT a;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of 10.4 tests
|
||||||
|
--echo #
|
||||||
|
30
sql/field.cc
30
sql/field.cc
@ -2331,6 +2331,36 @@ Field *Field::new_key_field(MEM_ROOT *root, TABLE *new_table,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Create field for temporary table from given field.
|
||||||
|
|
||||||
|
@param thd Thread handler
|
||||||
|
@param table Temporary table
|
||||||
|
@param maybe_null_arg If the result field should be NULL-able,
|
||||||
|
even if the original field is NOT NULL, e.g. for:
|
||||||
|
- OUTER JOIN fields
|
||||||
|
- WITH ROLLUP fields
|
||||||
|
- arguments of aggregate functions, e.g. SUM(column1)
|
||||||
|
@retval NULL, on error
|
||||||
|
@retval pointer to the new field created, on success.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Field *Field::create_tmp_field(MEM_ROOT *mem_root, TABLE *new_table,
|
||||||
|
bool maybe_null_arg)
|
||||||
|
{
|
||||||
|
Field *new_field;
|
||||||
|
|
||||||
|
if ((new_field= make_new_field(mem_root, new_table, new_table == table)))
|
||||||
|
{
|
||||||
|
new_field->init_for_tmp_table(this, new_table);
|
||||||
|
new_field->flags|= flags & NO_DEFAULT_VALUE_FLAG;
|
||||||
|
if (maybe_null_arg)
|
||||||
|
new_field->flags&= ~NOT_NULL_FLAG; // Because of outer join
|
||||||
|
}
|
||||||
|
return new_field;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This is used to generate a field in TABLE from TABLE_SHARE */
|
/* This is used to generate a field in TABLE from TABLE_SHARE */
|
||||||
|
|
||||||
Field *Field::clone(MEM_ROOT *root, TABLE *new_table)
|
Field *Field::clone(MEM_ROOT *root, TABLE *new_table)
|
||||||
|
25
sql/field.h
25
sql/field.h
@ -1228,6 +1228,12 @@ public:
|
|||||||
virtual Field *new_key_field(MEM_ROOT *root, TABLE *new_table,
|
virtual Field *new_key_field(MEM_ROOT *root, TABLE *new_table,
|
||||||
uchar *new_ptr, uint32 length,
|
uchar *new_ptr, uint32 length,
|
||||||
uchar *new_null_ptr, uint new_null_bit);
|
uchar *new_null_ptr, uint new_null_bit);
|
||||||
|
Field *create_tmp_field(MEM_ROOT *root, TABLE *new_table,
|
||||||
|
bool maybe_null_arg);
|
||||||
|
Field *create_tmp_field(MEM_ROOT *root, TABLE *new_table)
|
||||||
|
{
|
||||||
|
return create_tmp_field(root, new_table, maybe_null());
|
||||||
|
}
|
||||||
Field *clone(MEM_ROOT *mem_root, TABLE *new_table);
|
Field *clone(MEM_ROOT *mem_root, TABLE *new_table);
|
||||||
Field *clone(MEM_ROOT *mem_root, TABLE *new_table, my_ptrdiff_t diff,
|
Field *clone(MEM_ROOT *mem_root, TABLE *new_table, my_ptrdiff_t diff,
|
||||||
bool stat_flag= FALSE);
|
bool stat_flag= FALSE);
|
||||||
@ -1388,7 +1394,19 @@ public:
|
|||||||
orig_table= table= table_arg;
|
orig_table= table= table_arg;
|
||||||
set_table_name(&table_arg->alias);
|
set_table_name(&table_arg->alias);
|
||||||
}
|
}
|
||||||
|
virtual void init_for_tmp_table(Field *org_field, TABLE *new_table)
|
||||||
|
{
|
||||||
|
init(new_table);
|
||||||
|
orig_table= org_field->orig_table;
|
||||||
|
vcol_info= 0;
|
||||||
|
cond_selectivity= 1.0;
|
||||||
|
next_equal_field= NULL;
|
||||||
|
option_list= NULL;
|
||||||
|
option_struct= NULL;
|
||||||
|
if (org_field->type() == MYSQL_TYPE_VAR_STRING ||
|
||||||
|
org_field->type() == MYSQL_TYPE_VARCHAR)
|
||||||
|
new_table->s->db_create_options|= HA_OPTION_PACK_RECORD;
|
||||||
|
}
|
||||||
/* maximum possible display length */
|
/* maximum possible display length */
|
||||||
virtual uint32 max_display_length()= 0;
|
virtual uint32 max_display_length()= 0;
|
||||||
|
|
||||||
@ -2307,6 +2325,11 @@ public:
|
|||||||
if (dec_arg >= FLOATING_POINT_DECIMALS)
|
if (dec_arg >= FLOATING_POINT_DECIMALS)
|
||||||
dec_arg= NOT_FIXED_DEC;
|
dec_arg= NOT_FIXED_DEC;
|
||||||
}
|
}
|
||||||
|
void init_for_tmp_table(Field *org_field, TABLE *new_table)
|
||||||
|
{
|
||||||
|
Field::init_for_tmp_table(org_field, new_table);
|
||||||
|
not_fixed= true;
|
||||||
|
}
|
||||||
const Type_handler *type_handler() const { return &type_handler_double; }
|
const Type_handler *type_handler() const { return &type_handler_double; }
|
||||||
enum ha_base_keytype key_type() const { return HA_KEYTYPE_DOUBLE; }
|
enum ha_base_keytype key_type() const { return HA_KEYTYPE_DOUBLE; }
|
||||||
int store(const char *to,size_t length,CHARSET_INFO *charset);
|
int store(const char *to,size_t length,CHARSET_INFO *charset);
|
||||||
|
155
sql/item.h
155
sql/item.h
@ -99,7 +99,9 @@ class sp_head;
|
|||||||
class Protocol;
|
class Protocol;
|
||||||
struct TABLE_LIST;
|
struct TABLE_LIST;
|
||||||
void item_init(void); /* Init item functions */
|
void item_init(void); /* Init item functions */
|
||||||
|
class Item_result_field;
|
||||||
class Item_field;
|
class Item_field;
|
||||||
|
class Item_ref;
|
||||||
class Item_param;
|
class Item_param;
|
||||||
class user_var_entry;
|
class user_var_entry;
|
||||||
class JOIN;
|
class JOIN;
|
||||||
@ -603,6 +605,70 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
A helper class describing what kind of Item created a temporary field.
|
||||||
|
- If m_field is set, then the temporary field was created from Field
|
||||||
|
(e.g. when the Item was Item_field, or Item_ref pointing to Item_field)
|
||||||
|
- If m_default_field is set, then there is a usable DEFAULT value.
|
||||||
|
(e.g. when the Item is Item_field)
|
||||||
|
- If m_item_result_field is set, then the temporary field was created
|
||||||
|
from certain sub-types of Item_result_field (e.g. Item_func)
|
||||||
|
See create_tmp_field() in sql_select.cc for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Tmp_field_src
|
||||||
|
{
|
||||||
|
Field *m_field;
|
||||||
|
Field *m_default_field;
|
||||||
|
Item_result_field *m_item_result_field;
|
||||||
|
public:
|
||||||
|
Tmp_field_src()
|
||||||
|
:m_field(0),
|
||||||
|
m_default_field(0),
|
||||||
|
m_item_result_field(0)
|
||||||
|
{ }
|
||||||
|
Field *field() const { return m_field; }
|
||||||
|
Field *default_field() const { return m_default_field; }
|
||||||
|
Item_result_field *item_result_field() const { return m_item_result_field; }
|
||||||
|
void set_field(Field *field) { m_field= field; }
|
||||||
|
void set_default_field(Field *field) { m_default_field= field; }
|
||||||
|
void set_item_result_field(Item_result_field *item)
|
||||||
|
{ m_item_result_field= item; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Parameters for create_tmp_field_ex().
|
||||||
|
See create_tmp_field() in sql_select.cc for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Tmp_field_param
|
||||||
|
{
|
||||||
|
bool m_group;
|
||||||
|
bool m_modify_item;
|
||||||
|
bool m_table_cant_handle_bit_fields;
|
||||||
|
bool m_make_copy_field;
|
||||||
|
public:
|
||||||
|
Tmp_field_param(bool group,
|
||||||
|
bool modify_item,
|
||||||
|
bool table_cant_handle_bit_fields,
|
||||||
|
bool make_copy_field)
|
||||||
|
:m_group(group),
|
||||||
|
m_modify_item(modify_item),
|
||||||
|
m_table_cant_handle_bit_fields(table_cant_handle_bit_fields),
|
||||||
|
m_make_copy_field(make_copy_field)
|
||||||
|
{ }
|
||||||
|
bool group() const { return m_group; }
|
||||||
|
bool modify_item() const { return m_modify_item; }
|
||||||
|
bool table_cant_handle_bit_fields() const
|
||||||
|
{ return m_table_cant_handle_bit_fields; }
|
||||||
|
bool make_copy_field() const { return m_make_copy_field; }
|
||||||
|
void set_modify_item(bool to) { m_modify_item= to; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
class Item: public Value_source,
|
class Item: public Value_source,
|
||||||
public Type_all_attributes
|
public Type_all_attributes
|
||||||
{
|
{
|
||||||
@ -635,7 +701,7 @@ public:
|
|||||||
SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM, TYPE_HOLDER,
|
SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM, TYPE_HOLDER,
|
||||||
PARAM_ITEM, TRIGGER_FIELD_ITEM, DECIMAL_ITEM,
|
PARAM_ITEM, TRIGGER_FIELD_ITEM, DECIMAL_ITEM,
|
||||||
XPATH_NODESET, XPATH_NODESET_CMP,
|
XPATH_NODESET, XPATH_NODESET_CMP,
|
||||||
VIEW_FIXER_ITEM, EXPR_CACHE_ITEM,
|
EXPR_CACHE_ITEM,
|
||||||
DATE_ITEM};
|
DATE_ITEM};
|
||||||
|
|
||||||
enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
|
enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
|
||||||
@ -682,6 +748,24 @@ protected:
|
|||||||
return h->make_and_init_table_field(&name, Record_addr(maybe_null),
|
return h->make_and_init_table_field(&name, Record_addr(maybe_null),
|
||||||
*this, table);
|
*this, table);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
Create a temporary field for a simple Item, which does not
|
||||||
|
need any special action after the field creation:
|
||||||
|
- is not an Item_field descendant (and not a reference to Item_field)
|
||||||
|
- is not an Item_result_field descendant
|
||||||
|
- does not need to copy any DEFAULT value to the result Field
|
||||||
|
- does not need to set Field::is_created_from_null_item for the result
|
||||||
|
See create_tmp_field_ex() for details on parameters and return values.
|
||||||
|
*/
|
||||||
|
Field *create_tmp_field_ex_simple(TABLE *table,
|
||||||
|
Tmp_field_src *src,
|
||||||
|
const Tmp_field_param *param)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(!param->make_copy_field());
|
||||||
|
DBUG_ASSERT(!is_result_field());
|
||||||
|
DBUG_ASSERT(type() != NULL_ITEM);
|
||||||
|
return tmp_table_field_from_field_type(table);
|
||||||
|
}
|
||||||
Field *create_tmp_field_int(TABLE *table, uint convert_int_length);
|
Field *create_tmp_field_int(TABLE *table, uint convert_int_length);
|
||||||
|
|
||||||
void push_note_converted_to_negative_complement(THD *thd);
|
void push_note_converted_to_negative_complement(THD *thd);
|
||||||
@ -1540,7 +1624,6 @@ public:
|
|||||||
set field of temporary table for Item which can be switched on temporary
|
set field of temporary table for Item which can be switched on temporary
|
||||||
table during query processing (grouping and so on)
|
table during query processing (grouping and so on)
|
||||||
*/
|
*/
|
||||||
virtual void set_result_field(Field *field) {}
|
|
||||||
virtual bool is_result_field() { return 0; }
|
virtual bool is_result_field() { return 0; }
|
||||||
virtual bool is_bool_type() { return false; }
|
virtual bool is_bool_type() { return false; }
|
||||||
virtual bool is_json_type() { return false; }
|
virtual bool is_json_type() { return false; }
|
||||||
@ -1817,11 +1900,17 @@ public:
|
|||||||
return Type_handler::type_handler_long_or_longlong(max_char_length());
|
return Type_handler::type_handler_long_or_longlong(max_char_length());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Field *create_tmp_field(bool group, TABLE *table)
|
/**
|
||||||
{
|
Create field for temporary table.
|
||||||
return tmp_table_field_from_field_type(table);
|
@param table Temporary table
|
||||||
}
|
@param [OUT] src Who created the fields
|
||||||
|
@param param Create parameters
|
||||||
|
@retval NULL (on error)
|
||||||
|
@retval a pointer to a newly create Field (on success)
|
||||||
|
*/
|
||||||
|
virtual Field *create_tmp_field_ex(TABLE *table,
|
||||||
|
Tmp_field_src *src,
|
||||||
|
const Tmp_field_param *param)= 0;
|
||||||
virtual Item_field *field_for_view_update() { return 0; }
|
virtual Item_field *field_for_view_update() { return 0; }
|
||||||
|
|
||||||
virtual bool vers_trx_id() const
|
virtual bool vers_trx_id() const
|
||||||
@ -2374,6 +2463,8 @@ protected:
|
|||||||
value == ((Item_basic_value*)item)->val_int() &&
|
value == ((Item_basic_value*)item)->val_int() &&
|
||||||
(value >= 0 || item->unsigned_flag == unsigned_flag);
|
(value >= 0 || item->unsigned_flag == unsigned_flag);
|
||||||
}
|
}
|
||||||
|
Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
|
||||||
|
const Tmp_field_param *param);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -2455,6 +2546,11 @@ public:
|
|||||||
|
|
||||||
inline bool const_item() const;
|
inline bool const_item() const;
|
||||||
|
|
||||||
|
Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
|
||||||
|
const Tmp_field_param *param)
|
||||||
|
{
|
||||||
|
return create_tmp_field_ex_simple(table, src, param);
|
||||||
|
}
|
||||||
inline int save_in_field(Field *field, bool no_conversions);
|
inline int save_in_field(Field *field, bool no_conversions);
|
||||||
inline bool send(Protocol *protocol, st_value *buffer);
|
inline bool send(Protocol *protocol, st_value *buffer);
|
||||||
bool check_vcol_func_processor(void *arg)
|
bool check_vcol_func_processor(void *arg)
|
||||||
@ -2733,6 +2829,16 @@ public:
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
|
||||||
|
const Tmp_field_param *param)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
We can get to here when using a CURSOR for a query with NAME_CONST():
|
||||||
|
DECLARE c CURSOR FOR SELECT NAME_CONST('x','y') FROM t1;
|
||||||
|
OPEN c;
|
||||||
|
*/
|
||||||
|
return create_tmp_field_ex_simple(table, src, param);
|
||||||
|
}
|
||||||
int save_in_field(Field *field, bool no_conversions)
|
int save_in_field(Field *field, bool no_conversions)
|
||||||
{
|
{
|
||||||
return value_item->save_in_field(field, no_conversions);
|
return value_item->save_in_field(field, no_conversions);
|
||||||
@ -2778,13 +2884,15 @@ public:
|
|||||||
{}
|
{}
|
||||||
~Item_result_field() {} /* Required with gcc 2.95 */
|
~Item_result_field() {} /* Required with gcc 2.95 */
|
||||||
Field *get_tmp_table_field() { return result_field; }
|
Field *get_tmp_table_field() { return result_field; }
|
||||||
|
Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
|
||||||
|
const Tmp_field_param *param);
|
||||||
|
void get_tmp_field_src(Tmp_field_src *src, const Tmp_field_param *param);
|
||||||
/*
|
/*
|
||||||
This implementation of used_tables() used by Item_avg_field and
|
This implementation of used_tables() used by Item_avg_field and
|
||||||
Item_variance_field which work when only temporary table left, so theu
|
Item_variance_field which work when only temporary table left, so theu
|
||||||
return table map of the temporary table.
|
return table map of the temporary table.
|
||||||
*/
|
*/
|
||||||
table_map used_tables() const { return 1; }
|
table_map used_tables() const { return 1; }
|
||||||
void set_result_field(Field *field) { result_field= field; }
|
|
||||||
bool is_result_field() { return true; }
|
bool is_result_field() { return true; }
|
||||||
void save_in_result_field(bool no_conversions)
|
void save_in_result_field(bool no_conversions)
|
||||||
{
|
{
|
||||||
@ -2877,6 +2985,12 @@ public:
|
|||||||
Type_std_attributes::set(par_field);
|
Type_std_attributes::set(par_field);
|
||||||
}
|
}
|
||||||
enum Type type() const { return FIELD_ITEM; }
|
enum Type type() const { return FIELD_ITEM; }
|
||||||
|
Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
|
||||||
|
const Tmp_field_param *param)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
double val_real() { return field->val_real(); }
|
double val_real() { return field->val_real(); }
|
||||||
longlong val_int() { return field->val_int(); }
|
longlong val_int() { return field->val_int(); }
|
||||||
String *val_str(String *str) { return field->val_str(str); }
|
String *val_str(String *str) { return field->val_str(str); }
|
||||||
@ -2992,6 +3106,11 @@ public:
|
|||||||
return &type_handler_null;
|
return &type_handler_null;
|
||||||
return field->type_handler();
|
return field->type_handler();
|
||||||
}
|
}
|
||||||
|
Field *create_tmp_field_from_item_field(TABLE *new_table,
|
||||||
|
Item_ref *orig_item,
|
||||||
|
const Tmp_field_param *param);
|
||||||
|
Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
|
||||||
|
const Tmp_field_param *param);
|
||||||
TYPELIB *get_typelib() const { return field->get_typelib(); }
|
TYPELIB *get_typelib() const { return field->get_typelib(); }
|
||||||
uint32 field_flags() const
|
uint32 field_flags() const
|
||||||
{
|
{
|
||||||
@ -3048,7 +3167,6 @@ public:
|
|||||||
cond_equal_ref);
|
cond_equal_ref);
|
||||||
}
|
}
|
||||||
bool is_result_field() { return false; }
|
bool is_result_field() { return false; }
|
||||||
void set_result_field(Field *field_arg) {}
|
|
||||||
void save_in_result_field(bool no_conversions) { }
|
void save_in_result_field(bool no_conversions) { }
|
||||||
Item *get_tmp_table_item(THD *thd);
|
Item *get_tmp_table_item(THD *thd);
|
||||||
bool collect_item_field_processor(void * arg);
|
bool collect_item_field_processor(void * arg);
|
||||||
@ -3257,6 +3375,12 @@ public:
|
|||||||
return result_field->type_handler();
|
return result_field->type_handler();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
|
||||||
|
const Tmp_field_param *param)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
void save_in_result_field(bool no_conversions)
|
void save_in_result_field(bool no_conversions)
|
||||||
{
|
{
|
||||||
save_in_field(result_field, no_conversions);
|
save_in_field(result_field, no_conversions);
|
||||||
@ -3675,8 +3799,6 @@ public:
|
|||||||
enum Type type() const { return INT_ITEM; }
|
enum Type type() const { return INT_ITEM; }
|
||||||
const Type_handler *type_handler() const
|
const Type_handler *type_handler() const
|
||||||
{ return type_handler_long_or_longlong(); }
|
{ return type_handler_long_or_longlong(); }
|
||||||
Field *create_tmp_field(bool group, TABLE *table)
|
|
||||||
{ return tmp_table_field_from_field_type(table); }
|
|
||||||
Field *create_field_for_create_select(TABLE *table)
|
Field *create_field_for_create_select(TABLE *table)
|
||||||
{ return tmp_table_field_from_field_type(table); }
|
{ return tmp_table_field_from_field_type(table); }
|
||||||
longlong val_int() { DBUG_ASSERT(fixed == 1); return value; }
|
longlong val_int() { DBUG_ASSERT(fixed == 1); return value; }
|
||||||
@ -4800,6 +4922,8 @@ public:
|
|||||||
Field *get_tmp_table_field()
|
Field *get_tmp_table_field()
|
||||||
{ return result_field ? result_field : (*ref)->get_tmp_table_field(); }
|
{ return result_field ? result_field : (*ref)->get_tmp_table_field(); }
|
||||||
Item *get_tmp_table_item(THD *thd);
|
Item *get_tmp_table_item(THD *thd);
|
||||||
|
Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
|
||||||
|
const Tmp_field_param *param);
|
||||||
table_map used_tables() const;
|
table_map used_tables() const;
|
||||||
void update_used_tables();
|
void update_used_tables();
|
||||||
COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
|
COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
|
||||||
@ -5549,6 +5673,12 @@ public:
|
|||||||
const Type_handler *type_handler() const
|
const Type_handler *type_handler() const
|
||||||
{ return Type_handler_hybrid_field_type::type_handler(); }
|
{ return Type_handler_hybrid_field_type::type_handler(); }
|
||||||
|
|
||||||
|
Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
|
||||||
|
const Tmp_field_param *param)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
void make_send_field(THD *thd, Send_field *field)
|
void make_send_field(THD *thd, Send_field *field)
|
||||||
{ item->make_send_field(thd, field); }
|
{ item->make_send_field(thd, field); }
|
||||||
table_map used_tables() const { return (table_map) 1L; }
|
table_map used_tables() const { return (table_map) 1L; }
|
||||||
@ -6518,7 +6648,8 @@ public:
|
|||||||
my_decimal *val_decimal(my_decimal *);
|
my_decimal *val_decimal(my_decimal *);
|
||||||
String *val_str(String*);
|
String *val_str(String*);
|
||||||
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
|
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
|
||||||
Field *create_tmp_field(bool group, TABLE *table)
|
Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
|
||||||
|
const Tmp_field_param *param)
|
||||||
{
|
{
|
||||||
return Item_type_holder::real_type_handler()->
|
return Item_type_holder::real_type_handler()->
|
||||||
make_and_init_table_field(&name, Record_addr(maybe_null),
|
make_and_init_table_field(&name, Record_addr(maybe_null),
|
||||||
|
@ -2358,8 +2358,8 @@ public:
|
|||||||
Item_func_user_var(THD *thd, Item_func_user_var *item)
|
Item_func_user_var(THD *thd, Item_func_user_var *item)
|
||||||
:Item_hybrid_func(thd, item),
|
:Item_hybrid_func(thd, item),
|
||||||
m_var_entry(item->m_var_entry), name(item->name) { }
|
m_var_entry(item->m_var_entry), name(item->name) { }
|
||||||
Field *create_tmp_field(bool group, TABLE *table)
|
Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
|
||||||
{ return create_table_field_from_handler(table); }
|
const Tmp_field_param *param);
|
||||||
Field *create_field_for_create_select(TABLE *table)
|
Field *create_field_for_create_select(TABLE *table)
|
||||||
{ return create_table_field_from_handler(table); }
|
{ return create_table_field_from_handler(table); }
|
||||||
bool check_vcol_func_processor(void *arg);
|
bool check_vcol_func_processor(void *arg);
|
||||||
@ -2534,6 +2534,12 @@ public:
|
|||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
|
||||||
|
const Tmp_field_param *param)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
/* We should return something different from FIELD_ITEM here */
|
/* We should return something different from FIELD_ITEM here */
|
||||||
enum Type type() const { return STRING_ITEM;}
|
enum Type type() const { return STRING_ITEM;}
|
||||||
double val_real();
|
double val_real();
|
||||||
@ -2839,6 +2845,8 @@ public:
|
|||||||
|
|
||||||
const Type_handler *type_handler() const;
|
const Type_handler *type_handler() const;
|
||||||
|
|
||||||
|
Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
|
||||||
|
const Tmp_field_param *param);
|
||||||
Field *create_field_for_create_select(TABLE *table)
|
Field *create_field_for_create_select(TABLE *table)
|
||||||
{
|
{
|
||||||
return result_type() != STRING_RESULT ?
|
return result_type() != STRING_RESULT ?
|
||||||
|
@ -56,6 +56,11 @@ public:
|
|||||||
bool with_subquery() const { DBUG_ASSERT(fixed); return m_with_subquery; }
|
bool with_subquery() const { DBUG_ASSERT(fixed); return m_with_subquery; }
|
||||||
enum Type type() const { return ROW_ITEM; };
|
enum Type type() const { return ROW_ITEM; };
|
||||||
const Type_handler *type_handler() const { return &type_handler_row; }
|
const Type_handler *type_handler() const { return &type_handler_row; }
|
||||||
|
Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
|
||||||
|
const Tmp_field_param *param)
|
||||||
|
{
|
||||||
|
return NULL; // Check with Vicentiu why it's called for Item_row
|
||||||
|
}
|
||||||
void illegal_method_call(const char *);
|
void illegal_method_call(const char *);
|
||||||
bool is_null() { return null_value; }
|
bool is_null() { return null_value; }
|
||||||
void make_send_field(THD *thd, Send_field *)
|
void make_send_field(THD *thd, Send_field *)
|
||||||
|
@ -1237,9 +1237,11 @@ Field *Item_sum_hybrid::create_tmp_field(bool group, TABLE *table)
|
|||||||
if (args[0]->type() == Item::FIELD_ITEM)
|
if (args[0]->type() == Item::FIELD_ITEM)
|
||||||
{
|
{
|
||||||
Field *field= ((Item_field*) args[0])->field;
|
Field *field= ((Item_field*) args[0])->field;
|
||||||
if ((field= create_tmp_field_from_field(table->in_use, field, &name,
|
if ((field= field->create_tmp_field(table->in_use->mem_root, table, true)))
|
||||||
table, NULL)))
|
{
|
||||||
field->flags&= ~NOT_NULL_FLAG;
|
DBUG_ASSERT((field->flags & NOT_NULL_FLAG) == 0);
|
||||||
|
field->field_name= name;
|
||||||
|
}
|
||||||
DBUG_RETURN(field);
|
DBUG_RETURN(field);
|
||||||
}
|
}
|
||||||
DBUG_RETURN(tmp_table_field_from_field_type(table));
|
DBUG_RETURN(tmp_table_field_from_field_type(table));
|
||||||
|
@ -510,7 +510,12 @@ public:
|
|||||||
}
|
}
|
||||||
virtual void make_unique() { force_copy_fields= TRUE; }
|
virtual void make_unique() { force_copy_fields= TRUE; }
|
||||||
Item *get_tmp_table_item(THD *thd);
|
Item *get_tmp_table_item(THD *thd);
|
||||||
Field *create_tmp_field(bool group, TABLE *table);
|
virtual Field *create_tmp_field(bool group, TABLE *table);
|
||||||
|
Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
|
||||||
|
const Tmp_field_param *param)
|
||||||
|
{
|
||||||
|
return create_tmp_field(param->group(), table);
|
||||||
|
}
|
||||||
virtual bool collect_outer_ref_processor(void *param);
|
virtual bool collect_outer_ref_processor(void *param);
|
||||||
bool init_sum_func_check(THD *thd);
|
bool init_sum_func_check(THD *thd);
|
||||||
bool check_sum_func(THD *thd, Item **ref);
|
bool check_sum_func(THD *thd, Item **ref);
|
||||||
@ -1377,6 +1382,11 @@ public:
|
|||||||
fixed= true;
|
fixed= true;
|
||||||
}
|
}
|
||||||
table_map used_tables() const { return (table_map) 1L; }
|
table_map used_tables() const { return (table_map) 1L; }
|
||||||
|
Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
|
||||||
|
const Tmp_field_param *param)
|
||||||
|
{
|
||||||
|
return create_tmp_field_ex_simple(table, src, param);
|
||||||
|
}
|
||||||
void save_in_result_field(bool no_conversions) { DBUG_ASSERT(0); }
|
void save_in_result_field(bool no_conversions) { DBUG_ASSERT(0); }
|
||||||
bool check_vcol_func_processor(void *arg)
|
bool check_vcol_func_processor(void *arg)
|
||||||
{
|
{
|
||||||
|
@ -187,6 +187,12 @@ public:
|
|||||||
nodeset->length(0);
|
nodeset->length(0);
|
||||||
}
|
}
|
||||||
enum Type type() const { return XPATH_NODESET; }
|
enum Type type() const { return XPATH_NODESET; }
|
||||||
|
Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
|
||||||
|
const Tmp_field_param *param)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
String *val_str(String *str)
|
String *val_str(String *str)
|
||||||
{
|
{
|
||||||
prepare_nodes();
|
prepare_nodes();
|
||||||
@ -592,7 +598,12 @@ public:
|
|||||||
{
|
{
|
||||||
return mark_unsupported_function(func_name(), arg, VCOL_IMPOSSIBLE);
|
return mark_unsupported_function(func_name(), arg, VCOL_IMPOSSIBLE);
|
||||||
}
|
}
|
||||||
|
Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
|
||||||
|
const Tmp_field_param *param)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
longlong val_int()
|
longlong val_int()
|
||||||
{
|
{
|
||||||
Item_func *comp= (Item_func*)args[1];
|
Item_func *comp= (Item_func*)args[1];
|
||||||
|
@ -44,6 +44,16 @@ public:
|
|||||||
this->name.length= strlen(name_par);
|
this->name.length= strlen(name_par);
|
||||||
}
|
}
|
||||||
enum Type type() const { return Item::PROC_ITEM; }
|
enum Type type() const { return Item::PROC_ITEM; }
|
||||||
|
Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
|
||||||
|
const Tmp_field_param *param)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
We can get to here when using a CURSOR for a query with PROCEDURE:
|
||||||
|
DECLARE c CURSOR FOR SELECT * FROM t1 PROCEDURE analyse();
|
||||||
|
OPEN c;
|
||||||
|
*/
|
||||||
|
return create_tmp_field_ex_simple(table, src, param);
|
||||||
|
}
|
||||||
virtual void set(double nr)=0;
|
virtual void set(double nr)=0;
|
||||||
virtual void set(const char *str,uint length,CHARSET_INFO *cs)=0;
|
virtual void set(const char *str,uint length,CHARSET_INFO *cs)=0;
|
||||||
virtual void set(longlong nr)=0;
|
virtual void set(longlong nr)=0;
|
||||||
|
@ -4080,9 +4080,9 @@ void select_insert::abort_result_set() {
|
|||||||
|
|
||||||
Field *Item::create_field_for_create_select(TABLE *table)
|
Field *Item::create_field_for_create_select(TABLE *table)
|
||||||
{
|
{
|
||||||
Field *def_field, *tmp_field;
|
static Tmp_field_param param(false, false, false, false);
|
||||||
return ::create_tmp_field(table->in_use, table, this, type(),
|
Tmp_field_src src;
|
||||||
(Item ***) 0, &tmp_field, &def_field, 0, 0, 0, 0);
|
return create_tmp_field_ex(table, &src, ¶m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -16525,60 +16525,6 @@ const_expression_in_where(COND *cond, Item *comp_item, Field *comp_field,
|
|||||||
Create internal temporary table
|
Create internal temporary table
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/**
|
|
||||||
Create field for temporary table from given field.
|
|
||||||
|
|
||||||
@param thd Thread handler
|
|
||||||
@param org_field field from which new field will be created
|
|
||||||
@param name New field name
|
|
||||||
@param table Temporary table
|
|
||||||
@param item !=NULL if item->result_field should point to new field.
|
|
||||||
This is relevant for how fill_record() is going to work:
|
|
||||||
If item != NULL then fill_record() will update
|
|
||||||
the record in the original table.
|
|
||||||
If item == NULL then fill_record() will update
|
|
||||||
the temporary table
|
|
||||||
|
|
||||||
@retval
|
|
||||||
NULL on error
|
|
||||||
@retval
|
|
||||||
new_created field
|
|
||||||
*/
|
|
||||||
|
|
||||||
Field *create_tmp_field_from_field(THD *thd, Field *org_field,
|
|
||||||
LEX_CSTRING *name, TABLE *table,
|
|
||||||
Item_field *item)
|
|
||||||
{
|
|
||||||
Field *new_field;
|
|
||||||
|
|
||||||
new_field= org_field->make_new_field(thd->mem_root, table,
|
|
||||||
table == org_field->table);
|
|
||||||
if (new_field)
|
|
||||||
{
|
|
||||||
new_field->init(table);
|
|
||||||
new_field->orig_table= org_field->orig_table;
|
|
||||||
if (item)
|
|
||||||
item->result_field= new_field;
|
|
||||||
else
|
|
||||||
new_field->field_name= *name;
|
|
||||||
new_field->flags|= org_field->flags & NO_DEFAULT_VALUE_FLAG;
|
|
||||||
if (org_field->maybe_null() || (item && item->maybe_null))
|
|
||||||
new_field->flags&= ~NOT_NULL_FLAG; // Because of outer join
|
|
||||||
if (org_field->type() == MYSQL_TYPE_VAR_STRING ||
|
|
||||||
org_field->type() == MYSQL_TYPE_VARCHAR)
|
|
||||||
table->s->db_create_options|= HA_OPTION_PACK_RECORD;
|
|
||||||
else if (org_field->type() == FIELD_TYPE_DOUBLE)
|
|
||||||
((Field_double *) new_field)->not_fixed= TRUE;
|
|
||||||
new_field->vcol_info= 0;
|
|
||||||
new_field->cond_selectivity= 1.0;
|
|
||||||
new_field->next_equal_field= NULL;
|
|
||||||
new_field->option_list= NULL;
|
|
||||||
new_field->option_struct= NULL;
|
|
||||||
}
|
|
||||||
return new_field;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Field *Item::create_tmp_field_int(TABLE *table, uint convert_int_length)
|
Field *Item::create_tmp_field_int(TABLE *table, uint convert_int_length)
|
||||||
{
|
{
|
||||||
const Type_handler *h= &type_handler_long;
|
const Type_handler *h= &type_handler_long;
|
||||||
@ -16619,59 +16565,6 @@ Field *Item_sum::create_tmp_field(bool group, TABLE *table)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void create_tmp_field_from_item_finalize(THD *thd,
|
|
||||||
Field *new_field,
|
|
||||||
Item *item,
|
|
||||||
Item ***copy_func,
|
|
||||||
bool modify_item)
|
|
||||||
{
|
|
||||||
if (copy_func &&
|
|
||||||
(item->is_result_field() ||
|
|
||||||
(item->real_item()->is_result_field())))
|
|
||||||
*((*copy_func)++) = item; // Save for copy_funcs
|
|
||||||
if (modify_item)
|
|
||||||
item->set_result_field(new_field);
|
|
||||||
if (item->type() == Item::NULL_ITEM)
|
|
||||||
new_field->is_created_from_null_item= TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Create field for temporary table using type of given item.
|
|
||||||
|
|
||||||
@param thd Thread handler
|
|
||||||
@param item Item to create a field for
|
|
||||||
@param table Temporary table
|
|
||||||
@param copy_func If set and item is a function, store copy of
|
|
||||||
item in this array
|
|
||||||
@param modify_item 1 if item->result_field should point to new
|
|
||||||
item. This is relevent for how fill_record()
|
|
||||||
is going to work:
|
|
||||||
If modify_item is 1 then fill_record() will
|
|
||||||
update the record in the original table.
|
|
||||||
If modify_item is 0 then fill_record() will
|
|
||||||
update the temporary table
|
|
||||||
@param convert_blob_length If >0 create a varstring(convert_blob_length)
|
|
||||||
field instead of blob.
|
|
||||||
|
|
||||||
@retval
|
|
||||||
0 on error
|
|
||||||
@retval
|
|
||||||
new_created field
|
|
||||||
*/
|
|
||||||
|
|
||||||
static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
|
|
||||||
Item ***copy_func, bool modify_item)
|
|
||||||
{
|
|
||||||
Field *UNINIT_VAR(new_field);
|
|
||||||
DBUG_ASSERT(thd == table->in_use);
|
|
||||||
if ((new_field= item->create_tmp_field(false, table)))
|
|
||||||
create_tmp_field_from_item_finalize(thd, new_field, item,
|
|
||||||
copy_func, modify_item);
|
|
||||||
return new_field;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Create field for information schema table.
|
Create field for information schema table.
|
||||||
|
|
||||||
@ -16708,20 +16601,207 @@ Field *Item::create_field_for_schema(THD *thd, TABLE *table)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Create a temporary field for Item_field (or its descendant),
|
||||||
|
either direct or referenced by an Item_ref.
|
||||||
|
*/
|
||||||
|
Field *
|
||||||
|
Item_field::create_tmp_field_from_item_field(TABLE *new_table,
|
||||||
|
Item_ref *orig_item,
|
||||||
|
const Tmp_field_param *param)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(!is_result_field());
|
||||||
|
Field *result;
|
||||||
|
/*
|
||||||
|
If item have to be able to store NULLs but underlaid field can't do it,
|
||||||
|
create_tmp_field_from_field() can't be used for tmp field creation.
|
||||||
|
*/
|
||||||
|
if (((maybe_null && in_rollup) ||
|
||||||
|
(new_table->in_use->create_tmp_table_for_derived && /* for mat. view/dt */
|
||||||
|
orig_item && orig_item->maybe_null)) &&
|
||||||
|
!field->maybe_null())
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
The item the ref points to may have maybe_null flag set while
|
||||||
|
the ref doesn't have it. This may happen for outer fields
|
||||||
|
when the outer query decided at some point after name resolution phase
|
||||||
|
that this field might be null. Take this into account here.
|
||||||
|
*/
|
||||||
|
Record_addr rec(orig_item ? orig_item->maybe_null : maybe_null);
|
||||||
|
const Type_handler *handler= type_handler()->
|
||||||
|
type_handler_for_tmp_table(this);
|
||||||
|
result= handler->make_and_init_table_field(&name, rec, *this, new_table);
|
||||||
|
}
|
||||||
|
else if (param->table_cant_handle_bit_fields() &&
|
||||||
|
field->type() == MYSQL_TYPE_BIT)
|
||||||
|
{
|
||||||
|
const Type_handler *handler= type_handler_long_or_longlong();
|
||||||
|
result= handler->make_and_init_table_field(&name,
|
||||||
|
Record_addr(maybe_null),
|
||||||
|
*this, new_table);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LEX_CSTRING *tmp= orig_item ? &orig_item->name : &name;
|
||||||
|
bool tmp_maybe_null= param->modify_item() ? maybe_null :
|
||||||
|
field->maybe_null();
|
||||||
|
result= field->create_tmp_field(new_table->in_use->mem_root, new_table,
|
||||||
|
tmp_maybe_null);
|
||||||
|
if (result)
|
||||||
|
result->field_name= *tmp;
|
||||||
|
}
|
||||||
|
if (result && param->modify_item())
|
||||||
|
result_field= result;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Field *Item_field::create_tmp_field_ex(TABLE *table,
|
||||||
|
Tmp_field_src *src,
|
||||||
|
const Tmp_field_param *param)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(!is_result_field());
|
||||||
|
Field *result;
|
||||||
|
src->set_field(field);
|
||||||
|
if (!(result= create_tmp_field_from_item_field(table, NULL, param)))
|
||||||
|
return NULL;
|
||||||
|
/*
|
||||||
|
Fields that are used as arguments to the DEFAULT() function already have
|
||||||
|
their data pointers set to the default value during name resolution. See
|
||||||
|
Item_default_value::fix_fields.
|
||||||
|
*/
|
||||||
|
if (type() != Item::DEFAULT_VALUE_ITEM && field->eq_def(result))
|
||||||
|
src->set_default_field(field);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Field *Item_ref::create_tmp_field_ex(TABLE *table,
|
||||||
|
Tmp_field_src *src,
|
||||||
|
const Tmp_field_param *param)
|
||||||
|
{
|
||||||
|
Item *item= real_item();
|
||||||
|
DBUG_ASSERT(is_result_field());
|
||||||
|
if (item->type() == Item::FIELD_ITEM)
|
||||||
|
{
|
||||||
|
Field *result;
|
||||||
|
Item_field *field= (Item_field*) item;
|
||||||
|
Tmp_field_param prm2(*param);
|
||||||
|
prm2.set_modify_item(false);
|
||||||
|
src->set_field(field->field);
|
||||||
|
if (!(result= field->create_tmp_field_from_item_field(table, this, &prm2)))
|
||||||
|
return NULL;
|
||||||
|
if (param->modify_item())
|
||||||
|
result_field= result;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return Item_result_field::create_tmp_field_ex(table, src, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Item_result_field::get_tmp_field_src(Tmp_field_src *src,
|
||||||
|
const Tmp_field_param *param)
|
||||||
|
{
|
||||||
|
if (param->make_copy_field())
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(result_field);
|
||||||
|
src->set_field(result_field);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
src->set_item_result_field(this); // Save for copy_funcs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Field *Item_result_field::create_tmp_field_ex(TABLE *table,
|
||||||
|
Tmp_field_src *src,
|
||||||
|
const Tmp_field_param *param)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Possible Item types:
|
||||||
|
- Item_cache_wrapper (only for CREATE..SELECT ?)
|
||||||
|
- Item_func
|
||||||
|
- Item_subselect
|
||||||
|
*/
|
||||||
|
DBUG_ASSERT(is_result_field());
|
||||||
|
DBUG_ASSERT(type() != NULL_ITEM);
|
||||||
|
get_tmp_field_src(src, param);
|
||||||
|
Field *result;
|
||||||
|
if ((result= tmp_table_field_from_field_type(table)) && param->modify_item())
|
||||||
|
result_field= result;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Field *Item_func_user_var::create_tmp_field_ex(TABLE *table,
|
||||||
|
Tmp_field_src *src,
|
||||||
|
const Tmp_field_param *param)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(is_result_field());
|
||||||
|
DBUG_ASSERT(type() != NULL_ITEM);
|
||||||
|
get_tmp_field_src(src, param);
|
||||||
|
Field *result;
|
||||||
|
if ((result= create_table_field_from_handler(table)) && param->modify_item())
|
||||||
|
result_field= result;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Field *Item_func_sp::create_tmp_field_ex(TABLE *table,
|
||||||
|
Tmp_field_src *src,
|
||||||
|
const Tmp_field_param *param)
|
||||||
|
{
|
||||||
|
Field *result;
|
||||||
|
get_tmp_field_src(src, param);
|
||||||
|
if ((result= sp_result_field->create_tmp_field(table->in_use->mem_root,
|
||||||
|
table)))
|
||||||
|
{
|
||||||
|
result->field_name= name;
|
||||||
|
if (param->modify_item())
|
||||||
|
result_field= result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Field *Item_basic_value::create_tmp_field_ex(TABLE *table,
|
||||||
|
Tmp_field_src *src,
|
||||||
|
const Tmp_field_param *param)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
create_tmp_field_ex() for this type of Items is called for:
|
||||||
|
- CREATE TABLE ... SELECT
|
||||||
|
- In ORDER BY: SELECT max(a) FROM t1 GROUP BY a ORDER BY 'const';
|
||||||
|
- In CURSORS:
|
||||||
|
DECLARE c CURSOR FOR SELECT 'test';
|
||||||
|
OPEN c;
|
||||||
|
*/
|
||||||
|
DBUG_ASSERT(!param->make_copy_field());
|
||||||
|
DBUG_ASSERT(!is_result_field());
|
||||||
|
Field *result;
|
||||||
|
if ((result= tmp_table_field_from_field_type(table)))
|
||||||
|
{
|
||||||
|
if (type() == Item::NULL_ITEM) // Item_null or Item_param
|
||||||
|
result->is_created_from_null_item= true;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Create field for temporary table.
|
Create field for temporary table.
|
||||||
|
|
||||||
@param thd Thread handler
|
@param table Temporary table
|
||||||
@param table Temporary table
|
@param item Item to create a field for
|
||||||
@param item Item to create a field for
|
@param type Type of item (normally item->type)
|
||||||
@param type Type of item (normally item->type)
|
@param copy_func If set and item is a function, store copy of item
|
||||||
@param copy_func If set and item is a function, store copy of item
|
|
||||||
in this array
|
in this array
|
||||||
@param from_field if field will be created using other field as example,
|
@param from_field if field will be created using other field as example,
|
||||||
pointer example field will be written here
|
pointer example field will be written here
|
||||||
@param default_field If field has a default value field, store it here
|
@param default_field If field has a default value field, store it here
|
||||||
@param group 1 if we are going to do a relative group by on result
|
@param group 1 if we are going to do a relative group by on result
|
||||||
@param modify_item 1 if item->result_field should point to new item.
|
@param modify_item 1 if item->result_field should point to new item.
|
||||||
This is relevent for how fill_record() is going to
|
This is relevent for how fill_record() is going to
|
||||||
work:
|
work:
|
||||||
If modify_item is 1 then fill_record() will update
|
If modify_item is 1 then fill_record() will update
|
||||||
@ -16730,172 +16810,28 @@ Field *Item::create_field_for_schema(THD *thd, TABLE *table)
|
|||||||
the temporary table
|
the temporary table
|
||||||
|
|
||||||
@retval
|
@retval
|
||||||
0 on error
|
0 on error
|
||||||
@retval
|
@retval
|
||||||
new_created field
|
new_created field
|
||||||
|
Create a temporary field for Item_field (or its descendant),
|
||||||
|
either direct or referenced by an Item_ref.
|
||||||
*/
|
*/
|
||||||
|
Field *create_tmp_field(TABLE *table, Item *item,
|
||||||
Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
|
||||||
Item ***copy_func, Field **from_field,
|
Item ***copy_func, Field **from_field,
|
||||||
Field **default_field,
|
Field **default_field,
|
||||||
bool group, bool modify_item,
|
bool group, bool modify_item,
|
||||||
bool table_cant_handle_bit_fields,
|
bool table_cant_handle_bit_fields,
|
||||||
bool make_copy_field)
|
bool make_copy_field)
|
||||||
{
|
{
|
||||||
Field *result;
|
Tmp_field_src src;
|
||||||
Item::Type orig_type= type;
|
Tmp_field_param prm(group, modify_item, table_cant_handle_bit_fields,
|
||||||
Item *orig_item= 0;
|
make_copy_field);
|
||||||
|
Field *result= item->create_tmp_field_ex(table, &src, &prm);
|
||||||
DBUG_ASSERT(thd == table->in_use);
|
*from_field= src.field();
|
||||||
|
*default_field= src.default_field();
|
||||||
if (type != Item::FIELD_ITEM &&
|
if (src.item_result_field())
|
||||||
item->real_item()->type() == Item::FIELD_ITEM)
|
*((*copy_func)++)= src.item_result_field();
|
||||||
{
|
return result;
|
||||||
orig_item= item;
|
|
||||||
item= item->real_item();
|
|
||||||
type= Item::FIELD_ITEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case Item::TYPE_HOLDER:
|
|
||||||
case Item::SUM_FUNC_ITEM:
|
|
||||||
{
|
|
||||||
result= item->create_tmp_field(group, table);
|
|
||||||
if (!result)
|
|
||||||
my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
case Item::FIELD_ITEM:
|
|
||||||
case Item::DEFAULT_VALUE_ITEM:
|
|
||||||
case Item::INSERT_VALUE_ITEM:
|
|
||||||
case Item::TRIGGER_FIELD_ITEM:
|
|
||||||
{
|
|
||||||
Item_field *field= (Item_field*) item;
|
|
||||||
bool orig_modify= modify_item;
|
|
||||||
if (orig_type == Item::REF_ITEM)
|
|
||||||
modify_item= 0;
|
|
||||||
/*
|
|
||||||
If item have to be able to store NULLs but underlaid field can't do it,
|
|
||||||
create_tmp_field_from_field() can't be used for tmp field creation.
|
|
||||||
*/
|
|
||||||
if (((field->maybe_null && field->in_rollup) ||
|
|
||||||
(thd->create_tmp_table_for_derived && /* for mat. view/dt */
|
|
||||||
orig_item && orig_item->maybe_null)) &&
|
|
||||||
!field->field->maybe_null())
|
|
||||||
{
|
|
||||||
bool save_maybe_null= FALSE;
|
|
||||||
/*
|
|
||||||
The item the ref points to may have maybe_null flag set while
|
|
||||||
the ref doesn't have it. This may happen for outer fields
|
|
||||||
when the outer query decided at some point after name resolution phase
|
|
||||||
that this field might be null. Take this into account here.
|
|
||||||
*/
|
|
||||||
if (orig_item)
|
|
||||||
{
|
|
||||||
save_maybe_null= item->maybe_null;
|
|
||||||
item->maybe_null= orig_item->maybe_null;
|
|
||||||
}
|
|
||||||
result= create_tmp_field_from_item(thd, item, table, NULL,
|
|
||||||
modify_item);
|
|
||||||
*from_field= field->field;
|
|
||||||
if (result && modify_item)
|
|
||||||
field->result_field= result;
|
|
||||||
if (orig_item)
|
|
||||||
item->maybe_null= save_maybe_null;
|
|
||||||
}
|
|
||||||
else if (table_cant_handle_bit_fields && field->field->type() ==
|
|
||||||
MYSQL_TYPE_BIT)
|
|
||||||
{
|
|
||||||
const Type_handler *handler= item->type_handler_long_or_longlong();
|
|
||||||
*from_field= field->field;
|
|
||||||
if ((result=
|
|
||||||
handler->make_and_init_table_field(&item->name,
|
|
||||||
Record_addr(item->maybe_null),
|
|
||||||
*item, table)))
|
|
||||||
create_tmp_field_from_item_finalize(thd, result, item,
|
|
||||||
copy_func, modify_item);
|
|
||||||
if (result && modify_item)
|
|
||||||
field->result_field= result;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LEX_CSTRING *tmp= orig_item ? &orig_item->name : &item->name;
|
|
||||||
result= create_tmp_field_from_field(thd, (*from_field= field->field),
|
|
||||||
tmp, table,
|
|
||||||
modify_item ? field :
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (orig_type == Item::REF_ITEM && orig_modify)
|
|
||||||
((Item_ref*)orig_item)->set_result_field(result);
|
|
||||||
/*
|
|
||||||
Fields that are used as arguments to the DEFAULT() function already have
|
|
||||||
their data pointers set to the default value during name resolution. See
|
|
||||||
Item_default_value::fix_fields.
|
|
||||||
*/
|
|
||||||
if (orig_type != Item::DEFAULT_VALUE_ITEM && field->field->eq_def(result))
|
|
||||||
*default_field= field->field;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
/* Fall through */
|
|
||||||
case Item::FUNC_ITEM:
|
|
||||||
if (((Item_func *) item)->functype() == Item_func::FUNC_SP)
|
|
||||||
{
|
|
||||||
Item_func_sp *item_func_sp= (Item_func_sp *) item;
|
|
||||||
Field *sp_result_field= item_func_sp->get_sp_result_field();
|
|
||||||
|
|
||||||
if (make_copy_field)
|
|
||||||
{
|
|
||||||
DBUG_ASSERT(item_func_sp->result_field);
|
|
||||||
*from_field= item_func_sp->result_field;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*((*copy_func)++)= item;
|
|
||||||
}
|
|
||||||
Field *result_field=
|
|
||||||
create_tmp_field_from_field(thd,
|
|
||||||
sp_result_field,
|
|
||||||
&item_func_sp->name,
|
|
||||||
table,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (modify_item)
|
|
||||||
item->set_result_field(result_field);
|
|
||||||
|
|
||||||
return result_field;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fall through */
|
|
||||||
case Item::COND_ITEM:
|
|
||||||
case Item::FIELD_AVG_ITEM:
|
|
||||||
case Item::FIELD_STD_ITEM:
|
|
||||||
case Item::SUBSELECT_ITEM:
|
|
||||||
/* The following can only happen with 'CREATE TABLE ... SELECT' */
|
|
||||||
case Item::PROC_ITEM:
|
|
||||||
case Item::INT_ITEM:
|
|
||||||
case Item::REAL_ITEM:
|
|
||||||
case Item::DECIMAL_ITEM:
|
|
||||||
case Item::STRING_ITEM:
|
|
||||||
case Item::DATE_ITEM:
|
|
||||||
case Item::REF_ITEM:
|
|
||||||
case Item::NULL_ITEM:
|
|
||||||
case Item::VARBIN_ITEM:
|
|
||||||
case Item::CACHE_ITEM:
|
|
||||||
case Item::WINDOW_FUNC_ITEM: // psergey-winfunc:
|
|
||||||
case Item::EXPR_CACHE_ITEM:
|
|
||||||
case Item::PARAM_ITEM:
|
|
||||||
if (make_copy_field)
|
|
||||||
{
|
|
||||||
DBUG_ASSERT(((Item_result_field*)item)->result_field);
|
|
||||||
*from_field= ((Item_result_field*)item)->result_field;
|
|
||||||
}
|
|
||||||
return create_tmp_field_from_item(thd, item, table,
|
|
||||||
(make_copy_field ? 0 : copy_func),
|
|
||||||
modify_item);
|
|
||||||
default: // Dosen't have to be stored
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -17202,7 +17138,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
|
|||||||
{
|
{
|
||||||
Item *tmp_item;
|
Item *tmp_item;
|
||||||
Field *new_field=
|
Field *new_field=
|
||||||
create_tmp_field(thd, table, arg, arg->type(), ©_func,
|
create_tmp_field(table, arg, ©_func,
|
||||||
tmp_from_field, &default_field[fieldnr],
|
tmp_from_field, &default_field[fieldnr],
|
||||||
group != 0,not_all_columns,
|
group != 0,not_all_columns,
|
||||||
distinct, false);
|
distinct, false);
|
||||||
@ -17252,7 +17188,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
The last parameter to create_tmp_field() is a bit tricky:
|
The last parameter to create_tmp_field_ex() is a bit tricky:
|
||||||
|
|
||||||
We need to set it to 0 in union, to get fill_record() to modify the
|
We need to set it to 0 in union, to get fill_record() to modify the
|
||||||
temporary table.
|
temporary table.
|
||||||
@ -17266,7 +17202,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
|
|||||||
*/
|
*/
|
||||||
Field *new_field= (param->schema_table) ?
|
Field *new_field= (param->schema_table) ?
|
||||||
item->create_field_for_schema(thd, table) :
|
item->create_field_for_schema(thd, table) :
|
||||||
create_tmp_field(thd, table, item, type, ©_func,
|
create_tmp_field(table, item, ©_func,
|
||||||
tmp_from_field, &default_field[fieldnr],
|
tmp_from_field, &default_field[fieldnr],
|
||||||
group != 0,
|
group != 0,
|
||||||
!force_copy_fields &&
|
!force_copy_fields &&
|
||||||
@ -17280,7 +17216,6 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
|
|||||||
*/
|
*/
|
||||||
item->marker == 4 || param->bit_fields_as_long,
|
item->marker == 4 || param->bit_fields_as_long,
|
||||||
force_copy_fields);
|
force_copy_fields);
|
||||||
|
|
||||||
if (!new_field)
|
if (!new_field)
|
||||||
{
|
{
|
||||||
if (thd->is_fatal_error)
|
if (thd->is_fatal_error)
|
||||||
@ -23466,7 +23401,7 @@ calc_group_buffer(JOIN *join,ORDER *group)
|
|||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Group strings are taken as varstrings and require an length field.
|
Group strings are taken as varstrings and require an length field.
|
||||||
A field is not yet created by create_tmp_field()
|
A field is not yet created by create_tmp_field_ex()
|
||||||
and the sizes should match up.
|
and the sizes should match up.
|
||||||
*/
|
*/
|
||||||
key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH;
|
key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH;
|
||||||
|
@ -1804,10 +1804,6 @@ bool setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
|
|||||||
void copy_fields(TMP_TABLE_PARAM *param);
|
void copy_fields(TMP_TABLE_PARAM *param);
|
||||||
bool copy_funcs(Item **func_ptr, const THD *thd);
|
bool copy_funcs(Item **func_ptr, const THD *thd);
|
||||||
uint find_shortest_key(TABLE *table, const key_map *usable_keys);
|
uint find_shortest_key(TABLE *table, const key_map *usable_keys);
|
||||||
Field* create_tmp_field_from_field(THD *thd, Field* org_field,
|
|
||||||
LEX_CSTRING *name, TABLE *table,
|
|
||||||
Item_field *item);
|
|
||||||
|
|
||||||
bool is_indexed_agg_distinct(JOIN *join, List<Item_field> *out_args);
|
bool is_indexed_agg_distinct(JOIN *join, List<Item_field> *out_args);
|
||||||
|
|
||||||
/* functions from opt_sum.cc */
|
/* functions from opt_sum.cc */
|
||||||
@ -2059,12 +2055,6 @@ bool mysql_select(THD *thd,
|
|||||||
void free_underlaid_joins(THD *thd, SELECT_LEX *select);
|
void free_underlaid_joins(THD *thd, SELECT_LEX *select);
|
||||||
bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit,
|
bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit,
|
||||||
select_result *result);
|
select_result *result);
|
||||||
Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
|
||||||
Item ***copy_func, Field **from_field,
|
|
||||||
Field **def_field,
|
|
||||||
bool group, bool modify_item,
|
|
||||||
bool table_cant_handle_bit_fields,
|
|
||||||
bool make_copy_field);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
General routine to change field->ptr of a NULL-terminated array of Field
|
General routine to change field->ptr of a NULL-terminated array of Field
|
||||||
|
Loading…
x
Reference in New Issue
Block a user