1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

Merge remote-tracking branch 'origin/10.3' into 10.4

This commit is contained in:
Alexander Barkov
2018-06-05 10:50:08 +04:00
58 changed files with 433 additions and 315 deletions

View File

@@ -17,10 +17,15 @@ see the Credits appendix. You can also run 'SHOW authors' to get a
list of active contributors. list of active contributors.
A description of the MariaDB project and a manual can be found at: A description of the MariaDB project and a manual can be found at:
https://mariadb.org/ https://mariadb.org/
https://mariadb.com/kb/en/ https://mariadb.com/kb/en/
https://mariadb.com/kb/en/mariadb-vs-mysql-features/ https://mariadb.com/kb/en/mariadb-vs-mysql-features/
https://mariadb.com/kb/en/mariadb-versus-mysql-features/ https://mariadb.com/kb/en/mariadb-versus-mysql-features/
https://mariadb.com/kb/en/mariadb-versus-mysql-compatibility/ https://mariadb.com/kb/en/mariadb-versus-mysql-compatibility/
As MariaDB is a full replacement of MySQL, the MySQL manual at As MariaDB is a full replacement of MySQL, the MySQL manual at

View File

@@ -3,7 +3,7 @@ MACRO (MYSQL_CHECK_NUMA)
STRING(TOLOWER "${WITH_NUMA}" WITH_NUMA_LOWERCASE) STRING(TOLOWER "${WITH_NUMA}" WITH_NUMA_LOWERCASE)
IF(NOT WITH_NUMA) IF(NOT WITH_NUMA)
MESSAGE(STATUS "WITH_NUMA=OFF: NUMA memory allocation policy disabled") MESSAGE_ONCE(numa "WITH_NUMA=OFF: NUMA memory allocation policy disabled")
ELSEIF(NOT WITH_NUMA_LOWERCASE STREQUAL "auto" AND NOT WITH_NUMA_LOWERCASE STREQUAL "on") ELSEIF(NOT WITH_NUMA_LOWERCASE STREQUAL "auto" AND NOT WITH_NUMA_LOWERCASE STREQUAL "on")
MESSAGE(FATAL_ERROR "Wrong value for WITH_NUMA") MESSAGE(FATAL_ERROR "Wrong value for WITH_NUMA")
@@ -34,11 +34,11 @@ MACRO (MYSQL_CHECK_NUMA)
ENDIF() ENDIF()
IF(WITH_NUMA_LOWERCASE STREQUAL "auto" AND HAVE_LIBNUMA) IF(WITH_NUMA_LOWERCASE STREQUAL "auto" AND HAVE_LIBNUMA)
MESSAGE(STATUS "WITH_NUMA=AUTO: NUMA memory allocation policy enabled") MESSAGE_ONCE(numa "WITH_NUMA=AUTO: NUMA memory allocation policy enabled")
ELSEIF(WITH_NUMA_LOWERCASE STREQUAL "auto" AND NOT HAVE_LIBNUMA) ELSEIF(WITH_NUMA_LOWERCASE STREQUAL "auto" AND NOT HAVE_LIBNUMA)
MESSAGE(STATUS "WITH_NUMA=AUTO: NUMA memory allocation policy disabled") MESSAGE_ONCE(numa "WITH_NUMA=AUTO: NUMA memory allocation policy disabled")
ELSEIF(HAVE_LIBNUMA) ELSEIF(HAVE_LIBNUMA)
MESSAGE(STATUS "WITH_NUMA=ON: NUMA memory allocation policy enabled") MESSAGE_ONCE(numa "WITH_NUMA=ON: NUMA memory allocation policy enabled")
ELSE() ELSE()
# Forget it in cache, abort the build. # Forget it in cache, abort the build.
UNSET(WITH_NUMA CACHE) UNSET(WITH_NUMA CACHE)

View File

@@ -81,6 +81,16 @@ then
sed '/libzstd1/d' -i debian/control sed '/libzstd1/d' -i debian/control
fi fi
# The binaries should be fully hardened by default. However TokuDB compilation seems to fail on
# Debian Jessie and older and on Ubuntu Xenial and older with the following error message:
# /usr/bin/ld.bfd.real: /tmp/ccOIwjFo.ltrans0.ltrans.o: relocation R_X86_64_PC32 against symbol
# `toku_product_name_strings' can not be used when making a shared object; recompile with -fPIC
# Therefore we need to disable PIE on those releases using debhelper as proxy for detection.
if ! apt-cache madison debhelper | grep 'debhelper *| *1[0-9]\.' >/dev/null 2>&1
then
sed 's/hardening=+all$/hardening=+all,-pie/' -i debian/rules
fi
# Convert gcc version to numberical value. Format is Mmmpp where M is Major # Convert gcc version to numberical value. Format is Mmmpp where M is Major
# version, mm is minor version and p is patch. # version, mm is minor version and p is patch.

View File

@@ -1462,3 +1462,19 @@ a b
4 5 4 5
4 3 4 3
DROP TABLE t1; DROP TABLE t1;
#
# MDEV-16353: unreferenced CTE specified by query with UNION
#
with cte as
(select 1 union select 2 union select 3)
select 1 as f;
f
1
create table t1 (a int);
insert into t1 values (2), (1), (7), (1), (4);
with cte as
(select * from t1 where a < 2 union select * from t1 where a > 5)
select 2 as f;
f
2
drop table t1;

View File

@@ -1012,3 +1012,21 @@ SELECT a FROM cte;
WITH cte(a,b) AS (SELECT 4,5 UNION SELECT 4,3) SELECT a,b FROM cte; WITH cte(a,b) AS (SELECT 4,5 UNION SELECT 4,3) SELECT a,b FROM cte;
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # MDEV-16353: unreferenced CTE specified by query with UNION
--echo #
with cte as
(select 1 union select 2 union select 3)
select 1 as f;
create table t1 (a int);
insert into t1 values (2), (1), (7), (1), (4);
with cte as
(select * from t1 where a < 2 union select * from t1 where a > 5)
select 2 as f;
drop table t1;

View File

@@ -2281,3 +2281,28 @@ t1 CREATE TABLE `t1` (
`int11` int(11) DEFAULT NULL, `int11` int(11) DEFAULT NULL,
`text1` text DEFAULT NULL `text1` text DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
#
# MDEV-16385 ROW SP variable is allowed in unexpected context
#
CREATE TABLE t1 (a INT);
BEGIN NOT ATOMIC
DECLARE row ROW(a INT);
SELECT * FROM t1 ORDER BY row;
END;
$$
ERROR 21000: Operand should contain 1 column(s)
DROP TABLE t1;
CREATE TABLE t1 (a INT);
BEGIN NOT ATOMIC
DECLARE row ROW(a INT);
SELECT * FROM t1 HAVING row;
END;
$$
ERROR 21000: Operand should contain 1 column(s)
DROP TABLE t1;
BEGIN NOT ATOMIC
DECLARE a ROW(a INT);
SELECT 1 LIKE 2 ESCAPE a;
END;
$$
ERROR 21000: Operand should contain 1 column(s)

View File

@@ -1504,3 +1504,38 @@ BEGIN NOT ATOMIC
END; END;
$$ $$
DELIMITER ;$$ DELIMITER ;$$
--echo #
--echo # MDEV-16385 ROW SP variable is allowed in unexpected context
--echo #
CREATE TABLE t1 (a INT);
DELIMITER $$;
--error ER_OPERAND_COLUMNS
BEGIN NOT ATOMIC
DECLARE row ROW(a INT);
SELECT * FROM t1 ORDER BY row;
END;
$$
DELIMITER ;$$
DROP TABLE t1;
CREATE TABLE t1 (a INT);
DELIMITER $$;
--error ER_OPERAND_COLUMNS
BEGIN NOT ATOMIC
DECLARE row ROW(a INT);
SELECT * FROM t1 HAVING row;
END;
$$
DELIMITER ;$$
DROP TABLE t1;
DELIMITER $$;
--error ER_OPERAND_COLUMNS
BEGIN NOT ATOMIC
DECLARE a ROW(a INT);
SELECT 1 LIKE 2 ESCAPE a;
END;
$$
DELIMITER ;$$

View File

@@ -64,11 +64,19 @@ INSERT INTO t VALUES (18, 1, DEFAULT, 'mm');
INSERT INTO t VALUES (28, 1, DEFAULT, 'mm'); INSERT INTO t VALUES (28, 1, DEFAULT, 'mm');
INSERT INTO t VALUES (null, null, DEFAULT, 'mm'); INSERT INTO t VALUES (null, null, DEFAULT, 'mm');
CREATE INDEX idx_1 on t(c); CREATE INDEX idx_1 on t(c);
SET SESSION debug_dbug="+d,create_index_fail"; SET @saved_dbug = @@SESSION.debug_dbug;
ALTER TABLE t ADD COLUMN x INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (x); SET debug_dbug = '+d,create_index_fail';
ALTER TABLE t ADD COLUMN x INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (x),
ADD INDEX idcx (c,x);
ERROR 23000: Duplicate entry '' for key '*UNKNOWN*' ERROR 23000: Duplicate entry '' for key '*UNKNOWN*'
SET SESSION debug_dbug=""; UPDATE t SET a=a+1;
affected rows: 3
info: Rows matched: 4 Changed: 3 Warnings: 0
ALTER TABLE t ADD INDEX idc(c);
ERROR 23000: Duplicate entry '' for key '*UNKNOWN*'
SET debug_dbug = @saved_dbug;
affected rows: 0 affected rows: 0
UPDATE t SET b=b-1;
SHOW CREATE TABLE t; SHOW CREATE TABLE t;
Table Create Table Table Create Table
t CREATE TABLE `t` ( t CREATE TABLE `t` (

View File

@@ -119,14 +119,23 @@ INSERT INTO t VALUES (null, null, DEFAULT, 'mm');
CREATE INDEX idx_1 on t(c); CREATE INDEX idx_1 on t(c);
SET SESSION debug_dbug="+d,create_index_fail"; SET @saved_dbug = @@SESSION.debug_dbug;
SET debug_dbug = '+d,create_index_fail';
--enable_info --enable_info
--error ER_DUP_ENTRY --error ER_DUP_ENTRY
ALTER TABLE t ADD COLUMN x INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (x); ALTER TABLE t ADD COLUMN x INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (x),
SET SESSION debug_dbug=""; ADD INDEX idcx (c,x);
UPDATE t SET a=a+1;
--error ER_DUP_ENTRY
ALTER TABLE t ADD INDEX idc(c);
SET debug_dbug = @saved_dbug;
--disable_info --disable_info
UPDATE t SET b=b-1;
SHOW CREATE TABLE t; SHOW CREATE TABLE t;
SELECT c FROM t; SELECT c FROM t;

View File

@@ -1,2 +0,0 @@
[unique]
[pk]

View File

@@ -1,23 +0,0 @@
--disable_query_log
if ($MTR_COMBINATION_UNIQUE)
{
set @KEY_TYPE= 'unique';
}
if ($MTR_COMBINATION_PK)
{
set @KEY_TYPE= 'primary key';
}
delimiter ~~;
create procedure create_table(name varchar(255), cols varchar(255))
begin
if (cols is null or cols = '') then
set cols= '';
else
set cols= concat(', ', cols);
end if;
set @str= concat('create or replace table ', name, '(id int ', @KEY_TYPE, cols, ') with system versioning');
prepare stmt from @str; execute stmt; drop prepare stmt;
end~~
delimiter ;~~
--enable_query_log

View File

@@ -1,10 +1,28 @@
call create_table('t', 'x int'); create table t (
id int primary key,
x int,
row_start SYS_DATATYPE as row start invisible,
row_end SYS_DATATYPE as row end invisible,
period for system_time (row_start, row_end)
) with system versioning;
insert t values (1, 2); insert t values (1, 2);
replace t values (1, 3); replace t values (1, 3);
select *, row_end>TIMESTAMP'2038-01-01 00:00:00' as current from t for system_time all select *, current_row(row_end) as current from t for system_time all order by x;
order by x;
id x current id x current
1 2 0 1 2 0
1 3 1 1 3 1
drop database test; drop table t;
create database test; create table t (
id int unique,
x int,
row_start SYS_DATATYPE as row start invisible,
row_end SYS_DATATYPE as row end invisible,
period for system_time (row_start, row_end)
) with system versioning;
insert t values (1, 2);
replace t values (1, 3);
select *, current_row(row_end) as current from t for system_time all order by x;
id x current
1 2 0
1 3 1
drop table t;

View File

@@ -538,6 +538,27 @@ a
select * from t1 for system_time from @t2 to @t1; select * from t1 for system_time from @t2 to @t1;
a a
drop table t1; drop table t1;
#
# MDEV-15991 Server crashes in setup_on_expr upon calling SP or function executing DML on versioned tables
#
create or replace table t1 (i int);
insert into t1 values (1);
create or replace procedure p(n int)
begin
select * from t1;
end $
call p(1);
i
1
alter table t1 add system versioning;
call p(2);
i
1
call p(3);
i
1
drop procedure p;
drop table t1;
call verify_trt_dummy(34); call verify_trt_dummy(34);
No A B C D No A B C D
1 1 1 1 1 1 1 1 1 1

View File

@@ -1,13 +1,32 @@
--source suite/versioning/common.inc --source suite/versioning/common.inc
--source suite/versioning/key_type.inc
--source suite/versioning/engines.inc --source suite/versioning/engines.inc
call create_table('t', 'x int'); --replace_result $sys_datatype_expl SYS_DATATYPE
eval create table t (
id int primary key,
x int,
row_start $sys_datatype_expl as row start invisible,
row_end $sys_datatype_expl as row end invisible,
period for system_time (row_start, row_end)
) with system versioning;
insert t values (1, 2); insert t values (1, 2);
replace t values (1, 3); replace t values (1, 3);
select *, row_end>TIMESTAMP'2038-01-01 00:00:00' as current from t for system_time all select *, current_row(row_end) as current from t for system_time all order by x;
order by x; drop table t;
drop database test; --replace_result $sys_datatype_expl SYS_DATATYPE
create database test; eval create table t (
id int unique,
x int,
row_start $sys_datatype_expl as row start invisible,
row_end $sys_datatype_expl as row end invisible,
period for system_time (row_start, row_end)
) with system versioning;
insert t values (1, 2);
replace t values (1, 3);
select *, current_row(row_end) as current from t for system_time all order by x;
drop table t;
--source suite/versioning/common_finish.inc

View File

@@ -348,6 +348,24 @@ select * from t1 for system_time from @t1 to @t2;
select * from t1 for system_time from @t2 to @t1; select * from t1 for system_time from @t2 to @t1;
drop table t1; drop table t1;
--echo #
--echo # MDEV-15991 Server crashes in setup_on_expr upon calling SP or function executing DML on versioned tables
--echo #
create or replace table t1 (i int);
insert into t1 values (1);
--delimiter $
create or replace procedure p(n int)
begin
select * from t1;
end $
--delimiter ;
call p(1);
alter table t1 add system versioning;
call p(2);
call p(3);
drop procedure p;
drop table t1;
call verify_trt_dummy(34); call verify_trt_dummy(34);
-- source suite/versioning/common_finish.inc -- source suite/versioning/common_finish.inc

View File

@@ -3123,9 +3123,6 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
DBUG_RETURN(0); DBUG_RETURN(0);
} }
if (set_connect_attributes(mysql, buff, sizeof(buff)))
DBUG_RETURN(0);
mysql->methods= &client_methods; mysql->methods= &client_methods;
mysql->client_flag=0; /* For handshake */ mysql->client_flag=0; /* For handshake */
@@ -3579,6 +3576,8 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
mysql->client_flag= client_flag; mysql->client_flag= client_flag;
set_connect_attributes(mysql, buff, sizeof(buff));
/* /*
Part 2: invoke the plugin to send the authentication data to the server Part 2: invoke the plugin to send the authentication data to the server
*/ */

View File

@@ -1830,6 +1830,7 @@ Item_field *Item_splocal::get_variable(sp_rcontext *ctx) const
bool Item_splocal::fix_fields(THD *thd, Item **ref) bool Item_splocal::fix_fields(THD *thd, Item **ref)
{ {
DBUG_ASSERT(!fixed);
Item *item= get_variable(thd->spcont); Item *item= get_variable(thd->spcont);
set_handler(item->type_handler()); set_handler(item->type_handler());
return fix_fields_from_item(thd, ref, item); return fix_fields_from_item(thd, ref, item);
@@ -1957,6 +1958,7 @@ bool Item_splocal::check_cols(uint n)
bool Item_splocal_row_field::fix_fields(THD *thd, Item **ref) bool Item_splocal_row_field::fix_fields(THD *thd, Item **ref)
{ {
DBUG_ASSERT(!fixed);
Item *item= get_variable(thd->spcont)->element_index(m_field_idx); Item *item= get_variable(thd->spcont)->element_index(m_field_idx);
return fix_fields_from_item(thd, ref, item); return fix_fields_from_item(thd, ref, item);
} }
@@ -2014,6 +2016,7 @@ bool Item_splocal_row_field::set_value(THD *thd, sp_rcontext *ctx, Item **it)
bool Item_splocal_row_field_by_name::fix_fields(THD *thd, Item **it) bool Item_splocal_row_field_by_name::fix_fields(THD *thd, Item **it)
{ {
DBUG_ASSERT(!fixed);
m_thd= thd; m_thd= thd;
if (get_rcontext(thd->spcont)->find_row_field_by_name_or_error(&m_field_idx, if (get_rcontext(thd->spcont)->find_row_field_by_name_or_error(&m_field_idx,
m_var_idx, m_var_idx,
@@ -2234,10 +2237,8 @@ bool Item_name_const::fix_fields(THD *thd, Item **ref)
String s(buf, sizeof(buf), &my_charset_bin); String s(buf, sizeof(buf), &my_charset_bin);
s.length(0); s.length(0);
if ((!value_item->fixed && if (value_item->fix_fields_if_needed(thd, &value_item) ||
value_item->fix_fields(thd, &value_item)) || name_item->fix_fields_if_needed(thd, &name_item) ||
(!name_item->fixed &&
name_item->fix_fields(thd, &name_item)) ||
!value_item->const_item() || !value_item->const_item() ||
!name_item->const_item() || !name_item->const_item() ||
!(item_name= name_item->val_str(&s))) // Can't have a NULL name !(item_name= name_item->val_str(&s))) // Can't have a NULL name
@@ -9249,8 +9250,7 @@ bool Item_direct_view_ref::fix_fields(THD *thd, Item **reference)
bitmap_set_bit(fld->table->read_set, fld->field_index); bitmap_set_bit(fld->table->read_set, fld->field_index);
} }
} }
else if (!(*ref)->fixed && else if ((*ref)->fix_fields_if_needed(thd, ref))
((*ref)->fix_fields(thd, ref)))
return TRUE; return TRUE;
if (Item_direct_ref::fix_fields(thd, reference)) if (Item_direct_ref::fix_fields(thd, reference))
@@ -9278,7 +9278,7 @@ bool Item_outer_ref::fix_fields(THD *thd, Item **reference)
{ {
bool err; bool err;
/* outer_ref->check_cols() will be made in Item_direct_ref::fix_fields */ /* outer_ref->check_cols() will be made in Item_direct_ref::fix_fields */
if ((*ref) && !(*ref)->fixed && ((*ref)->fix_fields(thd, reference))) if ((*ref) && (*ref)->fix_fields_if_needed(thd, reference))
return TRUE; return TRUE;
err= Item_direct_ref::fix_fields(thd, reference); err= Item_direct_ref::fix_fields(thd, reference);
if (!outer_ref) if (!outer_ref)
@@ -9517,7 +9517,7 @@ bool Item_default_value::fix_fields(THD *thd, Item **items)
fixed= 1; fixed= 1;
return FALSE; return FALSE;
} }
if (!arg->fixed && arg->fix_fields(thd, &arg)) if (arg->fix_fields_if_needed(thd, &arg))
goto error; goto error;
@@ -9862,15 +9862,9 @@ bool Item_trigger_field::set_value(THD *thd, sp_rcontext * /*ctx*/, Item **it)
{ {
Item *item= thd->sp_prepare_func_item(it); Item *item= thd->sp_prepare_func_item(it);
if (!item) if (!item || fix_fields_if_needed(thd, NULL))
return true; return true;
if (!fixed)
{
if (fix_fields(thd, NULL))
return true;
}
// NOTE: field->table->copy_blobs should be false here, but let's // NOTE: field->table->copy_blobs should be false here, but let's
// remember the value at runtime to avoid subtle bugs. // remember the value at runtime to avoid subtle bugs.
bool copy_blobs_saved= field->table->copy_blobs; bool copy_blobs_saved= field->table->copy_blobs;

View File

@@ -902,6 +902,23 @@ public:
void init_make_send_field(Send_field *tmp_field,enum enum_field_types type); void init_make_send_field(Send_field *tmp_field,enum enum_field_types type);
virtual void cleanup(); virtual void cleanup();
virtual void make_send_field(THD *thd, Send_field *field); virtual void make_send_field(THD *thd, Send_field *field);
bool fix_fields_if_needed(THD *thd, Item **ref)
{
return fixed ? false : fix_fields(thd, ref);
}
bool fix_fields_if_needed_for_scalar(THD *thd, Item **ref)
{
return fix_fields_if_needed(thd, ref) || check_cols(1);
}
bool fix_fields_if_needed_for_bool(THD *thd, Item **ref)
{
return fix_fields_if_needed_for_scalar(thd, ref);
}
bool fix_fields_if_needed_for_order_by(THD *thd, Item **ref)
{
return fix_fields_if_needed_for_scalar(thd, ref);
}
virtual bool fix_fields(THD *, Item **); virtual bool fix_fields(THD *, Item **);
/* /*
Fix after some tables has been pulled out. Basically re-calculate all Fix after some tables has been pulled out. Basically re-calculate all
@@ -5164,8 +5181,7 @@ public:
bool fix_fields(THD *thd, Item **it) bool fix_fields(THD *thd, Item **it)
{ {
if ((!(*ref)->fixed && (*ref)->fix_fields(thd, ref)) || if ((*ref)->fix_fields_if_needed_for_scalar(thd, ref))
(*ref)->check_cols(1))
return TRUE; return TRUE;
return Item_ref::fix_fields(thd, it); return Item_ref::fix_fields(thd, it);
} }
@@ -5203,8 +5219,7 @@ public:
bool fix_fields(THD *thd, Item **it) bool fix_fields(THD *thd, Item **it)
{ {
DBUG_ASSERT(ident->type() == FIELD_ITEM || ident->type() == REF_ITEM); DBUG_ASSERT(ident->type() == FIELD_ITEM || ident->type() == REF_ITEM);
if ((!ident->fixed && ident->fix_fields(thd, ref)) || if (ident->fix_fields_if_needed_for_scalar(thd, ref))
ident->check_cols(1))
return TRUE; return TRUE;
set_properties(); set_properties();
return FALSE; return FALSE;

View File

@@ -1242,7 +1242,7 @@ bool Item_in_optimizer::fix_left(THD *thd)
ref0= &(((Item_in_subselect *)args[1])->left_expr); ref0= &(((Item_in_subselect *)args[1])->left_expr);
args[0]= ((Item_in_subselect *)args[1])->left_expr; args[0]= ((Item_in_subselect *)args[1])->left_expr;
} }
if ((!(*ref0)->fixed && (*ref0)->fix_fields(thd, ref0)) || if ((*ref0)->fix_fields_if_needed(thd, ref0) ||
(!cache && !(cache= (*ref0)->get_cache(thd)))) (!cache && !(cache= (*ref0)->get_cache(thd))))
DBUG_RETURN(1); DBUG_RETURN(1);
/* /*
@@ -1327,7 +1327,7 @@ bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
if (args[0]->maybe_null) if (args[0]->maybe_null)
maybe_null=1; maybe_null=1;
if (!args[1]->fixed && args[1]->fix_fields(thd, args+1)) if (args[1]->fix_fields_if_needed(thd, args + 1))
return TRUE; return TRUE;
if (!invisible_mode() && if (!invisible_mode() &&
((sub && ((col= args[0]->cols()) != sub->engine->cols())) || ((sub && ((col= args[0]->cols()) != sub->engine->cols())) ||
@@ -4586,11 +4586,9 @@ Item_cond::fix_fields(THD *thd, Item **ref)
thd->restore_active_arena(arena, &backup); thd->restore_active_arena(arena, &backup);
} }
// item can be substituted in fix_fields if (item->fix_fields_if_needed_for_bool(thd, li.ref()))
if ((!item->fixed &&
item->fix_fields(thd, li.ref())) ||
(item= *li.ref())->check_cols(1))
return TRUE; /* purecov: inspected */ return TRUE; /* purecov: inspected */
item= *li.ref(); // item can be substituted in fix_fields
used_tables_cache|= item->used_tables(); used_tables_cache|= item->used_tables();
if (item->const_item() && !item->with_param && if (item->const_item() && !item->with_param &&
!item->is_expensive() && !cond_has_datetime_is_null(item)) !item->is_expensive() && !cond_has_datetime_is_null(item))
@@ -5306,7 +5304,7 @@ bool Item_func_like::fix_fields(THD *thd, Item **ref)
{ {
DBUG_ASSERT(fixed == 0); DBUG_ASSERT(fixed == 0);
if (Item_bool_func2::fix_fields(thd, ref) || if (Item_bool_func2::fix_fields(thd, ref) ||
escape_item->fix_fields(thd, &escape_item) || escape_item->fix_fields_if_needed_for_scalar(thd, &escape_item) ||
fix_escape_item(thd, escape_item, &cmp_value1, escape_used_in_parsing, fix_escape_item(thd, escape_item, &cmp_value1, escape_used_in_parsing,
cmp_collation.collation, &escape)) cmp_collation.collation, &escape))
return TRUE; return TRUE;

View File

@@ -360,7 +360,7 @@ Item_func::fix_fields(THD *thd, Item **ref)
We can't yet set item to *arg as fix_fields may change *arg We can't yet set item to *arg as fix_fields may change *arg
We shouldn't call fix_fields() twice, so check 'fixed' field first We shouldn't call fix_fields() twice, so check 'fixed' field first
*/ */
if ((!(*arg)->fixed && (*arg)->fix_fields(thd, arg))) if ((*arg)->fix_fields_if_needed(thd, arg))
return TRUE; /* purecov: inspected */ return TRUE; /* purecov: inspected */
item= *arg; item= *arg;
@@ -3279,13 +3279,10 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
arg != arg_end ; arg != arg_end ;
arg++,i++) arg++,i++)
{ {
if (!(*arg)->fixed && if ((*arg)->fix_fields_if_needed_for_scalar(thd, arg))
(*arg)->fix_fields(thd, arg)) DBUG_RETURN(true);
DBUG_RETURN(1);
// we can't assign 'item' before, because fix_fields() can change arg // we can't assign 'item' before, because fix_fields() can change arg
Item *item= *arg; Item *item= *arg;
if (item->check_cols(1))
DBUG_RETURN(TRUE);
/* /*
TODO: We should think about this. It is not always TODO: We should think about this. It is not always
right way just to set an UDF result to return my_charset_bin right way just to set an UDF result to return my_charset_bin

View File

@@ -41,8 +41,7 @@ bool Item_row::fix_fields(THD *thd, Item **ref)
Item **arg, **arg_end; Item **arg, **arg_end;
for (arg= args, arg_end= args + arg_count; arg != arg_end ; arg++) for (arg= args, arg_end= args + arg_count; arg != arg_end ; arg++)
{ {
if (!(*arg)->fixed && if ((*arg)->fix_fields_if_needed(thd, arg))
(*arg)->fix_fields(thd, arg))
return TRUE; return TRUE;
// we can't assign 'item' before, because fix_fields() can change arg // we can't assign 'item' before, because fix_fields() can change arg
Item *item= *arg; Item *item= *arg;

View File

@@ -302,8 +302,7 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
engine->exclude(); engine->exclude();
substitution= 0; substitution= 0;
thd->where= "checking transformed subquery"; thd->where= "checking transformed subquery";
if (!(*ref)->fixed) res= (*ref)->fix_fields_if_needed(thd, ref);
res= (*ref)->fix_fields(thd, ref);
goto end; goto end;
} }
@@ -2181,7 +2180,7 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join,
row_value_transformer? row_value_transformer?
*/ */
item->name= in_additional_cond; item->name= in_additional_cond;
if (!item->fixed && item->fix_fields(thd, 0)) if (item->fix_fields_if_needed(thd, 0))
DBUG_RETURN(true); DBUG_RETURN(true);
*where_item= item; *where_item= item;
} }
@@ -2504,7 +2503,7 @@ Item_in_subselect::create_row_in_to_exists_cond(JOIN * join,
if (*where_item) if (*where_item)
{ {
if (!(*where_item)->fixed && (*where_item)->fix_fields(thd, 0)) if ((*where_item)->fix_fields_if_needed(thd, 0))
DBUG_RETURN(true); DBUG_RETURN(true);
(*where_item)->top_level_item(); (*where_item)->top_level_item();
} }
@@ -2651,7 +2650,7 @@ bool Item_in_subselect::inject_in_to_exists_cond(JOIN *join_arg)
} }
where_item= and_items(thd, join_arg->conds, where_item); where_item= and_items(thd, join_arg->conds, where_item);
if (!where_item->fixed && where_item->fix_fields(thd, 0)) if (where_item->fix_fields_if_needed(thd, 0))
DBUG_RETURN(true); DBUG_RETURN(true);
// TIMOUR TODO: call optimize_cond() for the new where clause // TIMOUR TODO: call optimize_cond() for the new where clause
thd->change_item_tree(&select_lex->where, where_item); thd->change_item_tree(&select_lex->where, where_item);
@@ -3117,7 +3116,7 @@ bool Item_exists_subselect::exists2in_processor(void *opt_arg)
exp= optimizer; exp= optimizer;
} }
upper_not->arguments()[0]= exp; upper_not->arguments()[0]= exp;
if (!exp->fixed && exp->fix_fields(thd, upper_not->arguments())) if (exp->fix_fields_if_needed(thd, upper_not->arguments()))
{ {
res= TRUE; res= TRUE;
goto out; goto out;
@@ -3315,8 +3314,7 @@ bool Item_in_subselect::fix_fields(THD *thd_arg, Item **ref)
} }
} }
if (left_expr && !left_expr->fixed && if (left_expr && left_expr->fix_fields_if_needed(thd_arg, &left_expr))
left_expr->fix_fields(thd_arg, &left_expr))
goto err; goto err;
else else
if (Item_subselect::fix_fields(thd_arg, ref)) if (Item_subselect::fix_fields(thd_arg, ref))
@@ -4999,8 +4997,8 @@ bool subselect_hash_sj_engine::init(List<Item> *tmp_columns, uint subquery_id)
Repeat name resolution for 'cond' since cond is not part of any Repeat name resolution for 'cond' since cond is not part of any
clause of the query, and it is not 'fixed' during JOIN::prepare. clause of the query, and it is not 'fixed' during JOIN::prepare.
*/ */
if (semi_join_conds && !semi_join_conds->fixed && if (semi_join_conds &&
semi_join_conds->fix_fields(thd, (Item**)&semi_join_conds)) semi_join_conds->fix_fields_if_needed(thd, (Item**)&semi_join_conds))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
/* Let our engine reuse this query plan for materialization. */ /* Let our engine reuse this query plan for materialization. */
materialize_join= materialize_engine->join; materialize_join= materialize_engine->join;

View File

@@ -1129,7 +1129,7 @@ Item_sum_num::fix_fields(THD *thd, Item **ref)
maybe_null= sum_func() != COUNT_FUNC; maybe_null= sum_func() != COUNT_FUNC;
for (uint i=0 ; i < arg_count ; i++) for (uint i=0 ; i < arg_count ; i++)
{ {
if (args[i]->fix_fields(thd, args + i) || args[i]->check_cols(1)) if (args[i]->fix_fields_if_needed_for_scalar(thd, &args[i]))
return TRUE; return TRUE;
set_if_bigger(decimals, args[i]->decimals); set_if_bigger(decimals, args[i]->decimals);
m_with_subquery|= args[i]->with_subquery(); m_with_subquery|= args[i]->with_subquery();
@@ -1156,14 +1156,11 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
DBUG_ENTER("Item_sum_hybrid::fix_fields"); DBUG_ENTER("Item_sum_hybrid::fix_fields");
DBUG_ASSERT(fixed == 0); DBUG_ASSERT(fixed == 0);
Item *item= args[0];
if (init_sum_func_check(thd)) if (init_sum_func_check(thd))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
// 'item' can be changed during fix_fields // 'item' can be changed during fix_fields
if ((!item->fixed && item->fix_fields(thd, args)) || if (args[0]->fix_fields_if_needed_for_scalar(thd, &args[0]))
(item= args[0])->check_cols(1))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
m_with_subquery= args[0]->with_subquery(); m_with_subquery= args[0]->with_subquery();
@@ -1300,7 +1297,7 @@ Item_sum_sp::fix_fields(THD *thd, Item **ref)
for (uint i= 0 ; i < arg_count ; i++) for (uint i= 0 ; i < arg_count ; i++)
{ {
if (args[i]->fix_fields(thd, args + i) || args[i]->check_cols(1)) if (args[i]->fix_fields_if_needed_for_scalar(thd, &args[i]))
return TRUE; return TRUE;
set_if_bigger(decimals, args[i]->decimals); set_if_bigger(decimals, args[i]->decimals);
m_with_subquery|= args[i]->with_subquery(); m_with_subquery|= args[i]->with_subquery();
@@ -3911,9 +3908,7 @@ Item_func_group_concat::fix_fields(THD *thd, Item **ref)
for (i=0 ; i < arg_count ; i++) for (i=0 ; i < arg_count ; i++)
{ {
if ((!args[i]->fixed && if (args[i]->fix_fields_if_needed_for_scalar(thd, &args[i]))
args[i]->fix_fields(thd, args + i)) ||
args[i]->check_cols(1))
return TRUE; return TRUE;
m_with_subquery|= args[i]->with_subquery(); m_with_subquery|= args[i]->with_subquery();
with_param|= args[i]->with_param; with_param|= args[i]->with_param;

View File

@@ -327,10 +327,8 @@ bool Item_sum_hybrid_simple::fix_fields(THD *thd, Item **ref)
for (uint i= 0; i < arg_count; i++) for (uint i= 0; i < arg_count; i++)
{ {
Item *item= args[i];
// 'item' can be changed during fix_fields // 'item' can be changed during fix_fields
if ((!item->fixed && item->fix_fields(thd, args)) || if (args[i]->fix_fields_if_needed_for_scalar(thd, &args[i]))
(item= args[i])->check_cols(1))
return TRUE; return TRUE;
} }
Type_std_attributes::set(args[0]); Type_std_attributes::set(args[0]);

View File

@@ -620,8 +620,8 @@ int check_and_do_in_subquery_rewrites(JOIN *join)
char const *save_where= thd->where; char const *save_where= thd->where;
thd->where= "IN/ALL/ANY subquery"; thd->where= "IN/ALL/ANY subquery";
bool failure= !in_subs->left_expr->fixed && bool failure= in_subs->left_expr->fix_fields_if_needed(thd,
in_subs->left_expr->fix_fields(thd, &in_subs->left_expr); &in_subs->left_expr);
thd->lex->current_select= current; thd->lex->current_select= current;
thd->where= save_where; thd->where= save_where;
if (failure) if (failure)
@@ -1666,8 +1666,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
*/ */
SELECT_LEX *save_lex= thd->lex->current_select; SELECT_LEX *save_lex= thd->lex->current_select;
thd->lex->current_select=subq_lex; thd->lex->current_select=subq_lex;
if (!subq_pred->left_expr->fixed && if (subq_pred->left_expr->fix_fields_if_needed(thd, &subq_pred->left_expr))
subq_pred->left_expr->fix_fields(thd, &subq_pred->left_expr))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
thd->lex->current_select=save_lex; thd->lex->current_select=save_lex;
@@ -1777,8 +1776,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
to check for this at name resolution stage, but as a legacy of IN->EXISTS to check for this at name resolution stage, but as a legacy of IN->EXISTS
we have in here). we have in here).
*/ */
if (!sj_nest->sj_on_expr->fixed && if (sj_nest->sj_on_expr->fix_fields_if_needed(thd, &sj_nest->sj_on_expr))
sj_nest->sj_on_expr->fix_fields(thd, &sj_nest->sj_on_expr))
{ {
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
@@ -1804,8 +1802,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
emb_tbl_nest->on_expr= and_items(thd, emb_tbl_nest->on_expr, emb_tbl_nest->on_expr= and_items(thd, emb_tbl_nest->on_expr,
sj_nest->sj_on_expr); sj_nest->sj_on_expr);
emb_tbl_nest->on_expr->top_level_item(); emb_tbl_nest->on_expr->top_level_item();
if (!emb_tbl_nest->on_expr->fixed && if (emb_tbl_nest->on_expr->fix_fields_if_needed(thd,
emb_tbl_nest->on_expr->fix_fields(thd,
&emb_tbl_nest->on_expr)) &emb_tbl_nest->on_expr))
{ {
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
@@ -1822,9 +1819,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
*/ */
save_lex= thd->lex->current_select; save_lex= thd->lex->current_select;
thd->lex->current_select=parent_join->select_lex; thd->lex->current_select=parent_join->select_lex;
if (!parent_join->conds->fixed && if (parent_join->conds->fix_fields_if_needed(thd, &parent_join->conds))
parent_join->conds->fix_fields(thd,
&parent_join->conds))
{ {
DBUG_RETURN(1); DBUG_RETURN(1);
} }
@@ -3724,7 +3719,7 @@ bool setup_sj_materialization_part1(JOIN_TAB *sjm_tab)
re-executing it will not be prepared. To use the Items from its re-executing it will not be prepared. To use the Items from its
select list we have to prepare (fix_fields) them select list we have to prepare (fix_fields) them
*/ */
if (!item->fixed && item->fix_fields(thd, it.ref())) if (item->fix_fields_if_needed(thd, it.ref()))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
item= *(it.ref()); // it can be changed by fix_fields item= *(it.ref()); // it can be changed by fix_fields
DBUG_ASSERT(!item->name.length || item->name.length == strlen(item->name.str)); DBUG_ASSERT(!item->name.length || item->name.length == strlen(item->name.str));
@@ -5587,7 +5582,7 @@ Item *and_new_conditions_to_optimized_cond(THD *thd, Item *cond,
li.rewind(); li.rewind();
while ((item=li++)) while ((item=li++))
{ {
if (!item->fixed && item->fix_fields(thd, NULL)) if (item->fix_fields_if_needed(thd, NULL))
return NULL; return NULL;
if (item->const_item() && !item->val_int()) if (item->const_item() && !item->val_int())
is_simplified_cond= true; is_simplified_cond= true;
@@ -5648,7 +5643,7 @@ Item *and_new_conditions_to_optimized_cond(THD *thd, Item *cond,
cond= iter++; cond= iter++;
} }
if (!cond->fixed && cond->fix_fields(thd, NULL)) if (cond->fix_fields_if_needed(thd, NULL))
return NULL; return NULL;
if (new_cond_equal.current_level.elements > 0) if (new_cond_equal.current_level.elements > 0)

View File

@@ -768,8 +768,7 @@ int set_var::check(THD *thd)
if (!value) if (!value)
return 0; return 0;
if ((!value->fixed && if (value->fix_fields_if_needed_for_scalar(thd, &value))
value->fix_fields(thd, &value)) || value->check_cols(1))
return -1; return -1;
if (var->check_update_type(value)) if (var->check_update_type(value))
{ {
@@ -803,8 +802,7 @@ int set_var::light_check(THD *thd)
if (type == OPT_GLOBAL && check_global_access(thd, SUPER_ACL)) if (type == OPT_GLOBAL && check_global_access(thd, SUPER_ACL))
return 1; return 1;
if (value && ((!value->fixed && value->fix_fields(thd, &value)) || if (value && value->fix_fields_if_needed_for_scalar(thd, &value))
value->check_cols(1)))
return -1; return -1;
return 0; return 0;
} }

View File

@@ -98,7 +98,7 @@ sp_map_item_type(const Type_handler *handler)
bool Item_splocal::append_for_log(THD *thd, String *str) bool Item_splocal::append_for_log(THD *thd, String *str)
{ {
if (fix_fields(thd, NULL)) if (fix_fields_if_needed(thd, NULL))
return true; return true;
if (limit_clause_param) if (limit_clause_param)
@@ -136,7 +136,7 @@ bool Item_splocal::append_value_for_log(THD *thd, String *str)
bool Item_splocal_row_field::append_for_log(THD *thd, String *str) bool Item_splocal_row_field::append_for_log(THD *thd, String *str)
{ {
if (fix_fields(thd, NULL)) if (fix_fields_if_needed(thd, NULL))
return true; return true;
if (limit_clause_param) if (limit_clause_param)
@@ -372,16 +372,14 @@ Item *THD::sp_prepare_func_item(Item **it_addr, uint cols)
Item *THD::sp_fix_func_item(Item **it_addr) Item *THD::sp_fix_func_item(Item **it_addr)
{ {
DBUG_ENTER("THD::sp_fix_func_item"); DBUG_ENTER("THD::sp_fix_func_item");
if (!(*it_addr)->fixed && if ((*it_addr)->fix_fields_if_needed(this, it_addr))
(*it_addr)->fix_fields(this, it_addr))
{ {
DBUG_PRINT("info", ("fix_fields() failed")); DBUG_PRINT("info", ("fix_fields() failed"));
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
} }
it_addr= (*it_addr)->this_item_addr(this, it_addr); it_addr= (*it_addr)->this_item_addr(this, it_addr);
if (!(*it_addr)->fixed && if ((*it_addr)->fix_fields_if_needed(this, it_addr))
(*it_addr)->fix_fields(this, it_addr))
{ {
DBUG_PRINT("info", ("fix_fields() failed")); DBUG_PRINT("info", ("fix_fields() failed"));
DBUG_RETURN(NULL); DBUG_RETURN(NULL);

View File

@@ -71,7 +71,7 @@ int compare_decimal2(int* len, const char *s, const char *t)
static bool static bool
prepare_param(THD *thd, Item **item, const char *proc_name, uint pos) prepare_param(THD *thd, Item **item, const char *proc_name, uint pos)
{ {
if (!(*item)->fixed && (*item)->fix_fields(thd, item)) if ((*item)->fix_fields_if_needed(thd, item))
{ {
DBUG_PRINT("info", ("fix_fields() for the parameter %u failed", pos)); DBUG_PRINT("info", ("fix_fields() for the parameter %u failed", pos));
return true; return true;

View File

@@ -5625,8 +5625,7 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name, si
calls fix_fields on that item), it's just a check during table calls fix_fields on that item), it's just a check during table
reopening for columns that was dropped by the concurrent connection. reopening for columns that was dropped by the concurrent connection.
*/ */
if (!nj_col->table_field->fixed && if (nj_col->table_field->fix_fields_if_needed(thd, &ref))
nj_col->table_field->fix_fields(thd, &ref))
{ {
DBUG_PRINT("info", ("column '%s' was dropped by the concurrent connection", DBUG_PRINT("info", ("column '%s' was dropped by the concurrent connection",
nj_col->table_field->name.str)); nj_col->table_field->name.str));
@@ -7327,8 +7326,7 @@ bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array,
if (make_pre_fix) if (make_pre_fix)
pre_fix->push_back(item, thd->stmt_arena->mem_root); pre_fix->push_back(item, thd->stmt_arena->mem_root);
if ((!item->fixed && item->fix_fields(thd, it.ref())) || if (item->fix_fields_if_needed_for_scalar(thd, it.ref()))
(item= *(it.ref()))->check_cols(1))
{ {
thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup; thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
thd->lex->allow_sum_func= save_allow_sum_func; thd->lex->allow_sum_func= save_allow_sum_func;
@@ -7336,6 +7334,7 @@ bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array,
DBUG_PRINT("info", ("thd->column_usage: %d", thd->column_usage)); DBUG_PRINT("info", ("thd->column_usage: %d", thd->column_usage));
DBUG_RETURN(TRUE); /* purecov: inspected */ DBUG_RETURN(TRUE); /* purecov: inspected */
} }
item= *(it.ref()); // Item might have changed in fix_fields()
if (!ref.is_null()) if (!ref.is_null())
{ {
ref[0]= item; ref[0]= item;
@@ -7957,9 +7956,8 @@ bool setup_on_expr(THD *thd, TABLE_LIST *table, bool is_update)
{ {
thd->where="on clause"; thd->where="on clause";
embedded->on_expr->mark_as_condition_AND_part(embedded); embedded->on_expr->mark_as_condition_AND_part(embedded);
if ((!embedded->on_expr->fixed && if (embedded->on_expr->fix_fields_if_needed_for_bool(thd,
embedded->on_expr->fix_fields(thd, &embedded->on_expr)) || &embedded->on_expr))
embedded->on_expr->check_cols(1))
return TRUE; return TRUE;
} }
/* /*
@@ -7969,7 +7967,7 @@ bool setup_on_expr(THD *thd, TABLE_LIST *table, bool is_update)
if (embedded->sj_subq_pred) if (embedded->sj_subq_pred)
{ {
Item **left_expr= &embedded->sj_subq_pred->left_expr; Item **left_expr= &embedded->sj_subq_pred->left_expr;
if (!(*left_expr)->fixed && (*left_expr)->fix_fields(thd, left_expr)) if ((*left_expr)->fix_fields_if_needed(thd, left_expr))
return TRUE; return TRUE;
} }
@@ -8067,8 +8065,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves,
if ((*conds)->type() == Item::FIELD_ITEM && !derived) if ((*conds)->type() == Item::FIELD_ITEM && !derived)
wrap_ident(thd, conds); wrap_ident(thd, conds);
(*conds)->mark_as_condition_AND_part(NO_JOIN_NEST); (*conds)->mark_as_condition_AND_part(NO_JOIN_NEST);
if ((!(*conds)->fixed && (*conds)->fix_fields(thd, conds)) || if ((*conds)->fix_fields_if_needed_for_bool(thd, conds))
(*conds)->check_cols(1))
goto err_no_arena; goto err_no_arena;
} }

View File

@@ -1007,8 +1007,6 @@ public:
{ return state == STMT_PREPARED || state == STMT_EXECUTED; } { return state == STMT_PREPARED || state == STMT_EXECUTED; }
inline bool is_conventional() const inline bool is_conventional() const
{ return state == STMT_CONVENTIONAL_EXECUTION; } { return state == STMT_CONVENTIONAL_EXECUTION; }
inline bool is_sp_execute() const
{ return is_stored_procedure; }
inline void* alloc(size_t size) { return alloc_root(mem_root,size); } inline void* alloc(size_t size) { return alloc_root(mem_root,size); }
inline void* calloc(size_t size) inline void* calloc(size_t size)

View File

@@ -465,9 +465,7 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived)
derived->prep_on_expr= expr->copy_andor_structure(thd); derived->prep_on_expr= expr->copy_andor_structure(thd);
} }
if (derived->on_expr && if (derived->on_expr &&
((!derived->on_expr->fixed && derived->on_expr->fix_fields_if_needed_for_bool(thd, &derived->on_expr))
derived->on_expr->fix_fields(thd, &derived->on_expr)) ||
derived->on_expr->check_cols(1)))
{ {
res= TRUE; /* purecov: inspected */ res= TRUE; /* purecov: inspected */
goto exit_merge; goto exit_merge;

View File

@@ -217,8 +217,7 @@ Condition_information::aggregate(THD *thd, const Diagnostics_area *da)
DBUG_ENTER("Condition_information::aggregate"); DBUG_ENTER("Condition_information::aggregate");
/* Prepare the expression for evaluation. */ /* Prepare the expression for evaluation. */
if (!m_cond_number_expr->fixed && if (m_cond_number_expr->fix_fields_if_needed(thd, &m_cond_number_expr))
m_cond_number_expr->fix_fields(thd, &m_cond_number_expr))
DBUG_RETURN(true); DBUG_RETURN(true);
cond_number= m_cond_number_expr->val_int(); cond_number= m_cond_number_expr->val_int();

View File

@@ -628,8 +628,7 @@ mysql_ha_fix_cond_and_key(SQL_HANDLER *handler,
/* This can only be true for temp tables */ /* This can only be true for temp tables */
if (table->query_id != thd->query_id) if (table->query_id != thd->query_id)
cond->cleanup(); // File was reopened cond->cleanup(); // File was reopened
if ((!cond->fixed && if (cond->fix_fields_if_needed_for_bool(thd, &cond))
cond->fix_fields(thd, &cond)) || cond->check_cols(1))
return 1; return 1;
} }
@@ -693,10 +692,9 @@ mysql_ha_fix_cond_and_key(SQL_HANDLER *handler,
{ {
my_bitmap_map *old_map; my_bitmap_map *old_map;
/* note that 'item' can be changed by fix_fields() call */ /* note that 'item' can be changed by fix_fields() call */
if ((!item->fixed && if (item->fix_fields_if_needed_for_scalar(thd, it_ke.ref()))
item->fix_fields(thd, it_ke.ref())) ||
(item= *it_ke.ref())->check_cols(1))
return 1; return 1;
item= *it_ke.ref();
if (item->used_tables() & ~(RAND_TABLE_BIT | PARAM_TABLE_BIT)) if (item->used_tables() & ~(RAND_TABLE_BIT | PARAM_TABLE_BIT))
{ {
my_error(ER_WRONG_ARGUMENTS,MYF(0),"HANDLER ... READ"); my_error(ER_WRONG_ARGUMENTS,MYF(0),"HANDLER ... READ");

View File

@@ -611,8 +611,7 @@ int send_variant_2_list(MEM_ROOT *mem_root, Protocol *protocol,
SQL_SELECT *prepare_simple_select(THD *thd, Item *cond, SQL_SELECT *prepare_simple_select(THD *thd, Item *cond,
TABLE *table, int *error) TABLE *table, int *error)
{ {
if (!cond->fixed) cond->fix_fields_if_needed(thd, &cond); // can never fail
cond->fix_fields(thd, &cond); // can never fail
/* Assume that no indexes cover all required fields */ /* Assume that no indexes cover all required fields */
table->covering_keys.clear_all(); table->covering_keys.clear_all();

View File

@@ -1317,7 +1317,7 @@ static bool check_view_insertability(THD * thd, TABLE_LIST *view)
/* check simplicity and prepare unique test of view */ /* check simplicity and prepare unique test of view */
for (trans= trans_start; trans != trans_end; trans++) for (trans= trans_start; trans != trans_end; trans++)
{ {
if (!trans->item->fixed && trans->item->fix_fields(thd, &trans->item)) if (trans->item->fix_fields_if_needed(thd, &trans->item))
{ {
thd->column_usage= saved_column_usage; thd->column_usage= saved_column_usage;
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);

View File

@@ -2682,15 +2682,9 @@ ha_rows st_select_lex::get_offset()
if (offset_limit) if (offset_limit)
{ {
// see comment for st_select_lex::get_limit() // see comment for st_select_lex::get_limit()
bool fix_fields_successful= true; bool err= offset_limit->fix_fields_if_needed(master_unit()->thd, NULL);
if (!offset_limit->fixed) DBUG_ASSERT(!err);
{ val= err ? HA_POS_ERROR : offset_limit->val_uint();
fix_fields_successful= !offset_limit->fix_fields(master_unit()->thd,
NULL);
DBUG_ASSERT(fix_fields_successful);
}
val= fix_fields_successful ? offset_limit->val_uint() : HA_POS_ERROR;
} }
return (ha_rows)val; return (ha_rows)val;
@@ -2729,15 +2723,9 @@ ha_rows st_select_lex::get_limit()
fix_fields() implementation. Also added runtime check against a result fix_fields() implementation. Also added runtime check against a result
of fix_fields() in order to handle error condition in non-debug build. of fix_fields() in order to handle error condition in non-debug build.
*/ */
bool fix_fields_successful= true; bool err= select_limit->fix_fields_if_needed(master_unit()->thd, NULL);
if (!select_limit->fixed) DBUG_ASSERT(!err);
{ val= err ? HA_POS_ERROR : select_limit->val_uint();
fix_fields_successful= !select_limit->fix_fields(master_unit()->thd,
NULL);
DBUG_ASSERT(fix_fields_successful);
}
val= fix_fields_successful ? select_limit->val_uint() : HA_POS_ERROR;
} }
return (ha_rows)val; return (ha_rows)val;

View File

@@ -3333,7 +3333,7 @@ public:
List_iterator_fast<Item> param_it(prepared_stmt_params); List_iterator_fast<Item> param_it(prepared_stmt_params);
while (Item *param= param_it++) while (Item *param= param_it++)
{ {
if (param->fix_fields(thd, 0) || param->check_cols(1)) if (param->fix_fields_if_needed_for_scalar(thd, 0))
return true; return true;
} }
return false; return false;

View File

@@ -3709,8 +3709,7 @@ mysql_execute_command(THD *thd)
Item **it= lex->value_list.head_ref(); Item **it= lex->value_list.head_ref();
if (!(*it)->basic_const_item() || if (!(*it)->basic_const_item() ||
(!(*it)->fixed && (*it)->fix_fields(lex->thd, it)) || (*it)->fix_fields_if_needed_for_scalar(lex->thd, it))
(*it)->check_cols(1))
{ {
my_message(ER_SET_CONSTANTS_ONLY, ER_THD(thd, ER_SET_CONSTANTS_ONLY), my_message(ER_SET_CONSTANTS_ONLY, ER_THD(thd, ER_SET_CONSTANTS_ONLY),
MYF(0)); MYF(0));
@@ -3819,8 +3818,7 @@ mysql_execute_command(THD *thd)
goto error; goto error;
/* PURGE MASTER LOGS BEFORE 'data' */ /* PURGE MASTER LOGS BEFORE 'data' */
it= (Item *)lex->value_list.head(); it= (Item *)lex->value_list.head();
if ((!it->fixed && it->fix_fields(lex->thd, &it)) || if (it->fix_fields_if_needed_for_scalar(lex->thd, &it))
it->check_cols(1))
{ {
my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE"); my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE");
goto error; goto error;
@@ -5680,7 +5678,7 @@ end_with_restore_list:
if (lex->kill_type == KILL_TYPE_ID || lex->kill_type == KILL_TYPE_QUERY) if (lex->kill_type == KILL_TYPE_ID || lex->kill_type == KILL_TYPE_QUERY)
{ {
Item *it= (Item *)lex->value_list.head(); Item *it= (Item *)lex->value_list.head();
if ((!it->fixed && it->fix_fields(lex->thd, &it)) || it->check_cols(1)) if (it->fix_fields_if_needed_for_scalar(lex->thd, &it))
{ {
my_message(ER_SET_CONSTANTS_ONLY, ER_THD(thd, ER_SET_CONSTANTS_ONLY), my_message(ER_SET_CONSTANTS_ONLY, ER_THD(thd, ER_SET_CONSTANTS_ONLY),
MYF(0)); MYF(0));

View File

@@ -146,7 +146,7 @@ Item* convert_charset_partition_constant(Item *item, CHARSET_INFO *cs)
item= item->safe_charset_converter(thd, cs); item= item->safe_charset_converter(thd, cs);
context->table_list= NULL; context->table_list= NULL;
thd->where= "convert character set partition constant"; thd->where= "convert character set partition constant";
if (!item || item->fix_fields(thd, (Item**)NULL)) if (item->fix_fields_if_needed(thd, (Item**)NULL))
item= NULL; item= NULL;
thd->where= save_where; thd->where= save_where;
context->table_list= save_list; context->table_list= save_list;
@@ -854,7 +854,7 @@ static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
const nesting_map saved_allow_sum_func= thd->lex->allow_sum_func; const nesting_map saved_allow_sum_func= thd->lex->allow_sum_func;
thd->lex->allow_sum_func= 0; thd->lex->allow_sum_func= 0;
if (likely(!(error= func_expr->fix_fields(thd, (Item**)&func_expr)))) if (likely(!(error= func_expr->fix_fields_if_needed(thd, (Item**)&func_expr))))
func_expr->walk(&Item::post_fix_fields_part_expr_processor, 0, NULL); func_expr->walk(&Item::post_fix_fields_part_expr_processor, 0, NULL);
/* /*

View File

@@ -1656,8 +1656,7 @@ static bool mysql_test_call_fields(Prepared_statement *stmt,
while ((item= it++)) while ((item= it++))
{ {
if ((!item->fixed && item->fix_fields(thd, it.ref())) || if (item->fix_fields_if_needed_for_scalar(thd, it.ref()))
item->check_cols(1))
goto err; goto err;
} }
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
@@ -2665,8 +2664,7 @@ end:
bool LEX::get_dynamic_sql_string(LEX_CSTRING *dst, String *buffer) bool LEX::get_dynamic_sql_string(LEX_CSTRING *dst, String *buffer)
{ {
if (prepared_stmt_code->fix_fields(thd, NULL) || if (prepared_stmt_code->fix_fields_if_needed_for_scalar(thd, NULL))
prepared_stmt_code->check_cols(1))
return true; return true;
const String *str= prepared_stmt_code->val_str(buffer); const String *str= prepared_stmt_code->val_str(buffer);

View File

@@ -531,7 +531,7 @@ fix_inner_refs(THD *thd, List<Item> &all_fields, SELECT_LEX *select,
ref->outer_ref= new_ref; ref->outer_ref= new_ref;
ref->ref= &ref->outer_ref; ref->ref= &ref->outer_ref;
if (!ref->fixed && ref->fix_fields(thd, 0)) if (ref->fix_fields_if_needed(thd, 0))
return TRUE; return TRUE;
thd->lex->used_tables|= item->used_tables(); thd->lex->used_tables|= item->used_tables();
thd->lex->current_select->select_list_tables|= item->used_tables(); thd->lex->current_select->select_list_tables|= item->used_tables();
@@ -678,7 +678,6 @@ bool vers_select_conds_t::init_from_sysvar(THD *thd)
vers_asof_timestamp_t &in= thd->variables.vers_asof_timestamp; vers_asof_timestamp_t &in= thd->variables.vers_asof_timestamp;
type= (vers_system_time_t) in.type; type= (vers_system_time_t) in.type;
start.unit= VERS_TIMESTAMP; start.unit= VERS_TIMESTAMP;
from_query= false;
if (type != SYSTEM_TIME_UNSPECIFIED && type != SYSTEM_TIME_ALL) if (type != SYSTEM_TIME_UNSPECIFIED && type != SYSTEM_TIME_ALL)
{ {
DBUG_ASSERT(type == SYSTEM_TIME_AS_OF); DBUG_ASSERT(type == SYSTEM_TIME_AS_OF);
@@ -726,7 +725,7 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables)
TABLE_LIST *table; TABLE_LIST *table;
if (!thd->stmt_arena->is_conventional() && if (!thd->stmt_arena->is_conventional() &&
!thd->stmt_arena->is_stmt_prepare() && !thd->stmt_arena->is_sp_execute()) !thd->stmt_arena->is_stmt_prepare_or_first_sp_execute())
{ {
// statement is already prepared // statement is already prepared
DBUG_RETURN(0); DBUG_RETURN(0);
@@ -741,7 +740,7 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables)
{ {
if (table->table && table->table->versioned()) if (table->table && table->table->versioned())
versioned_tables++; versioned_tables++;
else if (table->vers_conditions.user_defined() && else if (table->vers_conditions.is_set() &&
(table->is_non_derived() || !table->vers_conditions.used)) (table->is_non_derived() || !table->vers_conditions.used))
{ {
my_error(ER_VERS_NOT_VERSIONED, MYF(0), table->alias.str); my_error(ER_VERS_NOT_VERSIONED, MYF(0), table->alias.str);
@@ -1141,9 +1140,7 @@ JOIN::prepare(TABLE_LIST *tables_init,
if (having->type() == Item::REF_ITEM && if (having->type() == Item::REF_ITEM &&
((Item_ref *)having)->ref_type() == Item_ref::REF) ((Item_ref *)having)->ref_type() == Item_ref::REF)
wrap_ident(thd, &having); wrap_ident(thd, &having);
bool having_fix_rc= (!having->fixed && bool having_fix_rc= having->fix_fields_if_needed_for_bool(thd, &having);
(having->fix_fields(thd, &having) ||
having->check_cols(1)));
select_lex->having_fix_field= 0; select_lex->having_fix_field= 0;
if (unlikely(having_fix_rc || thd->is_error())) if (unlikely(having_fix_rc || thd->is_error()))
@@ -2713,10 +2710,10 @@ bool JOIN::add_having_as_table_cond(JOIN_TAB *tab)
sort_table_cond))) sort_table_cond)))
DBUG_RETURN(true); DBUG_RETURN(true);
} }
if (tab->select->cond && !tab->select->cond->fixed) if (tab->select->cond)
tab->select->cond->fix_fields(thd, 0); tab->select->cond->fix_fields_if_needed(thd, 0);
if (tab->pre_idx_push_select_cond && !tab->pre_idx_push_select_cond->fixed) if (tab->pre_idx_push_select_cond)
tab->pre_idx_push_select_cond->fix_fields(thd, 0); tab->pre_idx_push_select_cond->fix_fields_if_needed(thd, 0);
tab->select->pre_idx_push_select_cond= tab->pre_idx_push_select_cond; tab->select->pre_idx_push_select_cond= tab->pre_idx_push_select_cond;
tab->set_select_cond(tab->select->cond, __LINE__); tab->set_select_cond(tab->select->cond, __LINE__);
tab->select_cond->top_level_item(); tab->select_cond->top_level_item();
@@ -9386,7 +9383,7 @@ bool JOIN::inject_cond_into_where(Item *injected_cond)
} }
where_item= and_items(thd, conds, where_item); where_item= and_items(thd, conds, where_item);
if (!where_item->fixed && where_item->fix_fields(thd, 0)) if (where_item->fix_fields_if_needed(thd, 0))
return true; return true;
thd->change_item_tree(&select_lex->where, where_item); thd->change_item_tree(&select_lex->where, where_item);
select_lex->where->top_level_item(); select_lex->where->top_level_item();
@@ -22872,8 +22869,8 @@ find_order_in_list(THD *thd, Ref_ptr_array ref_pointer_array,
original field name, we should additionally check if we have conflict original field name, we should additionally check if we have conflict
for this name (in case if we would perform lookup in all tables). for this name (in case if we would perform lookup in all tables).
*/ */
if (resolution == RESOLVED_BEHIND_ALIAS && !order_item->fixed && if (resolution == RESOLVED_BEHIND_ALIAS &&
order_item->fix_fields(thd, order->item)) order_item->fix_fields_if_needed_for_order_by(thd, order->item))
return TRUE; return TRUE;
/* Lookup the current GROUP field in the FROM clause. */ /* Lookup the current GROUP field in the FROM clause. */
@@ -22954,11 +22951,10 @@ find_order_in_list(THD *thd, Ref_ptr_array ref_pointer_array,
We check order_item->fixed because Item_func_group_concat can put We check order_item->fixed because Item_func_group_concat can put
arguments for which fix_fields already was called. arguments for which fix_fields already was called.
*/ */
if (!order_item->fixed && if (order_item->fix_fields_if_needed_for_order_by(thd, order->item) ||
(order_item->fix_fields(thd, order->item) || thd->is_error())
(order_item= *order->item)->check_cols(1) ||
thd->is_error()))
return TRUE; /* Wrong field. */ return TRUE; /* Wrong field. */
order_item= *order->item; // Item can change during fix_fields()
if (!add_to_all_fields) if (!add_to_all_fields)
return FALSE; return FALSE;
@@ -24256,7 +24252,7 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
{ {
Item *new_cond= and_conds(thd, cond_copy, Item *new_cond= and_conds(thd, cond_copy,
join_tab->select->pre_idx_push_select_cond); join_tab->select->pre_idx_push_select_cond);
if (!new_cond->fixed && new_cond->fix_fields(thd, &new_cond)) if (new_cond->fix_fields_if_needed(thd, &new_cond))
error= 1; error= 1;
join_tab->pre_idx_push_select_cond= join_tab->pre_idx_push_select_cond=
join_tab->select->pre_idx_push_select_cond= new_cond; join_tab->select->pre_idx_push_select_cond= new_cond;

View File

@@ -8455,8 +8455,7 @@ int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list)
Field_translator *end= table_list->field_translation_end; Field_translator *end= table_list->field_translation_end;
for (transl= table_list->field_translation; transl < end; transl++) for (transl= table_list->field_translation; transl < end; transl++)
{ {
if (!transl->item->fixed && if (transl->item->fix_fields_if_needed(thd, &transl->item))
transl->item->fix_fields(thd, &transl->item))
DBUG_RETURN(1); DBUG_RETURN(1);
} }
DBUG_RETURN(0); DBUG_RETURN(0);
@@ -8473,11 +8472,9 @@ int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list)
{ {
transl->item= item; transl->item= item;
transl->name= item->name; transl->name= item->name;
if (!item->fixed && item->fix_fields(thd, &transl->item)) if (item->fix_fields_if_needed(thd, &transl->item))
{
DBUG_RETURN(1); DBUG_RETURN(1);
} }
}
table_list->field_translation= org_transl; table_list->field_translation= org_transl;
table_list->field_translation_end= transl; table_list->field_translation_end= transl;
} }

View File

@@ -218,16 +218,9 @@ int Sql_cmd_common_signal::eval_signal_informations(THD *thd, Sql_condition *con
i <= LAST_DIAG_SET_PROPERTY; i <= LAST_DIAG_SET_PROPERTY;
i++) i++)
{ {
set= m_set_signal_information.m_item[i]; if ((set= m_set_signal_information.m_item[i]) &&
if (set) set->fix_fields_if_needed(thd, &m_set_signal_information.m_item[i]))
{
if (! set->fixed)
{
if (set->fix_fields(thd, & set))
goto end; goto end;
m_set_signal_information.m_item[i]= set;
}
}
} }
/* /*

View File

@@ -797,8 +797,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
*/ */
trg_field->setup_field(thd, table, NULL); trg_field->setup_field(thd, table, NULL);
if (!trg_field->fixed && if (trg_field->fix_fields_if_needed(thd, (Item **)0))
trg_field->fix_fields(thd, (Item **)0))
DBUG_RETURN(true); DBUG_RETURN(true);
} }

View File

@@ -1008,7 +1008,7 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
{ {
if (with_element) if (with_element)
{ {
if (derived_arg->with->rename_columns_of_derived_unit(thd, this)) if (with_element->rename_columns_of_derived_unit(thd, this))
goto err; goto err;
if (check_duplicate_names(thd, sl->item_list, 0)) if (check_duplicate_names(thd, sl->item_list, 0))
goto err; goto err;

View File

@@ -1938,7 +1938,7 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view)
DBUG_PRINT("info", ("thd->column_usage: %d", thd->column_usage)); DBUG_PRINT("info", ("thd->column_usage: %d", thd->column_usage));
for (Field_translator *fld= trans; fld < end_of_trans; fld++) for (Field_translator *fld= trans; fld < end_of_trans; fld++)
{ {
if (!fld->item->fixed && fld->item->fix_fields(thd, &fld->item)) if (fld->item->fix_fields_if_needed(thd, &fld->item))
{ {
thd->column_usage= saved_column_usage; thd->column_usage= saved_column_usage;
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);

View File

@@ -11788,9 +11788,10 @@ table_primary_ident:
pop_index_hints(), pop_index_hints(),
$3)))) $3))))
MYSQL_YYABORT; MYSQL_YYABORT;
Select->add_joined_table($$); TABLE_LIST *tl= $$;
Select->add_joined_table(tl);
if ($4) if ($4)
$$->vers_conditions= Lex->vers_conditions; tl->vers_conditions= Lex->vers_conditions;
} }
; ;

View File

@@ -4915,10 +4915,8 @@ bool TABLE_LIST::prep_where(THD *thd, Item **conds,
{ {
if (where->fixed) if (where->fixed)
where->update_used_tables(); where->update_used_tables();
if (!where->fixed && where->fix_fields(thd, &where)) else if (where->fix_fields(thd, &where))
{
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
}
/* /*
check that it is not VIEW in which we insert with INSERT SELECT check that it is not VIEW in which we insert with INSERT SELECT
@@ -4948,12 +4946,12 @@ bool TABLE_LIST::prep_where(THD *thd, Item **conds,
} }
if (tbl == 0) if (tbl == 0)
{ {
if (*conds && !(*conds)->fixed) if (*conds)
res= (*conds)->fix_fields(thd, conds); res= (*conds)->fix_fields_if_needed_for_bool(thd, conds);
if (!res) if (!res)
*conds= and_conds(thd, *conds, where->copy_andor_structure(thd)); *conds= and_conds(thd, *conds, where->copy_andor_structure(thd));
if (*conds && !(*conds)->fixed && !res) if (*conds && !res)
res= (*conds)->fix_fields(thd, conds); res= (*conds)->fix_fields_if_needed_for_bool(thd, conds);
} }
if (arena) if (arena)
thd->restore_active_arena(arena, &backup); thd->restore_active_arena(arena, &backup);
@@ -5100,12 +5098,8 @@ bool TABLE_LIST::prep_check_option(THD *thd, uint8 check_opt_type)
{ {
const char *save_where= thd->where; const char *save_where= thd->where;
thd->where= "check option"; thd->where= "check option";
if ((!check_option->fixed && if (check_option->fix_fields_if_needed_for_bool(thd, &check_option))
check_option->fix_fields(thd, &check_option)) ||
check_option->check_cols(1))
{
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
}
thd->where= save_where; thd->where= save_where;
} }
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
@@ -8736,7 +8730,7 @@ bool Vers_history_point::resolve_unit(THD *thd)
{ {
if (!item) if (!item)
return false; return false;
if (!item->fixed && item->fix_fields(thd, &item)) if (item->fix_fields_if_needed(thd, &item))
return true; return true;
return item->this_item()->type_handler_for_system_time()-> return item->this_item()->type_handler_for_system_time()->
Vers_history_point_resolve_unit(thd, this); Vers_history_point_resolve_unit(thd, this);

View File

@@ -1830,7 +1830,6 @@ public:
struct vers_select_conds_t struct vers_select_conds_t
{ {
vers_system_time_t type; vers_system_time_t type;
bool from_query:1;
bool used:1; bool used:1;
Vers_history_point start; Vers_history_point start;
Vers_history_point end; Vers_history_point end;
@@ -1838,7 +1837,7 @@ struct vers_select_conds_t
void empty() void empty()
{ {
type= SYSTEM_TIME_UNSPECIFIED; type= SYSTEM_TIME_UNSPECIFIED;
used= from_query= false; used= false;
start.empty(); start.empty();
end.empty(); end.empty();
} }
@@ -1848,7 +1847,7 @@ struct vers_select_conds_t
Vers_history_point _end= Vers_history_point()) Vers_history_point _end= Vers_history_point())
{ {
type= _type; type= _type;
used= from_query= false; used= false;
start= _start; start= _start;
end= _end; end= _end;
} }
@@ -1862,10 +1861,6 @@ struct vers_select_conds_t
return type != SYSTEM_TIME_UNSPECIFIED; return type != SYSTEM_TIME_UNSPECIFIED;
} }
bool resolve_units(THD *thd); bool resolve_units(THD *thd);
bool user_defined() const
{
return !from_query && type != SYSTEM_TIME_UNSPECIFIED;
}
bool eq(const vers_select_conds_t &conds) const; bool eq(const vers_select_conds_t &conds) const;
}; };

View File

@@ -1057,9 +1057,8 @@ static bool make_empty_rec(THD *thd, uchar *buff, uint table_options,
field->real_field_type() == MYSQL_TYPE_GEOMETRY)) field->real_field_type() == MYSQL_TYPE_GEOMETRY))
{ {
Item *expr= field->default_value->expr; Item *expr= field->default_value->expr;
// may be already fixed if ALTER TABLE
int res= !expr->fixed && // may be already fixed if ALTER TABLE int res= expr->fix_fields_if_needed(thd, &expr);
expr->fix_fields(thd, &expr);
if (!res) if (!res)
res= expr->save_in_field(regfield, 1); res= expr->save_in_field(regfield, 1);
if (!res && (field->flags & BLOB_FLAG)) if (!res && (field->flags & BLOB_FLAG))

View File

@@ -2612,37 +2612,7 @@ dict_index_remove_from_cache_low(
UT_LIST_REMOVE(table->indexes, index); UT_LIST_REMOVE(table->indexes, index);
/* Remove the index from affected virtual column index list */ /* Remove the index from affected virtual column index list */
if (dict_index_has_virtual(index)) { index->detach_columns();
const dict_col_t* col;
const dict_v_col_t* vcol;
for (ulint i = 0; i < dict_index_get_n_fields(index); i++) {
col = dict_index_get_nth_col(index, i);
if (col->is_virtual()) {
vcol = reinterpret_cast<const dict_v_col_t*>(
col);
/* This could be NULL, when we do add virtual
column, add index together. We do not need to
track this virtual column's index */
if (vcol->v_indexes == NULL) {
continue;
}
dict_v_idx_list::iterator it;
for (it = vcol->v_indexes->begin();
it != vcol->v_indexes->end(); ++it) {
dict_v_idx_t v_index = *it;
if (v_index.index == index) {
vcol->v_indexes->erase(it);
break;
}
}
}
}
}
dict_mem_index_free(index); dict_mem_index_free(index);
} }

View File

@@ -58,10 +58,6 @@ Smart ALTER TABLE
#include "ha_innodb.h" #include "ha_innodb.h"
#include "ut0new.h" #include "ut0new.h"
#include "ut0stage.h" #include "ut0stage.h"
#ifdef WITH_WSREP
//#include "wsrep_api.h"
#include <sql_acl.h> // PROCESS_ACL
#endif
static const char *MSG_UNSUPPORTED_ALTER_ONLINE_ON_VIRTUAL_COLUMN= static const char *MSG_UNSUPPORTED_ALTER_ONLINE_ON_VIRTUAL_COLUMN=
"INPLACE ADD or DROP of virtual columns cannot be " "INPLACE ADD or DROP of virtual columns cannot be "
@@ -289,6 +285,16 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx
@return whether the table will be rebuilt */ @return whether the table will be rebuilt */
bool need_rebuild () const { return(old_table != new_table); } bool need_rebuild () const { return(old_table != new_table); }
/** Clear uncommmitted added indexes after a failed operation. */
void clear_added_indexes()
{
for (ulint i = 0; i < num_to_add_index; i++) {
if (!add_index[i]->is_committed()) {
add_index[i]->detach_columns();
}
}
}
/** Convert table-rebuilding ALTER to instant ALTER. */ /** Convert table-rebuilding ALTER to instant ALTER. */
void prepare_instant() void prepare_instant()
{ {
@@ -6726,7 +6732,8 @@ check_if_can_drop_indexes:
for (dict_index_t* index = dict_table_get_first_index(indexed_table); for (dict_index_t* index = dict_table_get_first_index(indexed_table);
index != NULL; index = dict_table_get_next_index(index)) { index != NULL; index = dict_table_get_next_index(index)) {
if (!index->to_be_dropped && index->is_corrupted()) { if (!index->to_be_dropped && index->is_committed()
&& index->is_corrupted()) {
my_error(ER_INDEX_CORRUPT, MYF(0), index->name()); my_error(ER_INDEX_CORRUPT, MYF(0), index->name());
goto err_exit; goto err_exit;
} }
@@ -7293,6 +7300,7 @@ oom:
that we hold at most a shared lock on the table. */ that we hold at most a shared lock on the table. */
m_prebuilt->trx->error_info = NULL; m_prebuilt->trx->error_info = NULL;
ctx->trx->error_state = DB_SUCCESS; ctx->trx->error_state = DB_SUCCESS;
ctx->clear_added_indexes();
DBUG_RETURN(true); DBUG_RETURN(true);
} }

View File

@@ -731,13 +731,9 @@ dict_index_is_spatial(
/*==================*/ /*==================*/
const dict_index_t* index) /*!< in: index */ const dict_index_t* index) /*!< in: index */
MY_ATTRIBUTE((warn_unused_result)); MY_ATTRIBUTE((warn_unused_result));
/** Check whether the index contains a virtual column.
@param[in] index index #define dict_index_has_virtual(index) (index)->has_virtual()
@return nonzero for index on virtual column, zero for other indexes */
UNIV_INLINE
ulint
dict_index_has_virtual(
const dict_index_t* index);
/********************************************************************//** /********************************************************************//**
Check whether the index is the insert buffer tree. Check whether the index is the insert buffer tree.
@return nonzero for insert buffer, zero for other indexes */ @return nonzero for insert buffer, zero for other indexes */

View File

@@ -314,20 +314,6 @@ dict_index_is_spatial(
return ulint(UNIV_EXPECT(index->type & DICT_SPATIAL, 0)); return ulint(UNIV_EXPECT(index->type & DICT_SPATIAL, 0));
} }
/** Check whether the index contains a virtual column
@param[in] index index
@return nonzero for the index has virtual column, zero for other indexes */
UNIV_INLINE
ulint
dict_index_has_virtual(
const dict_index_t* index)
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
return(index->type & DICT_VIRTUAL);
}
/********************************************************************//** /********************************************************************//**
Check whether the index is the insert buffer tree. Check whether the index is the insert buffer tree.
@return nonzero for insert buffer, zero for other indexes */ @return nonzero for insert buffer, zero for other indexes */

View File

@@ -588,6 +588,10 @@ struct dict_col_t{
3072 (REC_VERSION_56_MAX_INDEX_COL_LEN) 3072 (REC_VERSION_56_MAX_INDEX_COL_LEN)
bytes. */ bytes. */
/** Detach the column from an index.
@param[in] index index to be detached from */
inline void detach(const dict_index_t& index);
/** Data for instantly added columns */ /** Data for instantly added columns */
struct { struct {
/** original default value of instantly added column */ /** original default value of instantly added column */
@@ -1045,9 +1049,24 @@ struct dict_index_t{
return DICT_CLUSTERED == (type & (DICT_CLUSTERED | DICT_IBUF)); return DICT_CLUSTERED == (type & (DICT_CLUSTERED | DICT_IBUF));
} }
/** @return whether the index includes virtual columns */
bool has_virtual() const { return type & DICT_VIRTUAL; }
/** @return whether the index is corrupted */ /** @return whether the index is corrupted */
inline bool is_corrupted() const; inline bool is_corrupted() const;
/** Detach the columns from the index that is to be freed. */
void detach_columns()
{
if (has_virtual()) {
for (unsigned i = 0; i < n_fields; i++) {
fields[i].col->detach(*this);
}
n_fields = 0;
}
}
/** Determine how many fields of a given prefix can be set NULL. /** Determine how many fields of a given prefix can be set NULL.
@param[in] n_prefix number of fields in the prefix @param[in] n_prefix number of fields in the prefix
@return number of fields 0..n_prefix-1 that can be set NULL */ @return number of fields 0..n_prefix-1 that can be set NULL */
@@ -1112,6 +1131,26 @@ struct dict_index_t{
vers_history_row(const rec_t* rec, bool &history_row); vers_history_row(const rec_t* rec, bool &history_row);
}; };
/** Detach a column from an index.
@param[in] index index to be detached from */
inline void dict_col_t::detach(const dict_index_t& index)
{
if (!is_virtual()) {
return;
}
if (dict_v_idx_list* v_indexes = reinterpret_cast<const dict_v_col_t*>
(this)->v_indexes) {
for (dict_v_idx_list::iterator i = v_indexes->begin();
i != v_indexes->end(); i++) {
if (i->index == &index) {
v_indexes->erase(i);
return;
}
}
}
}
/** The status of online index creation */ /** The status of online index creation */
enum online_index_status { enum online_index_status {
/** the index is complete and ready for access */ /** the index is complete and ready for access */

View File

@@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (C) 2013, 2015, Google Inc. All Rights Reserved. Copyright (C) 2013, 2015, Google Inc. All Rights Reserved.
Copyright (C) 2014, 2017, MariaDB Corporation. All Rights Reserved. Copyright (C) 2014, 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the Free Software the terms of the GNU General Public License as published by the Free Software
@@ -160,7 +160,7 @@ static bool init_crypt_key(crypt_info_t* info, bool upgrade = false)
<< "Obtaining redo log encryption key version " << "Obtaining redo log encryption key version "
<< info->key_version << " failed (" << rc << info->key_version << " failed (" << rc
<< "). Maybe the key or the required encryption " << "). Maybe the key or the required encryption "
<< " key management plugin was not found."; "key management plugin was not found.";
return false; return false;
} }
@@ -280,7 +280,12 @@ log_crypt_101_read_block(byte* buf)
} }
} }
if (infos_used == 0) {
return false; return false;
}
/* MariaDB Server 10.1 would use the first key if it fails to
find a key for the current checkpoint. */
info = infos;
found: found:
byte dst[OS_FILE_LOG_BLOCK_SIZE]; byte dst[OS_FILE_LOG_BLOCK_SIZE];
uint dst_len; uint dst_len;

View File

@@ -858,12 +858,11 @@ recv_find_max_checkpoint_0(ulint* max_field)
/** Determine if a pre-MySQL 5.7.9/MariaDB 10.2.2 redo log is clean. /** Determine if a pre-MySQL 5.7.9/MariaDB 10.2.2 redo log is clean.
@param[in] lsn checkpoint LSN @param[in] lsn checkpoint LSN
@param[in] crypt whether the log might be encrypted
@return error code @return error code
@retval DB_SUCCESS if the redo log is clean @retval DB_SUCCESS if the redo log is clean
@retval DB_ERROR if the redo log is corrupted or dirty */ @retval DB_ERROR if the redo log is corrupted or dirty */
static static dberr_t recv_log_format_0_recover(lsn_t lsn, bool crypt)
dberr_t
recv_log_format_0_recover(lsn_t lsn)
{ {
log_mutex_enter(); log_mutex_enter();
const lsn_t source_offset = log_sys.log.calc_lsn_offset(lsn); const lsn_t source_offset = log_sys.log.calc_lsn_offset(lsn);
@@ -891,7 +890,13 @@ recv_log_format_0_recover(lsn_t lsn)
} }
if (log_block_get_data_len(buf) if (log_block_get_data_len(buf)
!= (source_offset & (OS_FILE_LOG_BLOCK_SIZE - 1))) { == (source_offset & (OS_FILE_LOG_BLOCK_SIZE - 1))) {
} else if (crypt) {
ib::error() << "Cannot decrypt log for upgrading."
" The encrypted log was created"
" before MariaDB 10.2.2.";
return DB_ERROR;
} else {
ib::error() << NO_UPGRADE_RECOVERY_MSG << "."; ib::error() << NO_UPGRADE_RECOVERY_MSG << ".";
return(DB_ERROR); return(DB_ERROR);
} }
@@ -3153,7 +3158,8 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)
switch (log_sys.log.format) { switch (log_sys.log.format) {
case 0: case 0:
log_mutex_exit(); log_mutex_exit();
return(recv_log_format_0_recover(checkpoint_lsn)); return recv_log_format_0_recover(checkpoint_lsn,
buf[20 + 32 * 9] == 2);
default: default:
if (end_lsn == 0) { if (end_lsn == 0) {
break; break;

View File

@@ -581,7 +581,7 @@ row_upd_changes_field_size_or_external(
/* We should ignore virtual field if the index is not /* We should ignore virtual field if the index is not
a virtual index */ a virtual index */
if (upd_fld_is_virtual_col(upd_field) if (upd_fld_is_virtual_col(upd_field)
&& dict_index_has_virtual(index) != DICT_VIRTUAL) { && !index->has_virtual()) {
continue; continue;
} }