
[Commits] 318097b: MDEV-15480 Audit plugin does not respect QUERY_DML for audit plugin.
by holyfoot@askmonty.org 10 May '18
by holyfoot@askmonty.org 10 May '18
10 May '18
revision-id: 318097bb8f6e12c546b5dcd287416158209dbb39 (mariadb-5.5.60-8-g318097b)
parent(s): 1d58d184c2c4ddd8a3b2be6f86d76c4e57bbe14f
committer: Alexey Botchkov
timestamp: 2018-05-10 19:00:54 +0400
message:
MDEV-15480 Audit plugin does not respect QUERY_DML for audit plugin.
QUERY_DML_NO_SELECT flag added.
---
mysql-test/suite/plugins/r/server_audit.result | 12 +++++++++++
mysql-test/suite/plugins/t/server_audit.test | 7 +++++++
plugin/server_audit/server_audit.c | 29 ++++++++++++++++++++++----
3 files changed, 44 insertions(+), 4 deletions(-)
diff --git a/mysql-test/suite/plugins/r/server_audit.result b/mysql-test/suite/plugins/r/server_audit.result
index 80b4345..2e18a48 100644
--- a/mysql-test/suite/plugins/r/server_audit.result
+++ b/mysql-test/suite/plugins/r/server_audit.result
@@ -182,6 +182,17 @@ select 2;
2
2
drop table t1;
+set global server_audit_events='query_dml_no_select';
+create table t1(id int);
+insert into t1 values (1), (2);
+select * from t1;
+id
+1
+2
+select 2;
+2
+2
+drop table t1;
set global server_audit_events='';
set global server_audit_query_log_limit= 15;
select (1), (2), (3), (4);
@@ -332,6 +343,7 @@ TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD \n# comment\nFOR u1
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD FOR u1=<secret>',ID
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u3 IDENTIFIED BY *****',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'drop user u1, u2, u3',0
+TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'insert into t1 values (1), (2)',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'set global server_audit_events=\'\'',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'set global serv',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'select (1), (2)',0
diff --git a/mysql-test/suite/plugins/t/server_audit.test b/mysql-test/suite/plugins/t/server_audit.test
index 6c5eaff..4af1ed8 100644
--- a/mysql-test/suite/plugins/t/server_audit.test
+++ b/mysql-test/suite/plugins/t/server_audit.test
@@ -121,6 +121,13 @@ select 2;
/*! select 2*/;
/*comment*/ select 2;
drop table t1;
+set global server_audit_events='query_dml_no_select';
+create table t1(id int);
+insert into t1 values (1), (2);
+select * from t1;
+select 2;
+drop table t1;
+
set global server_audit_events='';
set global server_audit_query_log_limit= 15;
diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c
index 9a3418e..d27da28 100644
--- a/plugin/server_audit/server_audit.c
+++ b/plugin/server_audit/server_audit.c
@@ -15,7 +15,7 @@
#define PLUGIN_VERSION 0x104
-#define PLUGIN_STR_VERSION "1.4.3"
+#define PLUGIN_STR_VERSION "1.4.4"
#define _my_thread_var loc_thread_var
@@ -366,16 +366,17 @@ static MYSQL_SYSVAR_STR(excl_users, excl_users, PLUGIN_VAR_RQCMDARG,
/* bits in the event filter. */
#define EVENT_CONNECT 1
#define EVENT_QUERY_ALL 2
-#define EVENT_QUERY 58
+#define EVENT_QUERY 122
#define EVENT_TABLE 4
#define EVENT_QUERY_DDL 8
#define EVENT_QUERY_DML 16
#define EVENT_QUERY_DCL 32
+#define EVENT_QUERY_DML_NO_SELECT 64
static const char *event_names[]=
{
"CONNECT", "QUERY", "TABLE", "QUERY_DDL", "QUERY_DML", "QUERY_DCL",
- NULL
+ "QUERY_DML_NO_SELECT", NULL
};
static TYPELIB events_typelib=
{
@@ -383,7 +384,7 @@ static TYPELIB events_typelib=
};
static MYSQL_SYSVAR_SET(events, events, PLUGIN_VAR_RQCMDARG,
"Specifies the set of events to monitor. Can be CONNECT, QUERY, TABLE,"
- " QUERY_DDL, QUERY_DML, QUERY_DCL.",
+ " QUERY_DDL, QUERY_DML, QUERY_DML_NO_SELECT, QUERY_DCL.",
NULL, NULL, 0, &events_typelib);
#define OUTPUT_SYSLOG 0
#define OUTPUT_FILE 1
@@ -857,6 +858,21 @@ struct sa_keyword dml_keywords[]=
};
+struct sa_keyword dml_no_select_keywords[]=
+{
+ {2, "DO", 0, SQLCOM_DML},
+ {4, "CALL", 0, SQLCOM_DML},
+ {4, "LOAD", &data_word, SQLCOM_DML},
+ {4, "LOAD", &xml_word, SQLCOM_DML},
+ {6, "DELETE", 0, SQLCOM_DML},
+ {6, "INSERT", 0, SQLCOM_DML},
+ {6, "UPDATE", 0, SQLCOM_DML},
+ {7, "HANDLER", 0, SQLCOM_DML},
+ {7, "REPLACE", 0, SQLCOM_DML},
+ {0, NULL, 0, SQLCOM_DML}
+};
+
+
struct sa_keyword dcl_keywords[]=
{
{6, "CREATE", &user_word, SQLCOM_DCL},
@@ -1637,6 +1653,11 @@ static int log_statement_ex(const struct connection_info *cn,
if (filter_query_type(query, dml_keywords))
goto do_log_query;
}
+ if (events & EVENT_QUERY_DML_NO_SELECT)
+ {
+ if (filter_query_type(query, dml_no_select_keywords))
+ goto do_log_query;
+ }
if (events & EVENT_QUERY_DCL)
{
if (filter_query_type(query, dcl_keywords))
1
0

[Commits] eae5844ca04: MDEV-15576: Server crashed in Cached_item_str::cmp / sortcmp or Assertion `item->null_value' failed in Type_handler_temporal_result::make_sort_key upon SELECT with NULLIF and ROLLUP
by Oleksandr Byelkin 09 May '18
by Oleksandr Byelkin 09 May '18
09 May '18
revision-id: eae5844ca04c89823cc9ee88095cf89aa45cdb69 (mariadb-10.3.6-127-geae5844ca04)
parent(s): 4513de3127df61fa2030690110bb34b7e1c40849
author: Oleksandr Byelkin
committer: Oleksandr Byelkin
timestamp: 2018-05-09 13:39:13 +0200
message:
MDEV-15576: Server crashed in Cached_item_str::cmp / sortcmp or Assertion `item->null_value' failed in Type_handler_temporal_result::make_sort_key upon SELECT with NULLIF and ROLLUP
Fix Item_func_rollup_const::get_date to process correctly NULL value.
---
mysql-test/main/olap.result | 14 ++++++++++++++
mysql-test/main/olap.test | 17 +++++++++++++++++
sql/item_func.h | 4 +++-
3 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/mysql-test/main/olap.result b/mysql-test/main/olap.result
index bcc96d4951d..6fdbe008016 100644
--- a/mysql-test/main/olap.result
+++ b/mysql-test/main/olap.result
@@ -816,3 +816,17 @@ a int(11) YES 0
b int(20) YES 0
DROP VIEW v1;
DROP TABLE t1;
+#
+# MDEV-15576: Server crashed in Cached_item_str::cmp / sortcmp or
+# Assertion `item->null_value' failed in
+# Type_handler_temporal_result::make_sort_key upon SELECT with NULLIF
+# and ROLLUP
+#
+CREATE TABLE t1 (i INT);
+INSERT INTO t1 VALUES (1),(2);
+SELECT NULLIF( CAST( 'foo' AS DATE ), NULL & 'bar' ) AS f FROM t1 GROUP BY f WITH ROLLUP;
+f
+NULL
+NULL
+DROP TABLE t1;
+# End of 10.3 Tests
diff --git a/mysql-test/main/olap.test b/mysql-test/main/olap.test
index 3da08581a87..74dbe8ba10b 100644
--- a/mysql-test/main/olap.test
+++ b/mysql-test/main/olap.test
@@ -447,3 +447,20 @@ DESC v1;
DROP VIEW v1;
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-15576: Server crashed in Cached_item_str::cmp / sortcmp or
+--echo # Assertion `item->null_value' failed in
+--echo # Type_handler_temporal_result::make_sort_key upon SELECT with NULLIF
+--echo # and ROLLUP
+--echo #
+
+CREATE TABLE t1 (i INT);
+INSERT INTO t1 VALUES (1),(2);
+--disable_warnings
+SELECT NULLIF( CAST( 'foo' AS DATE ), NULL & 'bar' ) AS f FROM t1 GROUP BY f WITH ROLLUP;
+--enable_warnings
+DROP TABLE t1;
+
+
+--echo # End of 10.3 Tests
diff --git a/sql/item_func.h b/sql/item_func.h
index 29ff14f7b39..c203a21cc2b 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1613,7 +1613,9 @@ class Item_func_rollup_const :public Item_func
my_decimal *val_decimal(my_decimal *dec) { return args[0]->val_decimal(dec); }
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
{
- return args[0]->get_date(ltime, fuzzydate);
+ bool rc= args[0]->get_date(ltime, fuzzydate);
+ null_value= rc;
+ return rc;
}
const char *func_name() const { return "rollup_const"; }
bool const_item() const { return 0; }
1
0

[Commits] 38cfcd7de13: MDEV-15373 engine gtid_slave_pos table name disobeys lower-case-table-names
by andrei.elkin@pp.inet.fi 09 May '18
by andrei.elkin@pp.inet.fi 09 May '18
09 May '18
revision-id: 38cfcd7de138977a80e116bc3911190ac803af13 (mariadb-10.3.6-81-g38cfcd7de13)
parent(s): baa5a43d8cb2f747eeb70d394a362fb5f3fdd194
author: Andrei Elkin
committer: Andrei Elkin
timestamp: 2018-05-08 22:17:18 +0300
message:
MDEV-15373 engine gtid_slave_pos table name disobeys lower-case-table-names
Replicated transaction extra gtid statement on slave failed to specify
an engine gtid_slave_pos name correctly. In case lower-case-table-names > 0
the InnoDB table name was generated to reproduce the lower-case-table-names=0 version
which is of mixed cases.
In rpl.rpl_mdev12179 test run this triggered a failure to DROP table which
was due to the innodb table handle was not closed:
InnoDB: Waited XYZ seconds for ref-count on table: `mysql`.`gtid_slave_pos_innodb`
on windows.
The closing issue was caused by having the table registered twice in the table cache,
for its lower- and mixed- case name versions. The DROP-table handler closed only
only one of the cache item to leave the 2nd one active.
(On Linux a failure occurs earlier at attempt to open an expected lower-cased table:
Last_Error: Error during XID COMMIT: failed to update GTID state in mysql.gtid_slave_pos: 1146: Table 'mysql.gtid_slave_pos_InnoDB' doesn't exist
but the table's name as the message shows is not in the right case).
Fixed with consulting lower-case-table-names when the engine gtid-slave-pos table
is created.
Note the lower-case-table-names=a-value created table will not recognized when next
the lower case option changes to a different value.
---
mysql-test/suite/rpl/r/rpl_mdev12179.result | 21 +++++++++++-----
mysql-test/suite/rpl/t/rpl_mdev12179.test | 38 +++++++++++++++++++++++++++--
sql/rpl_rli.cc | 1 +
3 files changed, 52 insertions(+), 8 deletions(-)
diff --git a/mysql-test/suite/rpl/r/rpl_mdev12179.result b/mysql-test/suite/rpl/r/rpl_mdev12179.result
index 40059375356..08b1de083af 100644
--- a/mysql-test/suite/rpl/r/rpl_mdev12179.result
+++ b/mysql-test/suite/rpl/r/rpl_mdev12179.result
@@ -152,12 +152,12 @@ a
1
2
*** Verify that mysql.gtid_slave_pos_InnoDB is auto-created ***
-SELECT table_name, engine FROM information_schema.tables
+SELECT lower(table_name), engine FROM information_schema.tables
WHERE table_schema='mysql' AND table_name LIKE 'gtid_slave_pos%'
ORDER BY table_name;
-table_name engine
+lower(table_name) engine
gtid_slave_pos MyISAM
-gtid_slave_pos_InnoDB InnoDB
+gtid_slave_pos_innodb InnoDB
include/stop_slave.inc
SET sql_log_bin=0;
INSERT INTO mysql.gtid_slave_pos SELECT * FROM mysql.gtid_slave_pos_InnoDB;
@@ -245,15 +245,24 @@ a
3
4
*** Verify that mysql.gtid_slave_pos_InnoDB is auto-created ***
-SELECT table_name, engine FROM information_schema.tables
+SELECT lower(table_name), engine FROM information_schema.tables
WHERE table_schema='mysql' AND table_name LIKE 'gtid_slave_pos%'
ORDER BY table_name;
-table_name engine
+lower(table_name) engine
gtid_slave_pos MyISAM
-gtid_slave_pos_InnoDB InnoDB
+gtid_slave_pos_innodb InnoDB
SELECT domain_id, max(seq_no) FROM mysql.gtid_slave_pos GROUP BY domain_id;
domain_id max(seq_no)
0 13
+connection server_2;
+*** Restart the slave server to prove 'gtid_slave_pos_innodb' autodiscovery ***
+connection server_2;
+SELECT max(seq_no) FROM mysql.gtid_slave_pos_InnoDB into @seq_no;
+connection server_1;
+INSERT INTO t2(a) SELECT 1+MAX(a) FROM t2;
+include/save_master_gtid.inc
+connection server_2;
+include/sync_with_master_gtid.inc
include/stop_slave.inc
SET GLOBAL gtid_pos_auto_engines="";
SET sql_log_bin=0;
diff --git a/mysql-test/suite/rpl/t/rpl_mdev12179.test b/mysql-test/suite/rpl/t/rpl_mdev12179.test
index a9113c91797..dac1881f40a 100644
--- a/mysql-test/suite/rpl/t/rpl_mdev12179.test
+++ b/mysql-test/suite/rpl/t/rpl_mdev12179.test
@@ -161,7 +161,8 @@ let $wait_condition=
SELECT EXISTS (SELECT * FROM information_schema.tables
WHERE table_schema='mysql' AND table_name='gtid_slave_pos_InnoDB');
--source include/wait_condition.inc
-SELECT table_name, engine FROM information_schema.tables
+# MDEV-15373 lowercases 'table_name' to satisfy --lower-case-table-names options
+SELECT lower(table_name), engine FROM information_schema.tables
WHERE table_schema='mysql' AND table_name LIKE 'gtid_slave_pos%'
ORDER BY table_name;
@@ -225,7 +226,7 @@ let $wait_condition=
SELECT EXISTS (SELECT * FROM information_schema.tables
WHERE table_schema='mysql' AND table_name='gtid_slave_pos_InnoDB');
--source include/wait_condition.inc
-SELECT table_name, engine FROM information_schema.tables
+SELECT lower(table_name), engine FROM information_schema.tables
WHERE table_schema='mysql' AND table_name LIKE 'gtid_slave_pos%'
ORDER BY table_name;
SELECT domain_id, max(seq_no) FROM mysql.gtid_slave_pos GROUP BY domain_id;
@@ -265,6 +266,39 @@ while (!$done)
# Note that at this point, the contents of table t2, as well as the GTID
# position, is non-deterministic.
+# MDEV-15373 engine gtid_slave_pos table name disobeys lower-case-table-names
+# This snippet verifies that engine gtid_slave_pos table is found,
+# its data are up-to-date.
+--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
+wait
+EOF
+--connection server_2
+--shutdown_server 30
+--source include/wait_until_disconnected.inc
+
+--echo *** Restart the slave server to prove 'gtid_slave_pos_innodb' autodiscovery ***
+--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
+restart: --skip-slave-start=0
+EOF
+
+--connection server_2
+--enable_reconnect
+--source include/wait_until_connected_again.inc
+SELECT max(seq_no) FROM mysql.gtid_slave_pos_InnoDB into @seq_no;
+
+--connection server_1
+INSERT INTO t2(a) SELECT 1+MAX(a) FROM t2;
+--source include/save_master_gtid.inc
+
+--connection server_2
+--source include/sync_with_master_gtid.inc
+if (`SELECT max(seq_no) <> @seq_no + 1 FROM mysql.gtid_slave_pos_InnoDB`)
+{
+ SELECT * FROM mysql.gtid_slave_pos_InnoDB;
+ --die Inconsistent table
+}
+#
+# end of MDEV-15373
#--connection server_2
--source include/stop_slave.inc
diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc
index 6229f3e1faf..350c3528f61 100644
--- a/sql/rpl_rli.cc
+++ b/sql/rpl_rli.cc
@@ -1782,6 +1782,7 @@ gtid_pos_auto_create_tables(rpl_slave_state::gtid_pos_table **list_ptr)
p= strmake(p, plugin_name(*auto_engines)->str, FN_REFLEN - (p - buf));
table_name.str= buf;
table_name.length= p - buf;
+ table_case_convert(const_cast<char*>(table_name.str), table_name.length);
entry= rpl_global_gtid_slave_state->alloc_gtid_pos_table
(&table_name, hton, rpl_slave_state::GTID_POS_AUTO_CREATE);
if (!entry)
1
0

[Commits] 0efb1e5: MDEV-16104 Server crash in JOIN::fix_all_splittings_in_plan
by IgorBabaev 09 May '18
by IgorBabaev 09 May '18
09 May '18
revision-id: 0efb1e502f2b77ae483cc7894beaeaab575e9b6f (mariadb-10.3.6-112-g0efb1e5)
parent(s): 0bfd45f63419c45b68448cbd210a6e73e5c1ab34
author: Igor Babaev
committer: Igor Babaev
timestamp: 2018-05-08 23:32:11 -0700
message:
MDEV-16104 Server crash in JOIN::fix_all_splittings_in_plan
upon select with view and subqueries
This bug occurred when a splittable materialized derived/view
were used inside another splittable materialized derived/view.
The bug happened because the function JOIN::fix_all_splittings_in_plan()
was called at the very beginning of the optimization phase 2 at
the moment when the plan structure of the embedding derived/view
were not valid. The proper position for this call is the very
end of the optimization phase 1.
---
mysql-test/main/derived_cond_pushdown.result | 33 ++++++++++++++++++++++++++++
mysql-test/main/derived_cond_pushdown.test | 23 +++++++++++++++++++
sql/sql_select.cc | 15 ++++++++++---
3 files changed, 68 insertions(+), 3 deletions(-)
diff --git a/mysql-test/main/derived_cond_pushdown.result b/mysql-test/main/derived_cond_pushdown.result
index 82f621c..e178ceb 100644
--- a/mysql-test/main/derived_cond_pushdown.result
+++ b/mysql-test/main/derived_cond_pushdown.result
@@ -15165,3 +15165,36 @@ id select_type table type possible_keys key key_len ref rows Extra
3 DERIVED t1 ALL NULL NULL NULL NULL 5 Using temporary
2 DERIVED t1 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort
drop table t1;
+#
+# MDEV-16104: embedded splittable materialized derived/views
+#
+CREATE TABLE t1 (f int PRIMARY KEY) ENGINE=MyISAM;
+INSERT INTO t1
+VALUES (3), (7), (1), (4), (8), (5), (9);
+CREATE ALGORITHM=MERGE VIEW v1 AS
+SELECT a2.*
+FROM
+( SELECT f, COUNT(*) as c FROM t1 GROUP BY f ) AS a1
+JOIN
+t1 AS a2
+USING (f);
+EXPLAIN EXTENDED
+SELECT * FROM ( SELECT STRAIGHT_JOIN f, COUNT(*) as c FROM v1 GROUP BY f ) AS s;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 7 100.00
+2 DERIVED <derived4> ALL NULL NULL NULL NULL 7 100.00 Using temporary; Using filesort
+2 DERIVED a2 eq_ref PRIMARY PRIMARY 4 a1.f 1 100.00 Using index
+4 DERIVED t1 index PRIMARY PRIMARY 4 NULL 7 100.00 Using index; Using temporary; Using filesort
+Warnings:
+Note 1003 /* select#1 */ select `s`.`f` AS `f`,`s`.`c` AS `c` from (/* select#2 */ select straight_join `a2`.`f` AS `f`,count(0) AS `c` from ((/* select#4 */ select `test`.`t1`.`f` AS `f`,count(0) AS `c` from `test`.`t1` group by `test`.`t1`.`f`)) `a1` join `test`.`t1` `a2` where `a2`.`f` = `a1`.`f` group by `a2`.`f`) `s`
+SELECT * FROM ( SELECT STRAIGHT_JOIN f, COUNT(*) as c FROM v1 GROUP BY f ) AS s;
+f c
+1 1
+3 1
+4 1
+5 1
+7 1
+8 1
+9 1
+DROP VIEW v1;
+DROP TABLE t1;
diff --git a/mysql-test/main/derived_cond_pushdown.test b/mysql-test/main/derived_cond_pushdown.test
index 2e2ec69..5966412 100644
--- a/mysql-test/main/derived_cond_pushdown.test
+++ b/mysql-test/main/derived_cond_pushdown.test
@@ -2690,3 +2690,26 @@ eval $q;
eval explain $q;
drop table t1;
+
+--echo #
+--echo # MDEV-16104: embedded splittable materialized derived/views
+--echo #
+
+CREATE TABLE t1 (f int PRIMARY KEY) ENGINE=MyISAM;
+INSERT INTO t1
+ VALUES (3), (7), (1), (4), (8), (5), (9);
+
+CREATE ALGORITHM=MERGE VIEW v1 AS
+SELECT a2.*
+FROM
+ ( SELECT f, COUNT(*) as c FROM t1 GROUP BY f ) AS a1
+ JOIN
+ t1 AS a2
+ USING (f);
+
+EXPLAIN EXTENDED
+SELECT * FROM ( SELECT STRAIGHT_JOIN f, COUNT(*) as c FROM v1 GROUP BY f ) AS s;
+SELECT * FROM ( SELECT STRAIGHT_JOIN f, COUNT(*) as c FROM v1 GROUP BY f ) AS s;
+
+DROP VIEW v1;
+DROP TABLE t1;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 320e631..c45edf8 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1852,6 +1852,18 @@ JOIN::optimize_inner()
DBUG_RETURN(1);
}
+ /*
+ If a splittable materialized derived/view dt_i is embedded into
+ into another splittable materialized derived/view dt_o then
+ splitting plans for dt_i and dt_o are evaluated independently.
+ First the optimizer looks for the best splitting plan sp_i for dt_i.
+ It happens when non-splitting plans for dt_o are evaluated.
+ The cost of sp_i is considered as the cost of materialization of dt_i
+ when evaluating any splitting plan for dt_o.
+ */
+ if (fix_all_splittings_in_plan())
+ DBUG_RETURN(1);
+
setup_subq_exit:
with_two_phase_optimization= check_two_phase_optimization(thd);
if (with_two_phase_optimization)
@@ -9370,9 +9382,6 @@ bool JOIN::get_best_combination()
full_join=0;
hash_join= FALSE;
- if (fix_all_splittings_in_plan())
- DBUG_RETURN(TRUE);
-
fix_semijoin_strategies_for_picked_join_order(this);
JOIN_TAB_RANGE *root_range;
1
0

09 May '18
revision-id: b2fc197b566eb178afa09dd527f8e77a2d9b28de (mariadb-10.1.32-86-gb2fc197b566)
parent(s): f98496da969ed2b65f944f11ac11163030bc44b1
author: Jan Lindström
committer: Jan Lindström
timestamp: 2018-05-09 09:16:20 +0300
message:
MDEV-15351: wsrep_sst_xtrabackup is broken in 10.1.31
Remove the setup_ports function call. This is related to
https://github.com/MariaDB/server/pull/717
Thanks to Daniel Black and Bart S.
---
scripts/wsrep_sst_xtrabackup.sh | 1 -
1 file changed, 1 deletion(-)
diff --git a/scripts/wsrep_sst_xtrabackup.sh b/scripts/wsrep_sst_xtrabackup.sh
index 628c1f8b06c..5bf380a8144 100644
--- a/scripts/wsrep_sst_xtrabackup.sh
+++ b/scripts/wsrep_sst_xtrabackup.sh
@@ -408,7 +408,6 @@ if [[ ! ${WSREP_SST_OPT_ROLE} == 'joiner' && ! ${WSREP_SST_OPT_ROLE} == 'donor'
fi
read_cnf
-setup_ports
get_stream
get_transfer
1
0

[Commits] ce96028: MDEV-16088: Pushdown into materialized views/derived tables doesn't
by galina.shalygina@mariadb.com 08 May '18
by galina.shalygina@mariadb.com 08 May '18
08 May '18
revision-id: ce96028f690db1a4371e3846dbfb584c399486cb (mariadb-10.2.14-79-gce96028)
parent(s): bd1d152d05ba75bd1bdd2d9bc0358d8508df307a
author: Galina Shalygina
committer: Galina Shalygina
timestamp: 2018-05-08 18:22:38 +0200
message:
MDEV-16088: Pushdown into materialized views/derived tables doesn't
work in the IN subqueries
The pushdown into the materialized derived table/view wasn't done because
optimize() for the derived was called before any conditions that can
be pushed down were extracted. So optimize() in
convert_join_subqueries_to_semijoins() method is called too early and is
unnecessary. The second optimize() call in mysql_handle_single_derived()
is enough.
---
mysql-test/r/derived_cond_pushdown.result | 413 ++++++++++++++++++++++++++++++
mysql-test/r/derived_view.result | 4 +-
mysql-test/r/subselect_extra.result | 4 +-
mysql-test/t/derived_cond_pushdown.test | 83 ++++++
sql/opt_subselect.cc | 2 -
5 files changed, 500 insertions(+), 6 deletions(-)
diff --git a/mysql-test/r/derived_cond_pushdown.result b/mysql-test/r/derived_cond_pushdown.result
index 8e74e09..09b3b52 100644
--- a/mysql-test/r/derived_cond_pushdown.result
+++ b/mysql-test/r/derived_cond_pushdown.result
@@ -9045,3 +9045,416 @@ select * from (select date('2018-01-01') as d) as t
where t.d between date ('2017-01-01') and date ('2019-01-01');
d
2018-01-01
+#
+# MDEV-16088: pushdown into derived defined in the IN subquery
+#
+CREATE TABLE t1 (a INT, b INT);
+CREATE TABLE t2 (e INT, f INT, g INT);
+INSERT INTO t1 VALUES (1,14),(2,13),(1,19),(2,32),(3,24);
+INSERT INTO t2 VALUES (1,19,2),(3,24,1),(1,12,2),(3,11,3),(2,32,1);
+SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+(
+SELECT d_tab.e,d_tab.max_f
+FROM (
+SELECT t2.e, MAX(t2.f) AS max_f
+FROM t2
+GROUP BY t2.e
+HAVING max_f>18
+) as d_tab
+WHERE d_tab.e>1
+)
+;
+a b
+2 32
+3 24
+EXPLAIN SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+(
+SELECT d_tab.e,d_tab.max_f
+FROM (
+SELECT t2.e, MAX(t2.f) AS max_f
+FROM t2
+GROUP BY t2.e
+HAVING max_f>18
+) as d_tab
+WHERE d_tab.e>1
+)
+;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 5
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1
+2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 5 Using where
+3 DERIVED t2 ALL NULL NULL NULL NULL 5 Using where; Using temporary; Using filesort
+EXPLAIN FORMAT=JSON SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+(
+SELECT d_tab.e,d_tab.max_f
+FROM (
+SELECT t2.e, MAX(t2.f) AS max_f
+FROM t2
+GROUP BY t2.e
+HAVING max_f>18
+) as d_tab
+WHERE d_tab.e>1
+)
+;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 100
+ },
+ "table": {
+ "table_name": "<subquery2>",
+ "access_type": "eq_ref",
+ "possible_keys": ["distinct_key"],
+ "key": "distinct_key",
+ "key_length": "8",
+ "used_key_parts": ["e", "max_f"],
+ "ref": ["func", "func"],
+ "rows": 1,
+ "filtered": 100,
+ "materialized": {
+ "unique": 1,
+ "query_block": {
+ "select_id": 2,
+ "table": {
+ "table_name": "<derived3>",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 100,
+ "attached_condition": "d_tab.e > 1",
+ "materialized": {
+ "query_block": {
+ "select_id": 3,
+ "having_condition": "max_f > 18",
+ "filesort": {
+ "sort_key": "t2.e",
+ "temporary_table": {
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 100,
+ "attached_condition": "t2.e > 1"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+(
+SELECT d_tab.e,d_tab.max_f
+FROM (
+SELECT t2.e, MAX(t2.f) AS max_f
+FROM t2
+GROUP BY t2.e
+HAVING max_f>18
+) as d_tab
+WHERE d_tab.max_f<25
+)
+;
+a b
+1 19
+3 24
+EXPLAIN SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+(
+SELECT d_tab.e,d_tab.max_f
+FROM (
+SELECT t2.e, MAX(t2.f) AS max_f
+FROM t2
+GROUP BY t2.e
+HAVING max_f>18
+) as d_tab
+WHERE d_tab.max_f<25
+)
+;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 5
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1
+2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 5 Using where
+3 DERIVED t2 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort
+EXPLAIN FORMAT=JSON SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+(
+SELECT d_tab.e,d_tab.max_f
+FROM (
+SELECT t2.e, MAX(t2.f) AS max_f
+FROM t2
+GROUP BY t2.e
+HAVING max_f>18
+) as d_tab
+WHERE d_tab.max_f<25
+)
+;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 100
+ },
+ "table": {
+ "table_name": "<subquery2>",
+ "access_type": "eq_ref",
+ "possible_keys": ["distinct_key"],
+ "key": "distinct_key",
+ "key_length": "8",
+ "used_key_parts": ["e", "max_f"],
+ "ref": ["func", "func"],
+ "rows": 1,
+ "filtered": 100,
+ "materialized": {
+ "unique": 1,
+ "query_block": {
+ "select_id": 2,
+ "table": {
+ "table_name": "<derived3>",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 100,
+ "attached_condition": "d_tab.max_f < 25",
+ "materialized": {
+ "query_block": {
+ "select_id": 3,
+ "having_condition": "max_f > 18 and max_f < 25",
+ "filesort": {
+ "sort_key": "t2.e",
+ "temporary_table": {
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 100
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+(
+SELECT d_tab.e, MAX(d_tab.max_f) AS max_f
+FROM (
+SELECT t2.e, MAX(t2.f) as max_f, t2.g
+FROM t2
+GROUP BY t2.e
+) as d_tab
+WHERE d_tab.e>1
+GROUP BY d_tab.g
+)
+;
+a b
+2 32
+EXPLAIN SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+(
+SELECT d_tab.e, MAX(d_tab.max_f) AS max_f
+FROM (
+SELECT t2.e, MAX(t2.f) as max_f, t2.g
+FROM t2
+GROUP BY t2.e
+) as d_tab
+WHERE d_tab.e>1
+GROUP BY d_tab.g
+)
+;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 test.t1.a,test.t1.b 1
+2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 5 Using where; Using temporary
+3 DERIVED t2 ALL NULL NULL NULL NULL 5 Using where; Using temporary; Using filesort
+EXPLAIN FORMAT=JSON SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+(
+SELECT d_tab.e, MAX(d_tab.max_f) AS max_f
+FROM (
+SELECT t2.e, MAX(t2.f) as max_f, t2.g
+FROM t2
+GROUP BY t2.e
+) as d_tab
+WHERE d_tab.e>1
+GROUP BY d_tab.g
+)
+;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 100,
+ "attached_condition": "t1.a is not null and t1.b is not null"
+ },
+ "table": {
+ "table_name": "<subquery2>",
+ "access_type": "eq_ref",
+ "possible_keys": ["distinct_key"],
+ "key": "distinct_key",
+ "key_length": "8",
+ "used_key_parts": ["e", "max_f"],
+ "ref": ["test.t1.a", "test.t1.b"],
+ "rows": 1,
+ "filtered": 100,
+ "materialized": {
+ "unique": 1,
+ "query_block": {
+ "select_id": 2,
+ "temporary_table": {
+ "table": {
+ "table_name": "<derived3>",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 100,
+ "attached_condition": "d_tab.e > 1",
+ "materialized": {
+ "query_block": {
+ "select_id": 3,
+ "filesort": {
+ "sort_key": "t2.e",
+ "temporary_table": {
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 100,
+ "attached_condition": "t2.e > 1"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+(
+SELECT d_tab.e, MAX(d_tab.max_f) AS max_f
+FROM (
+SELECT t2.e, MAX(t2.f) as max_f, t2.g
+FROM t2
+GROUP BY t2.e
+) as d_tab
+WHERE d_tab.max_f>20
+GROUP BY d_tab.g
+)
+;
+a b
+2 32
+EXPLAIN SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+(
+SELECT d_tab.e, MAX(d_tab.max_f) AS max_f
+FROM (
+SELECT t2.e, MAX(t2.f) as max_f, t2.g
+FROM t2
+GROUP BY t2.e
+) as d_tab
+WHERE d_tab.max_f>20
+GROUP BY d_tab.g
+)
+;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 test.t1.a,test.t1.b 1
+2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 5 Using where; Using temporary
+3 DERIVED t2 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort
+EXPLAIN FORMAT=JSON SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+(
+SELECT d_tab.e, MAX(d_tab.max_f) AS max_f
+FROM (
+SELECT t2.e, MAX(t2.f) as max_f, t2.g
+FROM t2
+GROUP BY t2.e
+) as d_tab
+WHERE d_tab.max_f>20
+GROUP BY d_tab.g
+)
+;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 100,
+ "attached_condition": "t1.a is not null and t1.b is not null"
+ },
+ "table": {
+ "table_name": "<subquery2>",
+ "access_type": "eq_ref",
+ "possible_keys": ["distinct_key"],
+ "key": "distinct_key",
+ "key_length": "8",
+ "used_key_parts": ["e", "max_f"],
+ "ref": ["test.t1.a", "test.t1.b"],
+ "rows": 1,
+ "filtered": 100,
+ "materialized": {
+ "unique": 1,
+ "query_block": {
+ "select_id": 2,
+ "temporary_table": {
+ "table": {
+ "table_name": "<derived3>",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 100,
+ "attached_condition": "d_tab.max_f > 20",
+ "materialized": {
+ "query_block": {
+ "select_id": 3,
+ "having_condition": "max_f > 20",
+ "filesort": {
+ "sort_key": "t2.e",
+ "temporary_table": {
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 100
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+DROP TABLE t1,t2;
diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result
index df6ba08..d2804ce 100644
--- a/mysql-test/r/derived_view.result
+++ b/mysql-test/r/derived_view.result
@@ -1841,7 +1841,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 system NULL NULL NULL NULL 1
1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where
1 PRIMARY <derived3> ALL NULL NULL NULL NULL 3 Using where; Start temporary; End temporary
-3 DERIVED t1 ALL NULL NULL NULL NULL 3
+3 DERIVED t1 ALL NULL NULL NULL NULL 3 Using where
SELECT * FROM t3
WHERE t3.b IN (SELECT v1.b FROM v1, t2
WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
@@ -1856,7 +1856,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 system NULL NULL NULL NULL 1
1 PRIMARY <derived3> ref key1 key1 8 const,const 0 Start temporary
1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
-3 DERIVED t1 ALL NULL NULL NULL NULL 3
+3 DERIVED t1 ALL NULL NULL NULL NULL 3 Using where
SELECT * FROM t3
WHERE t3.b IN (SELECT v1.b FROM v1, t2
WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
diff --git a/mysql-test/r/subselect_extra.result b/mysql-test/r/subselect_extra.result
index 73642c0..a3a0f1f 100644
--- a/mysql-test/r/subselect_extra.result
+++ b/mysql-test/r/subselect_extra.result
@@ -434,7 +434,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 system NULL NULL NULL NULL 1
1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where
1 PRIMARY <derived3> ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t3); Using join buffer (flat, BNL join)
-3 DERIVED t1 ALL NULL NULL NULL NULL 3
+3 DERIVED t1 ALL NULL NULL NULL NULL 3 Using where
SELECT * FROM t3
WHERE t3.b IN (SELECT v1.b FROM v1, t2
WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
@@ -449,7 +449,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 system NULL NULL NULL NULL 1
1 PRIMARY <derived3> ref key1 key1 8 const,const 0 Start temporary
1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
-3 DERIVED t1 ALL NULL NULL NULL NULL 3
+3 DERIVED t1 ALL NULL NULL NULL NULL 3 Using where
SELECT * FROM t3
WHERE t3.b IN (SELECT v1.b FROM v1, t2
WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
diff --git a/mysql-test/t/derived_cond_pushdown.test b/mysql-test/t/derived_cond_pushdown.test
index 0b87738..e8f6e9c 100644
--- a/mysql-test/t/derived_cond_pushdown.test
+++ b/mysql-test/t/derived_cond_pushdown.test
@@ -1646,3 +1646,86 @@ select * from (select date('2018-01-01') as d
select * from (select date('2018-01-01') as d) as t
where t.d between date ('2017-01-01') and date ('2019-01-01');
+
+--echo #
+--echo # MDEV-16088: pushdown into derived defined in the IN subquery
+--echo #
+
+CREATE TABLE t1 (a INT, b INT);
+CREATE TABLE t2 (e INT, f INT, g INT);
+INSERT INTO t1 VALUES (1,14),(2,13),(1,19),(2,32),(3,24);
+INSERT INTO t2 VALUES (1,19,2),(3,24,1),(1,12,2),(3,11,3),(2,32,1);
+
+LET $query=
+SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+ (
+ SELECT d_tab.e,d_tab.max_f
+ FROM (
+ SELECT t2.e, MAX(t2.f) AS max_f
+ FROM t2
+ GROUP BY t2.e
+ HAVING max_f>18
+ ) as d_tab
+ WHERE d_tab.e>1
+ )
+;
+EVAL $query;
+EVAL EXPLAIN $query;
+EVAL EXPLAIN FORMAT=JSON $query;
+
+LET $query=
+SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+ (
+ SELECT d_tab.e,d_tab.max_f
+ FROM (
+ SELECT t2.e, MAX(t2.f) AS max_f
+ FROM t2
+ GROUP BY t2.e
+ HAVING max_f>18
+ ) as d_tab
+ WHERE d_tab.max_f<25
+ )
+;
+EVAL $query;
+EVAL EXPLAIN $query;
+EVAL EXPLAIN FORMAT=JSON $query;
+
+LET $query=
+SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+ (
+ SELECT d_tab.e, MAX(d_tab.max_f) AS max_f
+ FROM (
+ SELECT t2.e, MAX(t2.f) as max_f, t2.g
+ FROM t2
+ GROUP BY t2.e
+ ) as d_tab
+ WHERE d_tab.e>1
+ GROUP BY d_tab.g
+ )
+;
+EVAL $query;
+EVAL EXPLAIN $query;
+EVAL EXPLAIN FORMAT=JSON $query;
+
+LET $query=
+SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+ (
+ SELECT d_tab.e, MAX(d_tab.max_f) AS max_f
+ FROM (
+ SELECT t2.e, MAX(t2.f) as max_f, t2.g
+ FROM t2
+ GROUP BY t2.e
+ ) as d_tab
+ WHERE d_tab.max_f>20
+ GROUP BY d_tab.g
+ )
+;
+EVAL $query;
+EVAL EXPLAIN $query;
+EVAL EXPLAIN FORMAT=JSON $query;
+
+DROP TABLE t1,t2;
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index b28adae..5765278 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -1092,8 +1092,6 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
while ((in_subq= li++))
{
SELECT_LEX *subq_sel= in_subq->get_select_lex();
- if (subq_sel->handle_derived(thd->lex, DT_OPTIMIZE))
- DBUG_RETURN(1);
if (subq_sel->handle_derived(thd->lex, DT_MERGE))
DBUG_RETURN(TRUE);
subq_sel->update_used_tables();
1
0

[Commits] 46e0c8a9219: MDEV-11071: Assertion `thd->transaction.stmt.is_empty()' failed in Locked_tables_list::unlock_locked_table
by Oleksandr Byelkin 08 May '18
by Oleksandr Byelkin 08 May '18
08 May '18
revision-id: 46e0c8a921978e7b95adf3f17f3c85b18d9f9ef6 (mariadb-10.2.14-78-g46e0c8a9219)
parent(s): 9bcd0f5fea8ca26742b10d37b95a966c69909ff1
author: Oleksandr Byelkin
committer: Oleksandr Byelkin
timestamp: 2018-05-08 15:26:26 +0200
message:
MDEV-11071: Assertion `thd->transaction.stmt.is_empty()' failed in Locked_tables_list::unlock_locked_table
fix_length_and_dec now return result (error/OK)
---
mysql-test/r/alter_table.result | 11 +++
mysql-test/t/alter_table.test | 16 ++++
sql/item.h | 2 +-
sql/item_cmpfunc.cc | 106 ++++++++++++++++----------
sql/item_cmpfunc.h | 58 ++++++++------
sql/item_func.cc | 106 +++++++++++++++-----------
sql/item_func.h | 118 ++++++++++++++++-------------
sql/item_geofunc.cc | 9 ++-
sql/item_geofunc.h | 72 ++++++++++--------
sql/item_inetfunc.h | 12 ++-
sql/item_jsonfunc.cc | 57 +++++++++-----
sql/item_jsonfunc.h | 38 +++++-----
sql/item_strfunc.cc | 164 +++++++++++++++++++++++++---------------
sql/item_strfunc.h | 156 +++++++++++++++++++++++---------------
sql/item_subselect.cc | 19 +++--
sql/item_subselect.h | 8 +-
sql/item_sum.cc | 28 +++----
sql/item_sum.h | 30 ++++----
sql/item_timefunc.cc | 46 ++++++-----
sql/item_timefunc.h | 125 +++++++++++++++++-------------
sql/item_windowfunc.cc | 6 +-
sql/item_windowfunc.h | 9 ++-
sql/item_xmlfunc.cc | 13 ++--
sql/item_xmlfunc.h | 2 +-
sql/sql_select.cc | 3 +-
sql/sql_table.cc | 11 ++-
26 files changed, 734 insertions(+), 491 deletions(-)
diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result
index 0845459f6b6..5f5586e2c21 100644
--- a/mysql-test/r/alter_table.result
+++ b/mysql-test/r/alter_table.result
@@ -2309,5 +2309,16 @@ t1 CREATE TABLE `t1` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
#
+# MDEV-11071: Assertion `thd->transaction.stmt.is_empty()' failed
+# in Locked_tables_list::unlock_locked_tables
+#
+CREATE TABLE t1 (d DATETIME DEFAULT CURRENT_TIMESTAMP, i INT) ENGINE=InnoDB;
+INSERT INTO t1 (i) VALUES (1),(1);
+LOCK TABLE t1 WRITE;
+ALTER TABLE t1 ADD UNIQUE(i);
+ERROR 23000: Duplicate entry '1' for key 'i'
+UNLOCK TABLES;
+DROP TABLE t1;
+#
# End of 10.2 tests
#
diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test
index 63d24c0740d..0a683b48338 100644
--- a/mysql-test/t/alter_table.test
+++ b/mysql-test/t/alter_table.test
@@ -1900,6 +1900,22 @@ alter table t1 change b new_b int not null, add column b char(1), add constraint
show create table t1;
drop table t1;
+--echo #
+--echo # MDEV-11071: Assertion `thd->transaction.stmt.is_empty()' failed
+--echo # in Locked_tables_list::unlock_locked_tables
+--echo #
+
+CREATE TABLE t1 (d DATETIME DEFAULT CURRENT_TIMESTAMP, i INT) ENGINE=InnoDB;
+INSERT INTO t1 (i) VALUES (1),(1);
+LOCK TABLE t1 WRITE;
+--error ER_DUP_ENTRY
+ALTER TABLE t1 ADD UNIQUE(i);
+
+# Cleanup
+UNLOCK TABLES;
+DROP TABLE t1;
+
+
--echo #
--echo # End of 10.2 tests
--echo #
diff --git a/sql/item.h b/sql/item.h
index 8921ee76f6a..e9713730a1c 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -4210,7 +4210,7 @@ class Item_func_or_sum: public Item_result_field,
also to make printing of items inherited from Item_sum uniform.
*/
virtual const char *func_name() const= 0;
- virtual void fix_length_and_dec()= 0;
+ virtual bool fix_length_and_dec()= 0;
bool const_item() const { return const_item_cache; }
table_map used_tables() const { return used_tables_cache; }
Item* build_clone(THD *thd, MEM_ROOT *mem_root);
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 44cc4f3cae9..46cf412e229 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -526,7 +526,7 @@ bool Item_func::setup_args_and_comparator(THD *thd, Arg_comparator *cmp)
}
-void Item_bool_rowready_func2::fix_length_and_dec()
+bool Item_bool_rowready_func2::fix_length_and_dec()
{
max_length= 1; // Function returns 0 or 1
@@ -535,8 +535,9 @@ void Item_bool_rowready_func2::fix_length_and_dec()
we have to check for out of memory conditions here
*/
if (!args[0] || !args[1])
- return;
- setup_args_and_comparator(current_thd, &cmp);
+ return FALSE;
+ bool res= setup_args_and_comparator(current_thd, &cmp);
+ return res;
}
@@ -1156,12 +1157,13 @@ int Arg_comparator::compare_e_str_json()
}
-void Item_func_truth::fix_length_and_dec()
+bool Item_func_truth::fix_length_and_dec()
{
maybe_null= 0;
null_value= 0;
decimals= 0;
max_length= 1;
+ return FALSE;
}
@@ -1778,10 +1780,11 @@ longlong Item_func_eq::val_int()
/** Same as Item_func_eq, but NULL = NULL. */
-void Item_func_equal::fix_length_and_dec()
+bool Item_func_equal::fix_length_and_dec()
{
- Item_bool_rowready_func2::fix_length_and_dec();
+ bool rc= Item_bool_rowready_func2::fix_length_and_dec();
maybe_null=null_value=0;
+ return rc;
}
longlong Item_func_equal::val_int()
@@ -1878,7 +1881,7 @@ bool Item_func_interval::fix_fields(THD *thd, Item **ref)
}
-void Item_func_interval::fix_length_and_dec()
+bool Item_func_interval::fix_length_and_dec()
{
uint rows= row->cols();
@@ -1896,10 +1899,13 @@ void Item_func_interval::fix_length_and_dec()
not_null_consts&= el->const_item() && !el->is_null();
}
- if (not_null_consts &&
- (intervals= (interval_range*) current_thd->alloc(sizeof(interval_range) *
- (rows - 1))))
+ if (not_null_consts)
{
+ intervals= (interval_range*) current_thd->alloc(sizeof(interval_range) *
+ (rows - 1));
+ if (!intervals)
+ return TRUE;
+
if (use_decimal_comparison)
{
for (uint i= 1; i < rows; i++)
@@ -1939,6 +1945,7 @@ void Item_func_interval::fix_length_and_dec()
not_null_tables_cache= row->not_null_tables();
with_sum_func= with_sum_func || row->with_sum_func;
with_field= with_field || row->with_field;
+ return FALSE;
}
@@ -2099,7 +2106,7 @@ void Item_func_between::fix_after_pullout(st_select_lex *new_parent,
eval_not_null_tables(NULL);
}
-void Item_func_between::fix_length_and_dec()
+bool Item_func_between::fix_length_and_dec()
{
THD *thd= current_thd;
max_length= 1;
@@ -2110,13 +2117,13 @@ void Item_func_between::fix_length_and_dec()
we have to check for out of memory conditions here
*/
if (!args[0] || !args[1] || !args[2])
- return;
+ return TRUE;
if (agg_cmp_type(&m_compare_type, args, 3))
- return;
+ return TRUE;
if (m_compare_type == STRING_RESULT &&
agg_arg_charsets_for_comparison(cmp_collation, args, 3))
- return;
+ return TRUE;
/*
When comparing as date/time, we need to convert non-temporal values
@@ -2141,6 +2148,7 @@ void Item_func_between::fix_length_and_dec()
m_compare_type= INT_RESULT; // Works for all types.
}
}
+ return FALSE;
}
@@ -2438,7 +2446,7 @@ void Item_func_if::cache_type_info(Item *source)
}
-void
+bool
Item_func_if::fix_length_and_dec()
{
// Let IF(cond, expr, NULL) and IF(cond, NULL, expr) inherit type from expr.
@@ -2449,15 +2457,15 @@ Item_func_if::fix_length_and_dec()
// If both arguments are NULL, make resulting type BINARY(0).
if (args[2]->type() == NULL_ITEM)
set_handler_by_field_type(MYSQL_TYPE_STRING);
- return;
+ return FALSE;
}
if (args[2]->type() == NULL_ITEM)
{
cache_type_info(args[1]);
maybe_null= true;
- return;
+ return FALSE;
}
- Item_func_case_abbreviation2::fix_length_and_dec2(args + 1);
+ return Item_func_case_abbreviation2::fix_length_and_dec2(args + 1);
}
@@ -2571,7 +2579,7 @@ void Item_func_nullif::update_used_tables()
-void
+bool
Item_func_nullif::fix_length_and_dec()
{
/*
@@ -2721,6 +2729,8 @@ Item_func_nullif::fix_length_and_dec()
m_cache= args[0]->cmp_type() == STRING_RESULT ?
new (thd->mem_root) Item_cache_str_for_nullif(thd, args[0]) :
Item_cache::get_cache(thd, args[0]);
+ if (!m_cache)
+ return TRUE;
m_cache->setup(thd, args[0]);
m_cache->store(args[0]);
m_cache->set_used_tables(args[0]->used_tables());
@@ -2734,7 +2744,8 @@ Item_func_nullif::fix_length_and_dec()
fix_char_length(args[2]->max_char_length());
maybe_null=1;
m_arg0= args[0];
- setup_args_and_comparator(thd, &cmp);
+ if (setup_args_and_comparator(thd, &cmp))
+ return TRUE;
/*
A special code for EXECUTE..PREPARE.
@@ -2774,6 +2785,7 @@ Item_func_nullif::fix_length_and_dec()
*/
if (args[0] == m_arg0)
m_arg0= NULL;
+ return FALSE;
}
@@ -3155,7 +3167,7 @@ static void change_item_tree_if_needed(THD *thd, Item **place, Item *new_value)
}
-void Item_func_case::fix_length_and_dec()
+bool Item_func_case::fix_length_and_dec()
{
m_found_types= 0;
if (else_expr_num == -1 || args[else_expr_num]->maybe_null)
@@ -3172,7 +3184,7 @@ void Item_func_case::fix_length_and_dec()
if (Item_func_case::result_type() == STRING_RESULT)
{
if (count_string_result_length(Item_func_case::field_type(), rets, nrets))
- return;
+ return TRUE;
}
else
fix_attributes(rets, nrets);
@@ -3186,7 +3198,7 @@ void Item_func_case::fix_length_and_dec()
left_cmp_type= args[0]->cmp_type();
if (!(m_found_types= collect_cmp_types(args, nwhens + 1)))
- return;
+ return TRUE;
Item *date_arg= 0;
if (m_found_types & (1U << TIME_RESULT))
@@ -3219,7 +3231,7 @@ void Item_func_case::fix_length_and_dec()
CASE utf16_item WHEN CONVERT(latin1_item USING utf16) THEN ... END
*/
if (agg_arg_charsets_for_comparison(cmp_collation, args, nwhens + 1))
- return;
+ return TRUE;
}
for (uint i= 0; i <= (uint)TIME_RESULT; i++)
@@ -3230,10 +3242,11 @@ void Item_func_case::fix_length_and_dec()
if (!(cmp_items[i]=
cmp_item::get_comparator((Item_result)i, date_arg,
cmp_collation.collation)))
- return;
+ return TRUE;
}
}
}
+ return FALSE;
}
@@ -4114,7 +4127,7 @@ static int srtcmp_in(CHARSET_INFO *cs, const String *x,const String *y)
(uchar *) y->ptr(),y->length());
}
-void Item_func_in::fix_length_and_dec()
+bool Item_func_in::fix_length_and_dec()
{
Item **arg, **arg_end;
bool const_itm= 1;
@@ -4126,7 +4139,7 @@ void Item_func_in::fix_length_and_dec()
m_compare_type= STRING_RESULT;
left_cmp_type= args[0]->cmp_type();
if (!(found_types= collect_cmp_types(args, arg_count, true)))
- return;
+ return TRUE;
for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++)
{
@@ -4175,7 +4188,7 @@ void Item_func_in::fix_length_and_dec()
{
if (m_compare_type == STRING_RESULT &&
agg_arg_charsets_for_comparison(cmp_collation, args, arg_count))
- return;
+ return TRUE;
arg_types_compatible= TRUE;
if (m_compare_type == ROW_RESULT)
@@ -4186,12 +4199,14 @@ void Item_func_in::fix_length_and_dec()
if (bisection_possible)
{
array= new (thd->mem_root) in_row(thd, arg_count-1, 0);
+ if (!array)
+ return TRUE;
cmp= &((in_row*)array)->tmp;
}
else
{
if (!(cmp= new (thd->mem_root) cmp_item_row))
- return;
+ return TRUE;
cmp_items[ROW_RESULT]= cmp;
}
cmp->n= cols;
@@ -4208,6 +4223,8 @@ void Item_func_in::fix_length_and_dec()
else
cmp= ((cmp_item_row*)cmp_items[ROW_RESULT])->comparators + col;
*cmp= new (thd->mem_root) cmp_item_datetime(date_arg);
+ if (!(*cmp))
+ return TRUE;
}
}
}
@@ -4270,7 +4287,7 @@ void Item_func_in::fix_length_and_dec()
break;
}
if (!array || thd->is_fatal_error) // OOM
- return;
+ return TRUE;
uint j=0;
for (uint i=1 ; i < arg_count ; i++)
{
@@ -4295,7 +4312,7 @@ void Item_func_in::fix_length_and_dec()
date_arg= find_date_time_item(thd, args, arg_count, 0, true);
if (found_types & (1U << STRING_RESULT) &&
agg_arg_charsets_for_comparison(cmp_collation, args, arg_count))
- return;
+ return TRUE;
for (i= 0; i <= (uint) TIME_RESULT; i++)
{
if (found_types & (1U << i) && !cmp_items[i])
@@ -4303,11 +4320,12 @@ void Item_func_in::fix_length_and_dec()
if (!cmp_items[i] && !(cmp_items[i]=
cmp_item::get_comparator((Item_result)i, date_arg,
cmp_collation.collation)))
- return;
+ return TRUE;
}
}
}
max_length= 1;
+ return FALSE;
}
@@ -4576,7 +4594,8 @@ Item_cond::fix_fields(THD *thd, Item **ref)
with_window_func|= item->with_window_func;
maybe_null|= item->maybe_null;
}
- fix_length_and_dec();
+ if (fix_length_and_dec())
+ return TRUE;
fixed= 1;
return FALSE;
}
@@ -5609,16 +5628,16 @@ bool Item_func_regex::fix_fields(THD *thd, Item **ref)
return Item_bool_func::fix_fields(thd, ref);
}
-void
+bool
Item_func_regex::fix_length_and_dec()
{
- Item_bool_func::fix_length_and_dec();
-
- if (agg_arg_charsets_for_comparison(cmp_collation, args, 2))
- return;
+ if (Item_bool_func::fix_length_and_dec() ||
+ agg_arg_charsets_for_comparison(cmp_collation, args, 2))
+ return TRUE;
re.init(cmp_collation.collation, 0);
re.fix_owner(this, args[0], args[1]);
+ return FALSE;
}
@@ -5642,14 +5661,15 @@ bool Item_func_regexp_instr::fix_fields(THD *thd, Item **ref)
}
-void
+bool
Item_func_regexp_instr::fix_length_and_dec()
{
if (agg_arg_charsets_for_comparison(cmp_collation, args, 2))
- return;
+ return TRUE;
re.init(cmp_collation.collation, 0);
re.fix_owner(this, args[0], args[1]);
+ return FALSE;
}
@@ -6591,7 +6611,8 @@ bool Item_equal::fix_fields(THD *thd, Item **ref)
}
if (prev_equal_field && last_equal_field != first_equal_field)
last_equal_field->next_equal_field= first_equal_field;
- fix_length_and_dec();
+ if (fix_length_and_dec())
+ return TRUE;
fixed= 1;
return FALSE;
}
@@ -6677,11 +6698,12 @@ longlong Item_equal::val_int()
}
-void Item_equal::fix_length_and_dec()
+bool Item_equal::fix_length_and_dec()
{
Item *item= get_first(NO_PARTICULAR_TAB, NULL);
eval_item= cmp_item::get_comparator(item->cmp_type(), item,
item->collation.collation);
+ return FALSE;
}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index de1b27cff1a..5efb98bc81d 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -200,7 +200,7 @@ class Item_bool_func :public Item_int_func
Item_bool_func(THD *thd, Item_bool_func *item) :Item_int_func(thd, item) {}
bool is_bool_type() { return true; }
virtual CHARSET_INFO *compare_collation() const { return NULL; }
- void fix_length_and_dec() { decimals=0; max_length=1; }
+ bool fix_length_and_dec() { decimals=0; max_length=1; return FALSE; }
uint decimal_precision() const { return 1; }
bool need_parentheses_in_default() { return true; }
};
@@ -216,7 +216,7 @@ class Item_func_truth : public Item_bool_func
public:
virtual bool val_bool();
virtual longlong val_int();
- virtual void fix_length_and_dec();
+ virtual bool fix_length_and_dec();
virtual void print(String *str, enum_query_type query_type);
enum precedence precedence() const { return CMP_PRECEDENCE; }
@@ -501,7 +501,7 @@ class Item_bool_rowready_func2 :public Item_bool_func2_with_rev
cond);
return this;
}
- void fix_length_and_dec();
+ bool fix_length_and_dec();
int set_cmp_func()
{
return cmp.set_cmp_func(this, tmp_arg, tmp_arg + 1, true);
@@ -711,7 +711,7 @@ class Item_func_equal :public Item_bool_rowready_func2
Item_func_equal(THD *thd, Item *a, Item *b):
Item_bool_rowready_func2(thd, a, b) {}
longlong val_int();
- void fix_length_and_dec();
+ bool fix_length_and_dec();
table_map not_null_tables() const { return 0; }
enum Functype functype() const { return EQUAL_FUNC; }
enum Functype rev_functype() const { return EQUAL_FUNC; }
@@ -878,7 +878,7 @@ class Item_func_between :public Item_func_opt_neg
enum Functype functype() const { return BETWEEN; }
const char *func_name() const { return "between"; }
enum precedence precedence() const { return BETWEEN_PRECEDENCE; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
virtual void print(String *str, enum_query_type query_type);
bool eval_not_null_tables(void *opt_arg);
void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
@@ -911,10 +911,12 @@ class Item_func_strcmp :public Item_int_func
longlong val_int();
uint decimal_precision() const { return 1; }
const char *func_name() const { return "strcmp"; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
- agg_arg_charsets_for_comparison(cmp_collation, args, 2);
+ if (agg_arg_charsets_for_comparison(cmp_collation, args, 2))
+ return TRUE;
fix_char_length(2); // returns "1" or "0" or "-1"
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_strcmp>(thd, mem_root, this); }
@@ -941,7 +943,7 @@ class Item_func_interval :public Item_int_func
}
bool fix_fields(THD *, Item **);
longlong val_int();
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "interval"; }
uint decimal_precision() const { return 2; }
void print(String *str, enum_query_type query_type)
@@ -966,10 +968,11 @@ class Item_func_coalesce :public Item_func_hybrid_field_type
String *str_op(String *);
my_decimal *decimal_op(my_decimal *);
bool date_op(MYSQL_TIME *ltime,uint fuzzydate);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
set_handler_by_field_type(agg_field_type(args, arg_count, true));
fix_attributes(args, arg_count);
+ return FALSE;
}
const char *func_name() const { return "coalesce"; }
table_map not_null_tables() const { return 0; }
@@ -986,10 +989,11 @@ class Item_func_coalesce :public Item_func_hybrid_field_type
class Item_func_case_abbreviation2 :public Item_func_hybrid_field_type
{
protected:
- void fix_length_and_dec2(Item **items)
+ bool fix_length_and_dec2(Item **items)
{
set_handler_by_field_type(agg_field_type(items, 2, true));
fix_attributes(items, 2);
+ return FALSE;
}
uint decimal_precision2(Item **args) const;
public:
@@ -1010,10 +1014,12 @@ class Item_func_ifnull :public Item_func_case_abbreviation2
String *str_op(String *str);
my_decimal *decimal_op(my_decimal *);
bool date_op(MYSQL_TIME *ltime,uint fuzzydate);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
- Item_func_case_abbreviation2::fix_length_and_dec2(args);
+ if (Item_func_case_abbreviation2::fix_length_and_dec2(args))
+ return TRUE;
maybe_null= args[1]->maybe_null;
+ return FALSE;
}
const char *func_name() const { return "ifnull"; }
Field *create_field_for_create_select(TABLE *table)
@@ -1041,7 +1047,7 @@ class Item_func_if :public Item_func_case_abbreviation2
my_decimal *decimal_op(my_decimal *);
String *str_op(String *);
bool fix_fields(THD *, Item **);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
uint decimal_precision() const
{
return Item_func_case_abbreviation2::decimal_precision2(args + 1);
@@ -1108,7 +1114,7 @@ class Item_func_nullif :public Item_func_hybrid_field_type
longlong int_op();
String *str_op(String *str);
my_decimal *decimal_op(my_decimal *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool walk(Item_processor processor, bool walk_subquery, void *arg);
uint decimal_precision() const { return args[2]->decimal_precision(); }
const char *func_name() const { return "nullif"; }
@@ -1570,7 +1576,7 @@ class Item_func_case :public Item_func_hybrid_field_type
my_decimal *decimal_op(my_decimal *);
bool date_op(MYSQL_TIME *ltime, uint fuzzydate);
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
uint decimal_precision() const;
table_map not_null_tables() const { return 0; }
const char *func_name() const { return "case"; }
@@ -1648,7 +1654,7 @@ class Item_func_in :public Item_func_opt_neg
}
longlong val_int();
bool fix_fields(THD *, Item **);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
void cleanup()
{
uint i;
@@ -1718,7 +1724,7 @@ class cmp_item_row :public cmp_item
int compare(cmp_item *arg);
cmp_item *make_same();
void store_value_by_template(THD *thd, cmp_item *tmpl, Item *);
- friend void Item_func_in::fix_length_and_dec();
+ friend bool Item_func_in::fix_length_and_dec();
cmp_item *get_comparator(uint i) { return comparators[i]; }
};
@@ -1731,7 +1737,7 @@ class in_row :public in_vector
~in_row();
void set(uint pos,Item *item);
uchar *get_value(Item *item);
- friend void Item_func_in::fix_length_and_dec();
+ friend bool Item_func_in::fix_length_and_dec();
Item_result result_type() { return ROW_RESULT; }
cmp_item *get_cmp_item() { return &tmp; }
};
@@ -1763,7 +1769,11 @@ class Item_func_null_predicate :public Item_bool_func
}
CHARSET_INFO *compare_collation() const
{ return args[0]->collation.collation; }
- void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=0; }
+ bool fix_length_and_dec()
+ {
+ decimals=0; max_length=1; maybe_null=0;
+ return FALSE;
+ }
bool count_sargable_conds(void *arg);
};
@@ -1987,10 +1997,10 @@ class Item_func_like :public Item_bool_func2
const char *func_name() const { return "like"; }
enum precedence precedence() const { return CMP_PRECEDENCE; }
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
max_length= 1;
- agg_arg_charsets_for_comparison(cmp_collation, args, 2);
+ return agg_arg_charsets_for_comparison(cmp_collation, args, 2);
}
void cleanup();
@@ -2111,7 +2121,7 @@ class Item_func_regex :public Item_bool_func
}
longlong val_int();
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "regexp"; }
enum precedence precedence() const { return CMP_PRECEDENCE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -2149,7 +2159,7 @@ class Item_func_regexp_instr :public Item_int_func
}
longlong val_int();
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "regexp_instr"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_regexp_instr>(thd, mem_root, this); }
@@ -2385,7 +2395,7 @@ class Item_equal: public Item_bool_func
longlong val_int();
const char *func_name() const { return "multiple equal"; }
void sort(Item_field_cmpfunc compare, void *arg);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool fix_fields(THD *thd, Item **ref);
void cleanup()
{
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 0c239b54f30..255923d98dd 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -235,8 +235,7 @@ Item_func::fix_fields(THD *thd, Item **ref)
with_subselect|= item->has_subquery();
}
}
- fix_length_and_dec();
- if (thd->is_error()) // An error inside fix_length_and_dec occurred
+ if (fix_length_and_dec())
return TRUE;
fixed= 1;
return FALSE;
@@ -731,10 +730,12 @@ String *Item_int_func::val_str(String *str)
}
-void Item_func_connection_id::fix_length_and_dec()
+bool Item_func_connection_id::fix_length_and_dec()
{
- Item_int_func::fix_length_and_dec();
+ if (Item_int_func::fix_length_and_dec())
+ return TRUE;
max_length= 10;
+ return FALSE;
}
@@ -753,7 +754,7 @@ bool Item_func_connection_id::fix_fields(THD *thd, Item **ref)
function of two arguments.
*/
-void Item_num_op::fix_length_and_dec(void)
+bool Item_num_op::fix_length_and_dec(void)
{
DBUG_ENTER("Item_num_op::fix_length_and_dec");
DBUG_PRINT("info", ("name %s", func_name()));
@@ -789,7 +790,7 @@ void Item_num_op::fix_length_and_dec(void)
result_type() == DECIMAL_RESULT ? "DECIMAL_RESULT" :
result_type() == INT_RESULT ? "INT_RESULT" :
"--ILLEGAL!!!--")));
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
@@ -799,7 +800,7 @@ void Item_num_op::fix_length_and_dec(void)
type depends only on the first argument)
*/
-void Item_func_num1::fix_length_and_dec()
+bool Item_func_num1::fix_length_and_dec()
{
DBUG_ENTER("Item_func_num1::fix_length_and_dec");
DBUG_PRINT("info", ("name %s", func_name()));
@@ -830,7 +831,7 @@ void Item_func_num1::fix_length_and_dec()
result_type() == DECIMAL_RESULT ? "DECIMAL_RESULT" :
result_type() == INT_RESULT ? "INT_RESULT" :
"--ILLEGAL!!!--")));
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
@@ -1415,12 +1416,14 @@ void Item_func_additive_op::result_precision()
subtraction of UNSIGNED BIGINT to return negative values.
*/
-void Item_func_minus::fix_length_and_dec()
+bool Item_func_minus::fix_length_and_dec()
{
- Item_num_op::fix_length_and_dec();
+ if (Item_num_op::fix_length_and_dec())
+ return TRUE;
if (unsigned_flag &&
(current_thd->variables.sql_mode & MODE_NO_UNSIGNED_SUBTRACTION))
unsigned_flag=0;
+ return FALSE;
}
@@ -1718,11 +1721,12 @@ void Item_func_div::result_precision()
}
-void Item_func_div::fix_length_and_dec()
+bool Item_func_div::fix_length_and_dec()
{
DBUG_ENTER("Item_func_div::fix_length_and_dec");
prec_increment= current_thd->variables.div_precincrement;
- Item_num_op::fix_length_and_dec();
+ if (Item_num_op::fix_length_and_dec())
+ DBUG_RETURN(TRUE);
switch (Item_func_div::result_type()) {
case REAL_RESULT:
{
@@ -1753,7 +1757,7 @@ void Item_func_div::fix_length_and_dec()
DBUG_ASSERT(0);
}
maybe_null= 1; // devision by zero
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
@@ -1829,7 +1833,7 @@ longlong Item_func_int_div::val_int()
}
-void Item_func_int_div::fix_length_and_dec()
+bool Item_func_int_div::fix_length_and_dec()
{
Item_result argtype= args[0]->result_type();
/* use precision ony for the data type it is applicable for and valid */
@@ -1840,6 +1844,7 @@ void Item_func_int_div::fix_length_and_dec()
MY_INT64_NUM_DECIMAL_DIGITS : char_length);
maybe_null=1;
unsigned_flag=args[0]->unsigned_flag | args[1]->unsigned_flag;
+ return false;
}
@@ -1923,11 +1928,13 @@ void Item_func_mod::result_precision()
}
-void Item_func_mod::fix_length_and_dec()
+bool Item_func_mod::fix_length_and_dec()
{
- Item_num_op::fix_length_and_dec();
+ if (Item_num_op::fix_length_and_dec())
+ return true;
maybe_null= 1;
unsigned_flag= args[0]->unsigned_flag;
+ return false;
}
@@ -1974,10 +1981,11 @@ my_decimal *Item_func_neg::decimal_op(my_decimal *decimal_value)
}
-void Item_func_neg::fix_length_and_dec()
+bool Item_func_neg::fix_length_and_dec()
{
DBUG_ENTER("Item_func_neg::fix_length_and_dec");
- Item_func_num1::fix_length_and_dec();
+ if (Item_func_num1::fix_length_and_dec())
+ DBUG_RETURN(TRUE);
/* 1 add because sign can appear */
max_length= args[0]->max_length + 1;
@@ -2003,7 +2011,7 @@ void Item_func_neg::fix_length_and_dec()
}
}
unsigned_flag= 0;
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
@@ -2043,10 +2051,12 @@ my_decimal *Item_func_abs::decimal_op(my_decimal *decimal_value)
}
-void Item_func_abs::fix_length_and_dec()
+bool Item_func_abs::fix_length_and_dec()
{
- Item_func_num1::fix_length_and_dec();
+ if (Item_func_num1::fix_length_and_dec())
+ return TRUE;
unsigned_flag= args[0]->unsigned_flag;
+ return FALSE;
}
@@ -2278,7 +2288,7 @@ longlong Item_func_bit_neg::val_int()
// Conversion functions
-void Item_func_int_val::fix_length_and_dec()
+bool Item_func_int_val::fix_length_and_dec()
{
DBUG_ENTER("Item_func_int_val::fix_length_and_dec");
DBUG_PRINT("info", ("name %s", func_name()));
@@ -2326,7 +2336,7 @@ void Item_func_int_val::fix_length_and_dec()
result_type() == INT_RESULT ? "INT_RESULT" :
"--ILLEGAL!!!--")));
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
@@ -2424,7 +2434,7 @@ my_decimal *Item_func_floor::decimal_op(my_decimal *decimal_value)
}
-void Item_func_round::fix_length_and_dec()
+bool Item_func_round::fix_length_and_dec()
{
int decimals_to_set;
longlong val1;
@@ -2442,12 +2452,12 @@ void Item_func_round::fix_length_and_dec()
}
else
set_handler_by_result_type(REAL_RESULT);
- return;
+ return FALSE;
}
val1= args[1]->val_int();
if ((null_value= args[1]->null_value))
- return;
+ return FALSE;
val1_unsigned= args[1]->unsigned_flag;
if (val1 < 0)
@@ -2460,7 +2470,7 @@ void Item_func_round::fix_length_and_dec()
decimals= MY_MIN(decimals_to_set, NOT_FIXED_DEC);
max_length= float_length(decimals);
set_handler_by_result_type(REAL_RESULT);
- return;
+ return FALSE;
}
switch (args[0]->result_type()) {
@@ -2501,6 +2511,7 @@ void Item_func_round::fix_length_and_dec()
case TIME_RESULT:
DBUG_ASSERT(0); /* This result type isn't handled */
}
+ return FALSE;
}
double my_double_round(double value, longlong dec, bool dec_unsigned,
@@ -2725,7 +2736,7 @@ double Item_func_units::val_real()
}
-void Item_func_min_max::fix_length_and_dec()
+bool Item_func_min_max::fix_length_and_dec()
{
uint unsigned_count= 0;
int max_int_part=0;
@@ -2836,6 +2847,7 @@ void Item_func_min_max::fix_length_and_dec()
set_handler_by_field_type(MYSQL_TYPE_DOUBLE);
break;
}
+ return FALSE;
}
@@ -3086,10 +3098,10 @@ longlong Item_func_coercibility::val_int()
}
-void Item_func_locate::fix_length_and_dec()
+bool Item_func_locate::fix_length_and_dec()
{
max_length= MY_INT32_NUM_DECIMAL_DIGITS;
- agg_arg_charsets_for_comparison(cmp_collation, args, 2);
+ return agg_arg_charsets_for_comparison(cmp_collation, args, 2);
}
@@ -3206,14 +3218,15 @@ longlong Item_func_field::val_int()
}
-void Item_func_field::fix_length_and_dec()
+bool Item_func_field::fix_length_and_dec()
{
maybe_null=0; max_length=3;
cmp_type= args[0]->result_type();
for (uint i=1; i < arg_count ; i++)
cmp_type= item_cmp_type(cmp_type, args[i]->result_type());
if (cmp_type == STRING_RESULT)
- agg_arg_charsets_for_comparison(cmp_collation, args, arg_count);
+ return agg_arg_charsets_for_comparison(cmp_collation, args, arg_count);
+ return FALSE;
}
@@ -3260,7 +3273,7 @@ longlong Item_func_ord::val_int()
/* Returns number of found type >= 1 or 0 if not found */
/* This optimizes searching in enums to bit testing! */
-void Item_func_find_in_set::fix_length_and_dec()
+bool Item_func_find_in_set::fix_length_and_dec()
{
decimals=0;
max_length=3; // 1-999
@@ -3282,7 +3295,7 @@ void Item_func_find_in_set::fix_length_and_dec()
}
}
}
- agg_arg_charsets_for_comparison(cmp_collation, args, 2);
+ return agg_arg_charsets_for_comparison(cmp_collation, args, 2);
}
static const char separator=',';
@@ -3487,7 +3500,8 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
DBUG_RETURN(TRUE);
}
}
- func->fix_length_and_dec();
+ if (func->fix_length_and_dec())
+ DBUG_RETURN(TRUE);
initid.max_length=func->max_length;
initid.maybe_null=func->maybe_null;
initid.const_item=func->const_item_cache;
@@ -3825,13 +3839,13 @@ String *Item_func_udf_decimal::val_str(String *str)
/* Default max_length is max argument length */
-void Item_func_udf_str::fix_length_and_dec()
+bool Item_func_udf_str::fix_length_and_dec()
{
DBUG_ENTER("Item_func_udf_str::fix_length_and_dec");
max_length=0;
for (uint i = 0; i < arg_count; i++)
set_if_bigger(max_length,args[i]->max_length);
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
String *Item_func_udf_str::val_str(String *str)
@@ -4718,7 +4732,7 @@ bool Item_func_set_user_var::fix_fields(THD *thd, Item **ref)
}
-void
+bool
Item_func_set_user_var::fix_length_and_dec()
{
maybe_null=args[0]->maybe_null;
@@ -4732,6 +4746,7 @@ Item_func_set_user_var::fix_length_and_dec()
args[0]->collation.collation);
}
unsigned_flag= args[0]->unsigned_flag;
+ return FALSE;
}
@@ -5570,7 +5585,7 @@ get_var_with_binlog(THD *thd, enum_sql_command sql_command,
return 1;
}
-void Item_func_get_user_var::fix_length_and_dec()
+bool Item_func_get_user_var::fix_length_and_dec()
{
THD *thd=current_thd;
int error;
@@ -5620,6 +5635,7 @@ void Item_func_get_user_var::fix_length_and_dec()
set_handler_by_field_type(MYSQL_TYPE_LONG_BLOB);
max_length= MAX_BLOB_WIDTH;
}
+ return false;
}
@@ -5762,7 +5778,7 @@ void Item_func_get_system_var::update_null_value()
}
-void Item_func_get_system_var::fix_length_and_dec()
+bool Item_func_get_system_var::fix_length_and_dec()
{
char *cptr;
maybe_null= TRUE;
@@ -5774,7 +5790,7 @@ void Item_func_get_system_var::fix_length_and_dec()
{
my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0),
var->name.str, var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL");
- return;
+ return TRUE;
}
/* As there was no local variable, return the global value */
var_type= OPT_GLOBAL;
@@ -5838,6 +5854,7 @@ void Item_func_get_system_var::fix_length_and_dec()
my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name.str);
break;
}
+ return FALSE;
}
@@ -6614,7 +6631,7 @@ bool Item_func_sp::is_expensive()
@note called from Item::fix_fields.
*/
-void Item_func_sp::fix_length_and_dec()
+bool Item_func_sp::fix_length_and_dec()
{
DBUG_ENTER("Item_func_sp::fix_length_and_dec");
@@ -6622,7 +6639,7 @@ void Item_func_sp::fix_length_and_dec()
Type_std_attributes::set(sp_result_field);
maybe_null= 1;
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
@@ -6961,11 +6978,12 @@ my_decimal *Item_func_last_value::val_decimal(my_decimal *decimal_value)
}
-void Item_func_last_value::fix_length_and_dec()
+bool Item_func_last_value::fix_length_and_dec()
{
last_value= args[arg_count -1];
Type_std_attributes::set(last_value);
maybe_null= last_value->maybe_null;
+ return FALSE;
}
diff --git a/sql/item_func.h b/sql/item_func.h
index 689bfb84034..0312b21328c 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -391,8 +391,8 @@ class Item_real_func :public Item_func
{ DBUG_ASSERT(fixed == 1); return (longlong) rint(val_real()); }
enum Item_result result_type () const { return REAL_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
- void fix_length_and_dec()
- { decimals= NOT_FIXED_DEC; max_length= float_length(decimals); }
+ bool fix_length_and_dec()
+ { decimals= NOT_FIXED_DEC; max_length= float_length(decimals); return FALSE; }
};
@@ -569,7 +569,7 @@ class Item_func_num1: public Item_func_numhybrid
public:
Item_func_num1(THD *thd, Item *a): Item_func_numhybrid(thd, a) {}
Item_func_num1(THD *thd, Item *a, Item *b): Item_func_numhybrid(thd, a, b) {}
- void fix_length_and_dec();
+ bool fix_length_and_dec();
};
@@ -584,7 +584,7 @@ class Item_num_op :public Item_func_numhybrid
{
print_op(str, query_type);
}
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool need_parentheses_in_default() { return true; }
};
@@ -611,7 +611,7 @@ class Item_int_func :public Item_func
String *val_str(String*str);
enum Item_result result_type () const { return INT_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
- void fix_length_and_dec() {}
+ bool fix_length_and_dec() { return FALSE; }
};
@@ -622,7 +622,7 @@ class Item_func_connection_id :public Item_int_func
public:
Item_func_connection_id(THD *thd): Item_int_func(thd) {}
const char *func_name() const { return "connection_id"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool fix_fields(THD *thd, Item **ref);
longlong val_int() { DBUG_ASSERT(fixed == 1); return value; }
bool check_vcol_func_processor(void *arg)
@@ -648,7 +648,7 @@ class Item_func_signed :public Item_int_func
null_value= args[0]->null_value;
return value;
}
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
uint32 char_length= MY_MIN(args[0]->max_char_length(),
MY_INT64_NUM_DECIMAL_DIGITS);
@@ -659,6 +659,7 @@ class Item_func_signed :public Item_int_func
*/
set_if_bigger(char_length, 1U + (unsigned_flag ? 0 : 1));
fix_char_length(char_length);
+ return FALSE;
}
virtual void print(String *str, enum_query_type query_type);
uint decimal_precision() const { return args[0]->decimal_precision(); }
@@ -705,7 +706,7 @@ class Item_decimal_typecast :public Item_func
my_decimal *val_decimal(my_decimal*);
enum Item_result result_type () const { return DECIMAL_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; }
- void fix_length_and_dec() {}
+ bool fix_length_and_dec() { return FALSE; }
const char *func_name() const { return "decimal_typecast"; }
virtual void print(String *str, enum_query_type query_type);
bool need_parentheses_in_default() { return true; }
@@ -725,7 +726,7 @@ class Item_double_typecast :public Item_real_func
}
double val_real();
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
- void fix_length_and_dec() { maybe_null= 1; }
+ bool fix_length_and_dec() { maybe_null= 1; return FALSE; }
const char *func_name() const { return "double_typecast"; }
virtual void print(String *str, enum_query_type query_type);
bool need_parentheses_in_default() { return true; }
@@ -769,7 +770,7 @@ class Item_func_minus :public Item_func_additive_op
longlong int_op();
double real_op();
my_decimal *decimal_op(my_decimal *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_minus>(thd, mem_root, this); }
};
@@ -803,7 +804,7 @@ class Item_func_div :public Item_num_op
my_decimal *decimal_op(my_decimal *);
const char *func_name() const { return "/"; }
enum precedence precedence() const { return MUL_PRECEDENCE; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
void result_precision();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_div>(thd, mem_root, this); }
@@ -818,7 +819,7 @@ class Item_func_int_div :public Item_int_func
longlong val_int();
const char *func_name() const { return "DIV"; }
enum precedence precedence() const { return MUL_PRECEDENCE; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
void print(String *str, enum_query_type query_type)
{
print_op(str, query_type);
@@ -842,7 +843,7 @@ class Item_func_mod :public Item_num_op
const char *func_name() const { return "%"; }
enum precedence precedence() const { return MUL_PRECEDENCE; }
void result_precision();
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -865,7 +866,7 @@ class Item_func_neg :public Item_func_num1
str->append(func_name());
args[0]->print_parenthesised(str, query_type, precedence());
}
- void fix_length_and_dec();
+ bool fix_length_and_dec();
uint decimal_precision() const { return args[0]->decimal_precision(); }
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
@@ -883,7 +884,7 @@ class Item_func_abs :public Item_func_num1
longlong int_op();
my_decimal *decimal_op(my_decimal *);
const char *func_name() const { return "abs"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -897,10 +898,11 @@ class Item_dec_func :public Item_real_func
public:
Item_dec_func(THD *thd, Item *a): Item_real_func(thd, a) {}
Item_dec_func(THD *thd, Item *a, Item *b): Item_real_func(thd, a, b) {}
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
decimals=NOT_FIXED_DEC; max_length=float_length(decimals);
maybe_null=1;
+ return FALSE;
}
};
@@ -1058,7 +1060,7 @@ class Item_func_int_val :public Item_func_num1
{
public:
Item_func_int_val(THD *thd, Item *a): Item_func_num1(thd, a) {}
- void fix_length_and_dec();
+ bool fix_length_and_dec();
};
@@ -1103,7 +1105,7 @@ class Item_func_round :public Item_func_num1
double real_op();
longlong int_op();
my_decimal *decimal_op(my_decimal *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_round>(thd, mem_root, this); }
};
@@ -1155,8 +1157,8 @@ class Item_func_units :public Item_real_func
Item_real_func(thd, a), name(name_arg), mul(mul_arg), add(add_arg) {}
double val_real();
const char *func_name() const { return name; }
- void fix_length_and_dec()
- { decimals= NOT_FIXED_DEC; max_length= float_length(decimals); }
+ bool fix_length_and_dec()
+ { decimals= NOT_FIXED_DEC; max_length= float_length(decimals); return FALSE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_units>(thd, mem_root, this); }
};
@@ -1186,7 +1188,7 @@ class Item_func_min_max :public Item_hybrid_func
String *val_str(String *);
my_decimal *val_decimal(my_decimal *);
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
};
class Item_func_min :public Item_func_min_max
@@ -1229,13 +1231,14 @@ class Item_func_rollup_const :public Item_func
bool const_item() const { return 0; }
Item_result result_type() const { return args[0]->result_type(); }
enum_field_types field_type() const { return args[0]->field_type(); }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
collation= args[0]->collation;
max_length= args[0]->max_length;
decimals=args[0]->decimals;
/* The item could be a NULL constant. */
null_value= args[0]->is_null();
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_rollup_const>(thd, mem_root, this); }
@@ -1249,7 +1252,7 @@ class Item_func_length :public Item_int_func
Item_func_length(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "length"; }
- void fix_length_and_dec() { max_length=10; }
+ bool fix_length_and_dec() { max_length=10; return FALSE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_length>(thd, mem_root, this); }
};
@@ -1272,7 +1275,7 @@ class Item_func_char_length :public Item_int_func
Item_func_char_length(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "char_length"; }
- void fix_length_and_dec() { max_length=10; }
+ bool fix_length_and_dec() { max_length=10; return FALSE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_char_length>(thd, mem_root, this); }
};
@@ -1283,7 +1286,7 @@ class Item_func_coercibility :public Item_int_func
Item_func_coercibility(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "coercibility"; }
- void fix_length_and_dec() { max_length=10; maybe_null= 0; }
+ bool fix_length_and_dec() { max_length=10; maybe_null= 0; return FALSE; }
bool eval_not_null_tables(void *)
{
not_null_tables_cache= 0;
@@ -1305,7 +1308,7 @@ class Item_func_locate :public Item_int_func
Item_func_locate(THD *thd, Item *a, Item *b, Item *c): Item_int_func(thd, a, b, c) {}
const char *func_name() const { return "locate"; }
longlong val_int();
- void fix_length_and_dec();
+ bool fix_length_and_dec();
virtual void print(String *str, enum_query_type query_type);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_locate>(thd, mem_root, this); }
@@ -1321,7 +1324,7 @@ class Item_func_field :public Item_int_func
Item_func_field(THD *thd, List<Item> &list): Item_int_func(thd, list) {}
longlong val_int();
const char *func_name() const { return "field"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_field>(thd, mem_root, this); }
};
@@ -1334,7 +1337,7 @@ class Item_func_ascii :public Item_int_func
Item_func_ascii(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "ascii"; }
- void fix_length_and_dec() { max_length=3; }
+ bool fix_length_and_dec() { max_length=3; return FALSE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_ascii>(thd, mem_root, this); }
};
@@ -1361,7 +1364,7 @@ class Item_func_find_in_set :public Item_int_func
Item_int_func(thd, a, b), enum_value(0) {}
longlong val_int();
const char *func_name() const { return "find_in_set"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_find_in_set>(thd, mem_root, this); }
};
@@ -1373,7 +1376,7 @@ class Item_func_bit: public Item_int_func
public:
Item_func_bit(THD *thd, Item *a, Item *b): Item_int_func(thd, a, b) {}
Item_func_bit(THD *thd, Item *a): Item_int_func(thd, a) {}
- void fix_length_and_dec() { unsigned_flag= 1; }
+ bool fix_length_and_dec() { unsigned_flag= 1; return FALSE; }
virtual inline void print(String *str, enum_query_type query_type)
{
@@ -1410,7 +1413,7 @@ class Item_func_bit_count :public Item_int_func
Item_func_bit_count(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "bit_count"; }
- void fix_length_and_dec() { max_length=2; }
+ bool fix_length_and_dec() { max_length=2; return FALSE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_bit_count>(thd, mem_root, this); }
};
@@ -1461,12 +1464,13 @@ class Item_func_last_insert_id :public Item_int_func
Item_func_last_insert_id(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "last_insert_id"; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
unsigned_flag= TRUE;
if (arg_count)
max_length= args[0]->max_length;
unsigned_flag=1;
+ return FALSE;
}
bool fix_fields(THD *thd, Item **ref);
bool check_vcol_func_processor(void *arg)
@@ -1486,7 +1490,7 @@ class Item_func_benchmark :public Item_int_func
{}
longlong val_int();
const char *func_name() const { return "benchmark"; }
- void fix_length_and_dec() { max_length=1; maybe_null=0; }
+ bool fix_length_and_dec() { max_length=1; maybe_null=0; return FALSE; }
virtual void print(String *str, enum_query_type query_type);
bool check_vcol_func_processor(void *arg)
{
@@ -1644,7 +1648,7 @@ class Item_func_udf_float :public Item_udf_func
double val_real();
String *val_str(String *str);
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
- void fix_length_and_dec() { fix_num_length_and_dec(); }
+ bool fix_length_and_dec() { fix_num_length_and_dec(); return FALSE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_udf_float>(thd, mem_root, this); }
};
@@ -1663,7 +1667,7 @@ class Item_func_udf_int :public Item_udf_func
String *val_str(String *str);
enum Item_result result_type () const { return INT_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
- void fix_length_and_dec() { decimals= 0; max_length= 21; }
+ bool fix_length_and_dec() { decimals= 0; max_length= 21; return FALSE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_udf_int>(thd, mem_root, this); }
};
@@ -1682,7 +1686,7 @@ class Item_func_udf_decimal :public Item_udf_func
String *val_str(String *str);
enum Item_result result_type () const { return DECIMAL_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; }
- void fix_length_and_dec() { fix_num_length_and_dec(); }
+ bool fix_length_and_dec() { fix_num_length_and_dec(); return FALSE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_udf_decimal>(thd, mem_root, this); }
};
@@ -1722,7 +1726,7 @@ class Item_func_udf_str :public Item_udf_func
}
enum Item_result result_type () const { return STRING_RESULT; }
enum_field_types field_type() const { return string_field_type(); }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_udf_str>(thd, mem_root, this); }
};
@@ -1774,7 +1778,7 @@ class Item_func_udf_str :public Item_func
double val_real() { DBUG_ASSERT(fixed == 1); null_value= 1; return 0.0; }
longlong val_int() { DBUG_ASSERT(fixed == 1); null_value=1; return 0; }
enum Item_result result_type () const { return STRING_RESULT; }
- void fix_length_and_dec() { maybe_null=1; max_length=0; }
+ bool fix_length_and_dec() { maybe_null=1; max_length=0; return FALSE; }
};
#endif /* HAVE_DLOPEN */
@@ -1789,7 +1793,7 @@ class Item_func_get_lock :public Item_int_func
Item_func_get_lock(THD *thd, Item *a, Item *b) :Item_int_func(thd, a, b) {}
longlong val_int();
const char *func_name() const { return "get_lock"; }
- void fix_length_and_dec() { max_length=1; maybe_null=1;}
+ bool fix_length_and_dec() { max_length=1; maybe_null=1; return FALSE; }
table_map used_tables() const
{
return used_tables_cache | RAND_TABLE_BIT;
@@ -1811,7 +1815,7 @@ class Item_func_release_lock :public Item_int_func
Item_func_release_lock(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "release_lock"; }
- void fix_length_and_dec() { max_length= 1; maybe_null= 1;}
+ bool fix_length_and_dec() { max_length= 1; maybe_null= 1; return FALSE; }
table_map used_tables() const
{
return used_tables_cache | RAND_TABLE_BIT;
@@ -1839,7 +1843,7 @@ class Item_master_pos_wait :public Item_int_func
Item_int_func(thd, a, b, c, d) {}
longlong val_int();
const char *func_name() const { return "master_pos_wait"; }
- void fix_length_and_dec() { max_length=21; maybe_null=1;}
+ bool fix_length_and_dec() { max_length=21; maybe_null=1; return FALSE; }
bool check_vcol_func_processor(void *arg)
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
@@ -1857,7 +1861,7 @@ class Item_master_gtid_wait :public Item_int_func
Item_master_gtid_wait(THD *thd, Item *a, Item *b): Item_int_func(thd, a, b) {}
longlong val_int();
const char *func_name() const { return "master_gtid_wait"; }
- void fix_length_and_dec() { max_length=2; }
+ bool fix_length_and_dec() { max_length=2; return FALSE; }
bool check_vcol_func_processor(void *arg)
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
@@ -1948,7 +1952,7 @@ class Item_func_set_user_var :public Item_func_user_var
void save_item_result(Item *item);
bool update();
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
Field *create_field_for_create_select(TABLE *table)
{
return result_type() != STRING_RESULT ?
@@ -1989,7 +1993,7 @@ class Item_func_get_user_var :public Item_func_user_var,
longlong val_int();
my_decimal *val_decimal(my_decimal*);
String *val_str(String* str);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
virtual void print(String *str, enum_query_type query_type);
/*
We must always return variables as strings to guard against selects of type
@@ -2071,7 +2075,7 @@ class Item_func_get_system_var :public Item_func
size_t name_len_arg);
enum Functype functype() const { return GSYSVAR_FUNC; }
void update_null_value();
- void fix_length_and_dec();
+ bool fix_length_and_dec();
void print(String *str, enum_query_type query_type);
bool const_item() const { return true; }
table_map used_tables() const { return 0; }
@@ -2210,7 +2214,11 @@ class Item_func_is_free_lock :public Item_int_func
Item_func_is_free_lock(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "is_free_lock"; }
- void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;}
+ bool fix_length_and_dec()
+ {
+ decimals=0; max_length=1; maybe_null=1;
+ return FALSE;
+ }
bool check_vcol_func_processor(void *arg)
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
@@ -2226,7 +2234,11 @@ class Item_func_is_used_lock :public Item_int_func
Item_func_is_used_lock(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "is_used_lock"; }
- void fix_length_and_dec() { decimals=0; max_length=10; maybe_null=1;}
+ bool fix_length_and_dec()
+ {
+ decimals=0; max_length=10; maybe_null=1;
+ return FALSE;
+ }
bool check_vcol_func_processor(void *arg)
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
@@ -2278,7 +2290,7 @@ class Item_func_row_count :public Item_int_func
Item_func_row_count(THD *thd): Item_int_func(thd) {}
longlong val_int();
const char *func_name() const { return "row_count"; }
- void fix_length_and_dec() { decimals= 0; maybe_null=0; }
+ bool fix_length_and_dec() { decimals= 0; maybe_null=0; return FALSE; }
bool check_vcol_func_processor(void *arg)
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
@@ -2406,7 +2418,7 @@ class Item_func_sp :public Item_func
virtual enum Functype functype() const { return FUNC_SP; }
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec(void);
+ bool fix_length_and_dec(void);
bool is_expensive();
inline Field *get_sp_result_field()
@@ -2442,7 +2454,7 @@ class Item_func_found_rows :public Item_int_func
Item_func_found_rows(THD *thd): Item_int_func(thd) {}
longlong val_int();
const char *func_name() const { return "found_rows"; }
- void fix_length_and_dec() { decimals= 0; maybe_null=0; }
+ bool fix_length_and_dec() { decimals= 0; maybe_null=0; return FALSE; }
bool check_vcol_func_processor(void *arg)
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
@@ -2461,8 +2473,8 @@ class Item_func_uuid_short :public Item_int_func
const char *func_name() const { return "uuid_short"; }
longlong val_int();
bool const_item() const { return false; }
- void fix_length_and_dec()
- { max_length= 21; unsigned_flag=1; }
+ bool fix_length_and_dec()
+ { max_length= 21; unsigned_flag=1; return FALSE; }
table_map used_tables() const { return RAND_TABLE_BIT; }
bool check_vcol_func_processor(void *arg)
{
@@ -2483,7 +2495,7 @@ class Item_func_last_value :public Item_func
longlong val_int();
String *val_str(String *);
my_decimal *val_decimal(my_decimal *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
enum Item_result result_type () const { return last_value->result_type(); }
const char *func_name() const { return "last_value"; }
bool eval_not_null_tables(void *)
diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc
index 3119f5a577b..246be438e36 100644
--- a/sql/item_geofunc.cc
+++ b/sql/item_geofunc.cc
@@ -49,12 +49,13 @@ Field *Item_geometry_func::create_field_for_create_select(TABLE *t_arg)
return result;
}
-void Item_geometry_func::fix_length_and_dec()
+bool Item_geometry_func::fix_length_and_dec()
{
collation.set(&my_charset_bin);
decimals=0;
max_length= (uint32) 4294967295U;
maybe_null= 1;
+ return FALSE;
}
@@ -223,11 +224,12 @@ String *Item_func_as_wkt::val_str_ascii(String *str)
}
-void Item_func_as_wkt::fix_length_and_dec()
+bool Item_func_as_wkt::fix_length_and_dec()
{
collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
max_length=MAX_BLOB_WIDTH;
maybe_null= 1;
+ return FALSE;
}
@@ -249,11 +251,12 @@ String *Item_func_as_wkb::val_str(String *str)
}
-void Item_func_as_geojson::fix_length_and_dec()
+bool Item_func_as_geojson::fix_length_and_dec()
{
collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
max_length=MAX_BLOB_WIDTH;
maybe_null= 1;
+ return FALSE;
}
diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h
index 199bc1f47de..acc94183d47 100644
--- a/sql/item_geofunc.h
+++ b/sql/item_geofunc.h
@@ -38,7 +38,7 @@ class Item_geometry_func: public Item_str_func
Item_geometry_func(THD *thd, Item *a, Item *b, Item *c):
Item_str_func(thd, a, b, c) {}
Item_geometry_func(THD *thd, List<Item> &list): Item_str_func(thd, list) {}
- void fix_length_and_dec();
+ bool fix_length_and_dec();
enum_field_types field_type() const { return MYSQL_TYPE_GEOMETRY; }
Field *create_field_for_create_select(TABLE *table);
};
@@ -90,7 +90,7 @@ class Item_func_as_wkt: public Item_str_ascii_func
Item_func_as_wkt(THD *thd, Item *a): Item_str_ascii_func(thd, a) {}
const char *func_name() const { return "st_astext"; }
String *val_str_ascii(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_as_wkt>(thd, mem_root, this); }
};
@@ -116,7 +116,7 @@ class Item_func_as_geojson: public Item_str_ascii_func
Item_func_as_geojson(THD *thd, Item *js, Item *max_dec_digits, Item *opt):
Item_str_ascii_func(thd, js, max_dec_digits, opt) {}
const char *func_name() const { return "st_asgeojson"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
String *val_str_ascii(String *);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_as_geojson>(thd, mem_root, this); }
@@ -129,11 +129,12 @@ class Item_func_geometry_type: public Item_str_ascii_func
Item_func_geometry_type(THD *thd, Item *a): Item_str_ascii_func(thd, a) {}
String *val_str_ascii(String *);
const char *func_name() const { return "st_geometrytype"; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
// "GeometryCollection" is the longest
fix_length_and_charset(20, default_charset());
maybe_null= 1;
+ return FALSE;
};
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_geometry_type>(thd, mem_root, this); }
@@ -308,9 +309,10 @@ class Item_func_spatial_collection: public Item_geometry_func
item_type=it;
}
String *val_str(String *);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
- Item_geometry_func::fix_length_and_dec();
+ if (Item_geometry_func::fix_length_and_dec())
+ return TRUE;
for (unsigned int i= 0; i < arg_count; ++i)
{
if (args[i]->fixed && args[i]->field_type() != MYSQL_TYPE_GEOMETRY)
@@ -320,8 +322,10 @@ class Item_func_spatial_collection: public Item_geometry_func
str.append('\0');
my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "non geometric",
str.ptr());
+ return TRUE;
}
}
+ return FALSE;
}
const char *func_name() const { return "geometrycollection"; }
@@ -510,7 +514,7 @@ class Item_func_isempty: public Item_bool_func
Item_func_isempty(THD *thd, Item *a): Item_bool_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "st_isempty"; }
- void fix_length_and_dec() { maybe_null= 1; }
+ bool fix_length_and_dec() { maybe_null= 1; return FALSE; }
bool need_parentheses_in_default() { return false; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_isempty>(thd, mem_root, this); }
@@ -526,7 +530,7 @@ class Item_func_issimple: public Item_int_func
Item_func_issimple(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "st_issimple"; }
- void fix_length_and_dec() { decimals=0; max_length=2; }
+ bool fix_length_and_dec() { decimals=0; max_length=2; return FALSE; }
uint decimal_precision() const { return 1; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_issimple>(thd, mem_root, this); }
@@ -538,7 +542,7 @@ class Item_func_isclosed: public Item_int_func
Item_func_isclosed(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "st_isclosed"; }
- void fix_length_and_dec() { decimals=0; max_length=2; }
+ bool fix_length_and_dec() { decimals=0; max_length=2; return FALSE; }
uint decimal_precision() const { return 1; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_isclosed>(thd, mem_root, this); }
@@ -561,7 +565,7 @@ class Item_func_dimension: public Item_int_func
Item_func_dimension(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "st_dimension"; }
- void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
+ bool fix_length_and_dec() { max_length= 10; maybe_null= 1; return FALSE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_dimension>(thd, mem_root, this); }
};
@@ -573,10 +577,12 @@ class Item_func_x: public Item_real_func
Item_func_x(THD *thd, Item *a): Item_real_func(thd, a) {}
double val_real();
const char *func_name() const { return "st_x"; }
- void fix_length_and_dec()
- {
- Item_real_func::fix_length_and_dec();
- maybe_null= 1;
+ bool fix_length_and_dec()
+ {
+ if (Item_real_func::fix_length_and_dec())
+ return TRUE;
+ maybe_null= 1;
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_x>(thd, mem_root, this); }
@@ -590,10 +596,12 @@ class Item_func_y: public Item_real_func
Item_func_y(THD *thd, Item *a): Item_real_func(thd, a) {}
double val_real();
const char *func_name() const { return "st_y"; }
- void fix_length_and_dec()
- {
- Item_real_func::fix_length_and_dec();
- maybe_null= 1;
+ bool fix_length_and_dec()
+ {
+ if (Item_real_func::fix_length_and_dec())
+ return TRUE;
+ maybe_null= 1;
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_y>(thd, mem_root, this); }
@@ -607,7 +615,7 @@ class Item_func_numgeometries: public Item_int_func
Item_func_numgeometries(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "st_numgeometries"; }
- void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
+ bool fix_length_and_dec() { max_length= 10; maybe_null= 1; return FALSE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_numgeometries>(thd, mem_root, this); }
};
@@ -620,7 +628,7 @@ class Item_func_numinteriorring: public Item_int_func
Item_func_numinteriorring(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "st_numinteriorrings"; }
- void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
+ bool fix_length_and_dec() { max_length= 10; maybe_null= 1; return FALSE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_numinteriorring>(thd, mem_root, this); }
};
@@ -633,7 +641,7 @@ class Item_func_numpoints: public Item_int_func
Item_func_numpoints(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "st_numpoints"; }
- void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
+ bool fix_length_and_dec() { max_length= 10; maybe_null= 1; return FALSE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_numpoints>(thd, mem_root, this); }
};
@@ -646,10 +654,12 @@ class Item_func_area: public Item_real_func
Item_func_area(THD *thd, Item *a): Item_real_func(thd, a) {}
double val_real();
const char *func_name() const { return "st_area"; }
- void fix_length_and_dec()
- {
- Item_real_func::fix_length_and_dec();
- maybe_null= 1;
+ bool fix_length_and_dec()
+ {
+ if (Item_real_func::fix_length_and_dec())
+ return TRUE;
+ maybe_null= 1;
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_area>(thd, mem_root, this); }
@@ -663,10 +673,12 @@ class Item_func_glength: public Item_real_func
Item_func_glength(THD *thd, Item *a): Item_real_func(thd, a) {}
double val_real();
const char *func_name() const { return "st_length"; }
- void fix_length_and_dec()
- {
- Item_real_func::fix_length_and_dec();
- maybe_null= 1;
+ bool fix_length_and_dec()
+ {
+ if (Item_real_func::fix_length_and_dec())
+ return TRUE;
+ maybe_null= 1;
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_glength>(thd, mem_root, this); }
@@ -680,7 +692,7 @@ class Item_func_srid: public Item_int_func
Item_func_srid(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "srid"; }
- void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
+ bool fix_length_and_dec() { max_length= 10; maybe_null= 1; return FALSE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_srid>(thd, mem_root, this); }
};
diff --git a/sql/item_inetfunc.h b/sql/item_inetfunc.h
index f19749df0af..670dce3da9f 100644
--- a/sql/item_inetfunc.h
+++ b/sql/item_inetfunc.h
@@ -30,12 +30,13 @@ class Item_func_inet_aton : public Item_int_func
Item_func_inet_aton(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "inet_aton"; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
decimals= 0;
max_length= 21;
maybe_null= 1;
unsigned_flag= 1;
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_inet_aton>(thd, mem_root, this); }
@@ -53,11 +54,12 @@ class Item_func_inet_ntoa : public Item_str_func
{ }
String* val_str(String* str);
const char *func_name() const { return "inet_ntoa"; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
decimals= 0;
fix_length_and_charset(3 * 8 + 7, default_charset());
maybe_null= 1;
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_inet_ntoa>(thd, mem_root, this); }
@@ -122,11 +124,12 @@ class Item_func_inet6_aton : public Item_func_inet_str_base
virtual const char *func_name() const
{ return "inet6_aton"; }
- virtual void fix_length_and_dec()
+ virtual bool fix_length_and_dec()
{
decimals= 0;
fix_length_and_charset(16, &my_charset_bin);
maybe_null= 1;
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_inet6_aton>(thd, mem_root, this); }
@@ -151,7 +154,7 @@ class Item_func_inet6_ntoa : public Item_func_inet_str_base
virtual const char *func_name() const
{ return "inet6_ntoa"; }
- virtual void fix_length_and_dec()
+ virtual bool fix_length_and_dec()
{
decimals= 0;
@@ -161,6 +164,7 @@ class Item_func_inet6_ntoa : public Item_func_inet_str_base
fix_length_and_charset(8 * 4 + 7, default_charset());
maybe_null= 1;
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_inet6_ntoa>(thd, mem_root, this); }
diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc
index 794831ae1a5..72aeac5b930 100644
--- a/sql/item_jsonfunc.cc
+++ b/sql/item_jsonfunc.cc
@@ -388,11 +388,13 @@ longlong Item_func_json_valid::val_int()
}
-void Item_func_json_exists::fix_length_and_dec()
+bool Item_func_json_exists::fix_length_and_dec()
{
- Item_int_func::fix_length_and_dec();
+ if (Item_int_func::fix_length_and_dec())
+ return TRUE;
maybe_null= 1;
path.set_constant_flag(args[1]->const_item());
+ return FALSE;
}
@@ -439,12 +441,13 @@ longlong Item_func_json_exists::val_int()
}
-void Item_func_json_value::fix_length_and_dec()
+bool Item_func_json_value::fix_length_and_dec()
{
collation.set(args[0]->collation);
max_length= args[0]->max_length;
path.set_constant_flag(args[1]->const_item());
maybe_null= 1;
+ return FALSE;
}
@@ -546,7 +549,7 @@ bool Item_func_json_query::check_and_get_value(json_engine_t *je, String *res,
}
-void Item_func_json_quote::fix_length_and_dec()
+bool Item_func_json_quote::fix_length_and_dec()
{
collation.set(&my_charset_utf8mb4_bin);
/*
@@ -554,6 +557,7 @@ void Item_func_json_quote::fix_length_and_dec()
of the argument turn into '\uXXXX\uXXXX', which is 12.
*/
max_length= args[0]->max_length * 12 + 2;
+ return FALSE;
}
@@ -581,12 +585,13 @@ String *Item_func_json_quote::val_str(String *str)
}
-void Item_func_json_unquote::fix_length_and_dec()
+bool Item_func_json_unquote::fix_length_and_dec()
{
collation.set(&my_charset_utf8_general_ci,
DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
max_length= args[0]->max_length;
maybe_null= 1;
+ return FALSE;
}
@@ -702,13 +707,14 @@ void Item_json_str_multipath::cleanup()
}
-void Item_func_json_extract::fix_length_and_dec()
+bool Item_func_json_extract::fix_length_and_dec()
{
collation.set(args[0]->collation);
max_length= args[0]->max_length * (arg_count - 1);
mark_constant_paths(paths, args+1, arg_count-1);
maybe_null= 1;
+ return FALSE;
}
@@ -937,14 +943,14 @@ double Item_func_json_extract::val_real()
}
-void Item_func_json_contains::fix_length_and_dec()
+bool Item_func_json_contains::fix_length_and_dec()
{
a2_constant= args[1]->const_item();
a2_parsed= FALSE;
maybe_null= 1;
if (arg_count > 2)
path.set_constant_flag(args[2]->const_item());
- Item_int_func::fix_length_and_dec();
+ return Item_int_func::fix_length_and_dec();
}
@@ -1190,13 +1196,13 @@ bool Item_func_json_contains_path::fix_fields(THD *thd, Item **ref)
}
-void Item_func_json_contains_path::fix_length_and_dec()
+bool Item_func_json_contains_path::fix_length_and_dec()
{
ooa_constant= args[1]->const_item();
ooa_parsed= FALSE;
maybe_null= 1;
mark_constant_paths(paths, args+2, arg_count-2);
- Item_int_func::fix_length_and_dec();
+ return Item_int_func::fix_length_and_dec();
}
@@ -1454,7 +1460,7 @@ static int append_json_keyname(String *str, Item *item, String *tmp_val)
}
-void Item_func_json_array::fix_length_and_dec()
+bool Item_func_json_array::fix_length_and_dec()
{
ulonglong char_length= 2;
uint n_arg;
@@ -1467,17 +1473,18 @@ void Item_func_json_array::fix_length_and_dec()
DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
tmp_val.set_charset(&my_charset_utf8_general_ci);
max_length= 2;
- return;
+ return FALSE;
}
if (agg_arg_charsets_for_string_result(collation, args, arg_count))
- return;
+ return TRUE;
for (n_arg=0 ; n_arg < arg_count ; n_arg++)
char_length+= args[n_arg]->max_char_length() + 4;
fix_char_length_ulonglong(char_length);
tmp_val.set_charset(collation.collation);
+ return FALSE;
}
@@ -1521,7 +1528,7 @@ String *Item_func_json_array::val_str(String *str)
}
-void Item_func_json_array_append::fix_length_and_dec()
+bool Item_func_json_array_append::fix_length_and_dec()
{
uint n_arg;
ulonglong char_length;
@@ -1536,6 +1543,7 @@ void Item_func_json_array_append::fix_length_and_dec()
}
fix_char_length_ulonglong(char_length);
+ return FALSE;
}
@@ -2122,11 +2130,12 @@ String *Item_func_json_merge::val_str(String *str)
}
-void Item_func_json_length::fix_length_and_dec()
+bool Item_func_json_length::fix_length_and_dec()
{
if (arg_count > 1)
path.set_constant_flag(args[1]->const_item());
maybe_null= 1;
+ return FALSE;
}
@@ -2266,11 +2275,12 @@ longlong Item_func_json_depth::val_int()
}
-void Item_func_json_type::fix_length_and_dec()
+bool Item_func_json_type::fix_length_and_dec()
{
collation.set(&my_charset_utf8_general_ci);
max_length= 12;
maybe_null= 1;
+ return FALSE;
}
@@ -2323,7 +2333,7 @@ String *Item_func_json_type::val_str(String *str)
}
-void Item_func_json_insert::fix_length_and_dec()
+bool Item_func_json_insert::fix_length_and_dec()
{
uint n_arg;
ulonglong char_length;
@@ -2339,6 +2349,7 @@ void Item_func_json_insert::fix_length_and_dec()
fix_char_length_ulonglong(char_length);
maybe_null= 1;
+ return FALSE;
}
@@ -2583,13 +2594,14 @@ String *Item_func_json_insert::val_str(String *str)
}
-void Item_func_json_remove::fix_length_and_dec()
+bool Item_func_json_remove::fix_length_and_dec()
{
collation.set(args[0]->collation);
max_length= args[0]->max_length;
mark_constant_paths(paths, args+1, arg_count-1);
maybe_null= 1;
+ return FALSE;
}
@@ -2769,13 +2781,14 @@ String *Item_func_json_remove::val_str(String *str)
}
-void Item_func_json_keys::fix_length_and_dec()
+bool Item_func_json_keys::fix_length_and_dec()
{
collation.set(args[0]->collation);
max_length= args[0]->max_length;
maybe_null= 1;
if (arg_count > 1)
path.set_constant_flag(args[1]->const_item());
+ return FALSE;
}
@@ -2936,7 +2949,7 @@ bool Item_func_json_search::fix_fields(THD *thd, Item **ref)
static const uint SQR_MAX_BLOB_WIDTH= (uint) sqrt(MAX_BLOB_WIDTH);
-void Item_func_json_search::fix_length_and_dec()
+bool Item_func_json_search::fix_length_and_dec()
{
collation.set(args[0]->collation);
@@ -2958,6 +2971,7 @@ void Item_func_json_search::fix_length_and_dec()
if (arg_count > 4)
mark_constant_paths(paths, args+4, arg_count-4);
maybe_null= 1;
+ return FALSE;
}
@@ -3135,11 +3149,12 @@ const char *Item_func_json_format::func_name() const
}
-void Item_func_json_format::fix_length_and_dec()
+bool Item_func_json_format::fix_length_and_dec()
{
decimals= 0;
max_length= args[0]->max_length;
maybe_null= 1;
+ return FALSE;
}
diff --git a/sql/item_jsonfunc.h b/sql/item_jsonfunc.h
index 927b60015b8..f331ee3b582 100644
--- a/sql/item_jsonfunc.h
+++ b/sql/item_jsonfunc.h
@@ -49,10 +49,12 @@ class Item_func_json_valid: public Item_int_func
Item_func_json_valid(THD *thd, Item *json) : Item_int_func(thd, json) {}
longlong val_int();
const char *func_name() const { return "json_valid"; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
- Item_int_func::fix_length_and_dec();
+ if (Item_int_func::fix_length_and_dec())
+ return TRUE;
maybe_null= 1;
+ return FALSE;
}
bool is_bool_type() { return true; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -71,7 +73,7 @@ class Item_func_json_exists: public Item_int_func
Item_int_func(thd, js, i_path) {}
const char *func_name() const { return "json_exists"; }
bool is_bool_type() { return true; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_json_exists>(thd, mem_root, this); }
longlong val_int();
@@ -88,7 +90,7 @@ class Item_func_json_value: public Item_str_func
Item_func_json_value(THD *thd, Item *js, Item *i_path):
Item_str_func(thd, js, i_path) {}
const char *func_name() const { return "json_value"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
String *val_str(String *);
virtual bool check_and_get_value(json_engine_t *je, String *res, int *error);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -117,7 +119,7 @@ class Item_func_json_quote: public Item_str_func
public:
Item_func_json_quote(THD *thd, Item *s): Item_str_func(thd, s) {}
const char *func_name() const { return "json_quote"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
String *val_str(String *);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_json_quote>(thd, mem_root, this); }
@@ -132,7 +134,7 @@ class Item_func_json_unquote: public Item_str_func
public:
Item_func_json_unquote(THD *thd, Item *s): Item_str_func(thd, s) {}
const char *func_name() const { return "json_unquote"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
String *val_str(String *);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_json_unquote>(thd, mem_root, this); }
@@ -165,7 +167,7 @@ class Item_func_json_extract: public Item_json_str_multipath
Item_json_str_multipath(thd, list) {}
const char *func_name() const { return "json_extract"; }
enum Functype functype() const { return JSON_EXTRACT_FUNC; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
String *val_str(String *);
longlong val_int();
double val_real();
@@ -187,7 +189,7 @@ class Item_func_json_contains: public Item_int_func
Item_func_json_contains(THD *thd, List<Item> &list):
Item_int_func(thd, list) {}
const char *func_name() const { return "json_contains"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
longlong val_int();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_json_contains>(thd, mem_root, this); }
@@ -209,7 +211,7 @@ class Item_func_json_contains_path: public Item_int_func
Item_int_func(thd, list), tmp_paths(0) {}
const char *func_name() const { return "json_contains_path"; }
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
void cleanup();
longlong val_int();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -229,7 +231,7 @@ class Item_func_json_array: public Item_str_func
Item_str_func(thd, list) {}
String *val_str(String *);
bool is_json_type() { return true; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "json_array"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_json_array>(thd, mem_root, this); }
@@ -244,7 +246,7 @@ class Item_func_json_array_append: public Item_json_str_multipath
public:
Item_func_json_array_append(THD *thd, List<Item> &list):
Item_json_str_multipath(thd, list) {}
- void fix_length_and_dec();
+ bool fix_length_and_dec();
String *val_str(String *);
uint get_n_paths() const { return arg_count/2; }
const char *func_name() const { return "json_array_append"; }
@@ -305,7 +307,7 @@ class Item_func_json_length: public Item_int_func
Item_func_json_length(THD *thd, List<Item> &list):
Item_int_func(thd, list) {}
const char *func_name() const { return "json_length"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
longlong val_int();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_json_length>(thd, mem_root, this); }
@@ -332,7 +334,7 @@ class Item_func_json_type: public Item_str_func
public:
Item_func_json_type(THD *thd, Item *js): Item_str_func(thd, js) {}
const char *func_name() const { return "json_type"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
String *val_str(String *);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_json_type>(thd, mem_root, this); }
@@ -349,7 +351,7 @@ class Item_func_json_insert: public Item_json_str_multipath
Item_func_json_insert(bool i_mode, bool r_mode, THD *thd, List<Item> &list):
Item_json_str_multipath(thd, list),
mode_insert(i_mode), mode_replace(r_mode) {}
- void fix_length_and_dec();
+ bool fix_length_and_dec();
String *val_str(String *);
uint get_n_paths() const { return arg_count/2; }
const char *func_name() const
@@ -369,7 +371,7 @@ class Item_func_json_remove: public Item_json_str_multipath
public:
Item_func_json_remove(THD *thd, List<Item> &list):
Item_json_str_multipath(thd, list) {}
- void fix_length_and_dec();
+ bool fix_length_and_dec();
String *val_str(String *);
uint get_n_paths() const { return arg_count - 1; }
const char *func_name() const { return "json_remove"; }
@@ -388,7 +390,7 @@ class Item_func_json_keys: public Item_str_func
Item_func_json_keys(THD *thd, List<Item> &list):
Item_str_func(thd, list) {}
const char *func_name() const { return "json_keys"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
String *val_str(String *);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_json_keys>(thd, mem_root, this); }
@@ -412,7 +414,7 @@ class Item_func_json_search: public Item_json_str_multipath
Item_json_str_multipath(thd, list) {}
const char *func_name() const { return "json_search"; }
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
String *val_str(String *);
uint get_n_paths() const { return arg_count > 4 ? arg_count - 4 : 0; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -440,7 +442,7 @@ class Item_func_json_format: public Item_str_func
Item_str_func(thd, list), fmt(DETAILED) {}
const char *func_name() const;
- void fix_length_and_dec();
+ bool fix_length_and_dec();
String *val_str(String *str);
String *val_json(String *str);
bool is_json_type() { return true; }
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 3d543c8c390..87c766340c7 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -188,10 +188,11 @@ String *Item_func_sha::val_str_ascii(String *str)
return 0;
}
-void Item_func_sha::fix_length_and_dec()
+bool Item_func_sha::fix_length_and_dec()
{
// size of hex representation of hash
fix_length_and_charset(MY_SHA1_HASH_SIZE * 2, default_charset());
+ return FALSE;
}
String *Item_func_sha2::val_str_ascii(String *str)
@@ -267,7 +268,7 @@ String *Item_func_sha2::val_str_ascii(String *str)
}
-void Item_func_sha2::fix_length_and_dec()
+bool Item_func_sha2::fix_length_and_dec()
{
maybe_null= 1;
max_length = 0;
@@ -292,6 +293,7 @@ void Item_func_sha2::fix_length_and_dec()
ER_THD(thd, ER_WRONG_PARAMETERS_TO_NATIVE_FCT),
"sha2");
}
+ return FALSE;
}
/* Implementation of AES encryption routines */
@@ -344,23 +346,25 @@ String *Item_aes_crypt::val_str(String *str2)
return 0;
}
-void Item_func_aes_encrypt::fix_length_and_dec()
+bool Item_func_aes_encrypt::fix_length_and_dec()
{
max_length=my_aes_get_size(MY_AES_ECB, args[0]->max_length);
what= ENCRYPTION_FLAG_ENCRYPT;
+ return FALSE;
}
-void Item_func_aes_decrypt::fix_length_and_dec()
+bool Item_func_aes_decrypt::fix_length_and_dec()
{
max_length=args[0]->max_length;
maybe_null= 1;
what= ENCRYPTION_FLAG_DECRYPT;
+ return FALSE;
}
-void Item_func_to_base64::fix_length_and_dec()
+bool Item_func_to_base64::fix_length_and_dec()
{
maybe_null= args[0]->maybe_null;
collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
@@ -375,6 +379,7 @@ void Item_func_to_base64::fix_length_and_dec()
DBUG_ASSERT(length > 0);
fix_char_length_ulonglong((ulonglong) length - 1);
}
+ return FALSE;
}
@@ -410,7 +415,7 @@ String *Item_func_to_base64::val_str_ascii(String *str)
}
-void Item_func_from_base64::fix_length_and_dec()
+bool Item_func_from_base64::fix_length_and_dec()
{
if (args[0]->max_length > (uint) my_base64_decode_max_arg_length())
{
@@ -422,6 +427,7 @@ void Item_func_from_base64::fix_length_and_dec()
fix_char_length_ulonglong((ulonglong) length);
}
maybe_null= 1; // Can be NULL, e.g. in case of badly formed input string
+ return FALSE;
}
@@ -630,17 +636,18 @@ String *Item_func_concat::val_str(String *str)
}
-void Item_func_concat::fix_length_and_dec()
+bool Item_func_concat::fix_length_and_dec()
{
ulonglong char_length= 0;
if (agg_arg_charsets_for_string_result(collation, args, arg_count))
- return;
+ return TRUE;
for (uint i=0 ; i < arg_count ; i++)
char_length+= args[i]->max_char_length();
fix_char_length_ulonglong(char_length);
+ return FALSE;
}
/**
@@ -992,12 +999,12 @@ String *Item_func_concat_ws::val_str(String *str)
}
-void Item_func_concat_ws::fix_length_and_dec()
+bool Item_func_concat_ws::fix_length_and_dec()
{
ulonglong char_length;
if (agg_arg_charsets_for_string_result(collation, args, arg_count))
- return;
+ return TRUE;
/*
arg_count cannot be less than 2,
@@ -1009,6 +1016,7 @@ void Item_func_concat_ws::fix_length_and_dec()
char_length+= args[i]->max_char_length();
fix_char_length_ulonglong(char_length);
+ return FALSE;
}
@@ -1062,11 +1070,12 @@ String *Item_func_reverse::val_str(String *str)
}
-void Item_func_reverse::fix_length_and_dec()
+bool Item_func_reverse::fix_length_and_dec()
{
agg_arg_charsets_for_string_result(collation, args, 1);
DBUG_ASSERT(collation.collation != NULL);
fix_char_length(args[0]->max_char_length());
+ return FALSE;
}
/**
@@ -1208,7 +1217,7 @@ String *Item_func_replace::val_str(String *str)
}
-void Item_func_replace::fix_length_and_dec()
+bool Item_func_replace::fix_length_and_dec()
{
ulonglong char_length= (ulonglong) args[0]->max_char_length();
int diff=(int) (args[2]->max_char_length() - args[1]->max_char_length());
@@ -1219,8 +1228,9 @@ void Item_func_replace::fix_length_and_dec()
}
if (agg_arg_charsets_for_string_result_with_comparison(collation, args, 3))
- return;
+ return TRUE;
fix_char_length_ulonglong(char_length);
+ return FALSE;
}
@@ -1232,13 +1242,14 @@ bool Item_func_regexp_replace::fix_fields(THD *thd, Item **ref)
}
-void Item_func_regexp_replace::fix_length_and_dec()
+bool Item_func_regexp_replace::fix_length_and_dec()
{
if (agg_arg_charsets_for_string_result_with_comparison(collation, args, 3))
- return;
+ return TRUE;
max_length= MAX_BLOB_WIDTH;
re.init(collation.collation, 0);
re.fix_owner(this, args[0], args[1]);
+ return FALSE;
}
@@ -1374,13 +1385,14 @@ bool Item_func_regexp_substr::fix_fields(THD *thd, Item **ref)
}
-void Item_func_regexp_substr::fix_length_and_dec()
+bool Item_func_regexp_substr::fix_length_and_dec()
{
if (agg_arg_charsets_for_string_result_with_comparison(collation, args, 2))
- return;
+ return TRUE;
fix_char_length(args[0]->max_char_length());
re.init(collation.collation, 0);
re.fix_owner(this, args[0], args[1]);
+ return FALSE;
}
@@ -1488,16 +1500,17 @@ String *Item_func_insert::val_str(String *str)
}
-void Item_func_insert::fix_length_and_dec()
+bool Item_func_insert::fix_length_and_dec()
{
ulonglong char_length;
// Handle character set for args[0] and args[3].
if (agg_arg_charsets_for_string_result(collation, args, 2, 3))
- return;
+ return TRUE;
char_length= ((ulonglong) args[0]->max_char_length() +
(ulonglong) args[3]->max_char_length());
fix_char_length_ulonglong(char_length);
+ return FALSE;
}
@@ -1534,22 +1547,26 @@ String *Item_str_conv::val_str(String *str)
}
-void Item_func_lcase::fix_length_and_dec()
+bool Item_func_lcase::fix_length_and_dec()
{
- agg_arg_charsets_for_string_result(collation, args, 1);
+ if (agg_arg_charsets_for_string_result(collation, args, 1))
+ return TRUE;
DBUG_ASSERT(collation.collation != NULL);
multiply= collation.collation->casedn_multiply;
converter= collation.collation->cset->casedn;
fix_char_length_ulonglong((ulonglong) args[0]->max_char_length() * multiply);
+ return FALSE;
}
-void Item_func_ucase::fix_length_and_dec()
+bool Item_func_ucase::fix_length_and_dec()
{
- agg_arg_charsets_for_string_result(collation, args, 1);
+ if (agg_arg_charsets_for_string_result(collation, args, 1))
+ return TRUE;
DBUG_ASSERT(collation.collation != NULL);
multiply= collation.collation->caseup_multiply;
converter= collation.collation->cset->caseup;
fix_char_length_ulonglong((ulonglong) args[0]->max_char_length() * multiply);
+ return FALSE;
}
@@ -1592,11 +1609,13 @@ void Item_str_func::left_right_max_length()
}
-void Item_func_left::fix_length_and_dec()
+bool Item_func_left::fix_length_and_dec()
{
- agg_arg_charsets_for_string_result(collation, args, 1);
+ if (agg_arg_charsets_for_string_result(collation, args, 1))
+ return TRUE;
DBUG_ASSERT(collation.collation != NULL);
left_right_max_length();
+ return FALSE;
}
@@ -1626,11 +1645,13 @@ String *Item_func_right::val_str(String *str)
}
-void Item_func_right::fix_length_and_dec()
+bool Item_func_right::fix_length_and_dec()
{
- agg_arg_charsets_for_string_result(collation, args, 1);
+ if (agg_arg_charsets_for_string_result(collation, args, 1))
+ return TRUE;
DBUG_ASSERT(collation.collation != NULL);
left_right_max_length();
+ return FALSE;
}
@@ -1681,11 +1702,12 @@ String *Item_func_substr::val_str(String *str)
}
-void Item_func_substr::fix_length_and_dec()
+bool Item_func_substr::fix_length_and_dec()
{
max_length=args[0]->max_length;
- agg_arg_charsets_for_string_result(collation, args, 1);
+ if (agg_arg_charsets_for_string_result(collation, args, 1))
+ return TRUE;
DBUG_ASSERT(collation.collation != NULL);
if (args[1]->const_item())
{
@@ -1706,14 +1728,16 @@ void Item_func_substr::fix_length_and_dec()
set_if_smaller(max_length,(uint) length);
}
max_length*= collation.collation->mbmaxlen;
+ return FALSE;
}
-void Item_func_substr_index::fix_length_and_dec()
-{
+bool Item_func_substr_index::fix_length_and_dec()
+{
if (agg_arg_charsets_for_string_result_with_comparison(collation, args, 2))
- return;
+ return TRUE;
fix_char_length(args[0]->max_char_length());
+ return FALSE;
}
@@ -2037,11 +2061,12 @@ String *Item_func_trim::val_str(String *str)
return trimmed_value(res, (uint32) (ptr - res->ptr()), (uint32) (end - ptr));
}
-void Item_func_trim::fix_length_and_dec()
+bool Item_func_trim::fix_length_and_dec()
{
if (arg_count == 1)
{
- agg_arg_charsets_for_string_result(collation, args, 1);
+ if (agg_arg_charsets_for_string_result(collation, args, 1))
+ return TRUE;
DBUG_ASSERT(collation.collation != NULL);
remove.set_charset(collation.collation);
remove.set_ascii(" ",1);
@@ -2052,9 +2077,10 @@ void Item_func_trim::fix_length_and_dec()
// Note that we pass args[1] as the first item, and args[0] as the second.
if (agg_arg_charsets_for_string_result_with_comparison(collation,
&args[1], 2, -1))
- return;
+ return TRUE;
}
fix_char_length(args[0]->max_char_length());
+ return FALSE;
}
void Item_func_trim::print(String *str, enum_query_type query_type)
@@ -2194,7 +2220,7 @@ bool Item_func_encode::seed()
return FALSE;
}
-void Item_func_encode::fix_length_and_dec()
+bool Item_func_encode::fix_length_and_dec()
{
max_length=args[0]->max_length;
maybe_null=args[0]->maybe_null || args[1]->maybe_null;
@@ -2202,6 +2228,7 @@ void Item_func_encode::fix_length_and_dec()
/* Precompute the seed state if the item is constant. */
seeded= args[1]->const_item() &&
(args[1]->result_type() == STRING_RESULT) && !seed();
+ return FALSE;
}
String *Item_func_encode::val_str(String *str)
@@ -2347,13 +2374,14 @@ bool Item_func_current_role::fix_fields(THD *thd, Item **ref)
return 0;
}
-void Item_func_soundex::fix_length_and_dec()
+bool Item_func_soundex::fix_length_and_dec()
{
uint32 char_length= args[0]->max_char_length();
agg_arg_charsets_for_string_result(collation, args, 1);
DBUG_ASSERT(collation.collation != NULL);
set_if_bigger(char_length, 4);
fix_char_length(char_length);
+ return FALSE;
}
@@ -2529,7 +2557,7 @@ MY_LOCALE *Item_func_format::get_locale(Item *item)
return lc;
}
-void Item_func_format::fix_length_and_dec()
+bool Item_func_format::fix_length_and_dec()
{
uint32 char_length= args[0]->max_char_length();
uint32 max_sep_count= (char_length / 3) + (decimals ? 1 : 0) + /*sign*/1;
@@ -2539,6 +2567,7 @@ void Item_func_format::fix_length_and_dec()
locale= args[2]->basic_const_item() ? get_locale(args[2]) : NULL;
else
locale= &my_locale_en_US; /* Two arguments */
+ return FALSE;
}
@@ -2652,13 +2681,13 @@ String *Item_func_format::val_str_ascii(String *str)
}
-void Item_func_elt::fix_length_and_dec()
+bool Item_func_elt::fix_length_and_dec()
{
uint32 char_length= 0;
decimals=0;
if (agg_arg_charsets_for_string_result(collation, args + 1, arg_count - 1))
- return;
+ return TRUE;
for (uint i= 1 ; i < arg_count ; i++)
{
@@ -2667,6 +2696,7 @@ void Item_func_elt::fix_length_and_dec()
}
fix_char_length(char_length);
maybe_null=1; // NULL if wrong first arg
+ return FALSE;
}
@@ -2713,16 +2743,17 @@ String *Item_func_elt::val_str(String *str)
}
-void Item_func_make_set::fix_length_and_dec()
+bool Item_func_make_set::fix_length_and_dec()
{
uint32 char_length= arg_count - 2; /* Separators */
if (agg_arg_charsets_for_string_result(collation, args + 1, arg_count - 1))
- return;
+ return TRUE;
for (uint i=1 ; i < arg_count ; i++)
char_length+= args[i]->max_char_length();
fix_char_length(char_length);
+ return FALSE;
}
@@ -2853,9 +2884,10 @@ inline String* alloc_buffer(String *res,String *str,String *tmp_value,
}
-void Item_func_repeat::fix_length_and_dec()
+bool Item_func_repeat::fix_length_and_dec()
{
- agg_arg_charsets_for_string_result(collation, args, 1);
+ if (agg_arg_charsets_for_string_result(collation, args, 1))
+ return TRUE;
DBUG_ASSERT(collation.collation != NULL);
if (args[1]->const_item())
{
@@ -2877,6 +2909,7 @@ void Item_func_repeat::fix_length_and_dec()
max_length= MAX_BLOB_WIDTH;
maybe_null= 1;
}
+ return FALSE;
}
/**
@@ -2938,7 +2971,7 @@ String *Item_func_repeat::val_str(String *str)
}
-void Item_func_space::fix_length_and_dec()
+bool Item_func_space::fix_length_and_dec()
{
collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
if (args[0]->const_item())
@@ -2954,12 +2987,13 @@ void Item_func_space::fix_length_and_dec()
if (count > INT_MAX32)
count= INT_MAX32;
fix_char_length_ulonglong(count);
- return;
+ return FALSE;
}
end:
max_length= MAX_BLOB_WIDTH;
maybe_null= 1;
+ return FALSE;
}
@@ -3009,11 +3043,12 @@ String *Item_func_space::val_str(String *str)
}
-void Item_func_binlog_gtid_pos::fix_length_and_dec()
+bool Item_func_binlog_gtid_pos::fix_length_and_dec()
{
collation.set(system_charset_info);
max_length= MAX_BLOB_WIDTH;
maybe_null= 1;
+ return FALSE;
}
@@ -3049,11 +3084,11 @@ String *Item_func_binlog_gtid_pos::val_str(String *str)
}
-void Item_func_rpad::fix_length_and_dec()
+bool Item_func_rpad::fix_length_and_dec()
{
// Handle character set for args[0] and args[2].
if (agg_arg_charsets_for_string_result(collation, &args[0], 2, 2))
- return;
+ return TRUE;
if (args[1]->const_item())
{
ulonglong char_length= (ulonglong) args[1]->val_int();
@@ -3071,6 +3106,7 @@ void Item_func_rpad::fix_length_and_dec()
max_length= MAX_BLOB_WIDTH;
maybe_null= 1;
}
+ return FALSE;
}
@@ -3157,12 +3193,12 @@ String *Item_func_rpad::val_str(String *str)
}
-void Item_func_lpad::fix_length_and_dec()
+bool Item_func_lpad::fix_length_and_dec()
{
// Handle character set for args[0] and args[2].
if (agg_arg_charsets_for_string_result(collation, &args[0], 2, 2))
- return;
-
+ return TRUE;
+
if (args[1]->const_item())
{
ulonglong char_length= (ulonglong) args[1]->val_int();
@@ -3180,6 +3216,7 @@ void Item_func_lpad::fix_length_and_dec()
max_length= MAX_BLOB_WIDTH;
maybe_null= 1;
}
+ return FALSE;
}
@@ -3329,10 +3366,11 @@ String *Item_func_conv_charset::val_str(String *str)
0 : str;
}
-void Item_func_conv_charset::fix_length_and_dec()
+bool Item_func_conv_charset::fix_length_and_dec()
{
DBUG_ASSERT(collation.derivation == DERIVATION_IMPLICIT);
fix_char_length(args[0]->max_char_length());
+ return FALSE;
}
void Item_func_conv_charset::print(String *str, enum_query_type query_type)
@@ -3354,7 +3392,7 @@ String *Item_func_set_collation::val_str(String *str)
return str;
}
-void Item_func_set_collation::fix_length_and_dec()
+bool Item_func_set_collation::fix_length_and_dec()
{
CHARSET_INFO *set_collation;
const char *colname;
@@ -3365,8 +3403,8 @@ void Item_func_set_collation::fix_length_and_dec()
MY_CS_BINSORT,MYF(0));
else
{
- if (!(set_collation= mysqld_collation_get_by_name(colname)))
- return;
+ if (!(set_collation= mysqld_collation_get_by_name(colname)))
+ return TRUE;
}
if (!set_collation ||
@@ -3374,11 +3412,12 @@ void Item_func_set_collation::fix_length_and_dec()
{
my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0),
colname, args[0]->collation.collation->csname);
- return;
+ return TRUE;
}
collation.set(set_collation, DERIVATION_EXPLICIT,
args[0]->collation.repertoire);
max_length= args[0]->max_length;
+ return FALSE;
}
@@ -3437,7 +3476,7 @@ String *Item_func_collation::val_str(String *str)
}
-void Item_func_weight_string::fix_length_and_dec()
+bool Item_func_weight_string::fix_length_and_dec()
{
CHARSET_INFO *cs= args[0]->collation.collation;
collation.set(&my_charset_bin, args[0]->collation.derivation);
@@ -3455,6 +3494,7 @@ void Item_func_weight_string::fix_length_and_dec()
max_length= cs->coll->strnxfrmlen(cs, char_length * cs->mbmaxlen);
}
maybe_null= 1;
+ return FALSE;
}
@@ -3838,15 +3878,16 @@ String* Item_func_export_set::val_str(String* str)
return str;
}
-void Item_func_export_set::fix_length_and_dec()
+bool Item_func_export_set::fix_length_and_dec()
{
uint32 length= MY_MAX(args[1]->max_char_length(), args[2]->max_char_length());
uint32 sep_length= (arg_count > 3 ? args[3]->max_char_length() : 1);
if (agg_arg_charsets_for_string_result(collation,
args + 1, MY_MIN(4, arg_count) - 1))
- return;
+ return TRUE;
fix_char_length(length * 64 + sep_length * 63);
+ return FALSE;
}
@@ -4246,12 +4287,13 @@ bool Item_func_dyncol_create::fix_fields(THD *thd, Item **ref)
}
-void Item_func_dyncol_create::fix_length_and_dec()
+bool Item_func_dyncol_create::fix_length_and_dec()
{
max_length= MAX_BLOB_WIDTH;
maybe_null= TRUE;
collation.set(&my_charset_bin);
decimals= 0;
+ return FALSE;
}
bool Item_func_dyncol_create::prepare_arguments(THD *thd, bool force_names_arg)
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index c9956ab364e..a908aba2d2f 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -145,9 +145,10 @@ class Item_func_md5 :public Item_str_ascii_checksum_func
public:
Item_func_md5(THD *thd, Item *a): Item_str_ascii_checksum_func(thd, a) {}
String *val_str_ascii(String *);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
fix_length_and_charset(32, default_charset());
+ return FALSE;
}
const char *func_name() const { return "md5"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -160,7 +161,7 @@ class Item_func_sha :public Item_str_ascii_checksum_func
public:
Item_func_sha(THD *thd, Item *a): Item_str_ascii_checksum_func(thd, a) {}
String *val_str_ascii(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "sha"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_sha>(thd, mem_root, this); }
@@ -172,7 +173,7 @@ class Item_func_sha2 :public Item_str_ascii_checksum_func
Item_func_sha2(THD *thd, Item *a, Item *b)
:Item_str_ascii_checksum_func(thd, a, b) {}
String *val_str_ascii(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "sha2"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_sha2>(thd, mem_root, this); }
@@ -185,7 +186,7 @@ class Item_func_to_base64 :public Item_str_ascii_checksum_func
Item_func_to_base64(THD *thd, Item *a)
:Item_str_ascii_checksum_func(thd, a) {}
String *val_str_ascii(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "to_base64"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_to_base64>(thd, mem_root, this); }
@@ -198,7 +199,7 @@ class Item_func_from_base64 :public Item_str_binary_checksum_func
Item_func_from_base64(THD *thd, Item *a)
:Item_str_binary_checksum_func(thd, a) { }
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "from_base64"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_from_base64>(thd, mem_root, this); }
@@ -225,7 +226,7 @@ class Item_func_aes_encrypt :public Item_aes_crypt
public:
Item_func_aes_encrypt(THD *thd, Item *a, Item *b)
:Item_aes_crypt(thd, a, b) {}
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "aes_encrypt"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_aes_encrypt>(thd, mem_root, this); }
@@ -236,7 +237,7 @@ class Item_func_aes_decrypt :public Item_aes_crypt
public:
Item_func_aes_decrypt(THD *thd, Item *a, Item *b):
Item_aes_crypt(thd, a, b) {}
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "aes_decrypt"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_aes_decrypt>(thd, mem_root, this); }
@@ -251,7 +252,7 @@ class Item_func_concat :public Item_str_func
Item_func_concat(THD *thd, List<Item> &list): Item_str_func(thd, list) {}
Item_func_concat(THD *thd, Item *a, Item *b): Item_str_func(thd, a, b) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "concat"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_concat>(thd, mem_root, this); }
@@ -263,11 +264,12 @@ class Item_func_decode_histogram :public Item_str_func
Item_func_decode_histogram(THD *thd, Item *a, Item *b):
Item_str_func(thd, a, b) {}
String *val_str(String *);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
collation.set(system_charset_info);
max_length= MAX_BLOB_WIDTH;
maybe_null= 1;
+ return FALSE;
}
const char *func_name() const { return "decode_histogram"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -280,7 +282,7 @@ class Item_func_concat_ws :public Item_str_func
public:
Item_func_concat_ws(THD *thd, List<Item> &list): Item_str_func(thd, list) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "concat_ws"; }
table_map not_null_tables() const { return 0; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -293,7 +295,7 @@ class Item_func_reverse :public Item_str_func
public:
Item_func_reverse(THD *thd, Item *a): Item_str_func(thd, a) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "reverse"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_reverse>(thd, mem_root, this); }
@@ -307,7 +309,7 @@ class Item_func_replace :public Item_str_func
Item_func_replace(THD *thd, Item *org, Item *find, Item *replace):
Item_str_func(thd, org, find, replace) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "replace"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_replace>(thd, mem_root, this); }
@@ -333,7 +335,7 @@ class Item_func_regexp_replace :public Item_str_func
}
String *val_str(String *str);
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "regexp_replace"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return 0;}
};
@@ -355,7 +357,7 @@ class Item_func_regexp_substr :public Item_str_func
}
String *val_str(String *str);
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "regexp_substr"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
};
@@ -369,7 +371,7 @@ class Item_func_insert :public Item_str_func
Item *new_str):
Item_str_func(thd, org, start, length, new_str) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "insert"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_insert>(thd, mem_root, this); }
@@ -393,7 +395,7 @@ class Item_func_lcase :public Item_str_conv
public:
Item_func_lcase(THD *thd, Item *item): Item_str_conv(thd, item) {}
const char *func_name() const { return "lcase"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_lcase>(thd, mem_root, this); }
};
@@ -403,7 +405,7 @@ class Item_func_ucase :public Item_str_conv
public:
Item_func_ucase(THD *thd, Item *item): Item_str_conv(thd, item) {}
const char *func_name() const { return "ucase"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_ucase>(thd, mem_root, this); }
};
@@ -415,7 +417,7 @@ class Item_func_left :public Item_str_func
public:
Item_func_left(THD *thd, Item *a, Item *b): Item_str_func(thd, a, b) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "left"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_left>(thd, mem_root, this); }
@@ -428,7 +430,7 @@ class Item_func_right :public Item_str_func
public:
Item_func_right(THD *thd, Item *a, Item *b): Item_str_func(thd, a, b) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "right"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_right>(thd, mem_root, this); }
@@ -442,7 +444,7 @@ class Item_func_substr :public Item_str_func
Item_func_substr(THD *thd, Item *a, Item *b): Item_str_func(thd, a, b) {}
Item_func_substr(THD *thd, Item *a, Item *b, Item *c): Item_str_func(thd, a, b, c) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "substr"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_substr>(thd, mem_root, this); }
@@ -456,7 +458,7 @@ class Item_func_substr_index :public Item_str_func
Item_func_substr_index(THD *thd, Item *a,Item *b,Item *c):
Item_str_func(thd, a, b, c) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "substring_index"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_substr_index>(thd, mem_root, this); }
@@ -488,7 +490,7 @@ class Item_func_trim :public Item_str_func
Item_func_trim(THD *thd, Item *a, Item *b): Item_str_func(thd, a, b) {}
Item_func_trim(THD *thd, Item *a): Item_str_func(thd, a) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "trim"; }
void print(String *str, enum_query_type query_type);
virtual const char *mode_name() const { return "both"; }
@@ -546,12 +548,13 @@ class Item_func_password :public Item_str_ascii_checksum_func
Item_str_ascii_checksum_func(thd, a), alg(al), deflt(0) {}
String *val_str_ascii(String *str);
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
fix_length_and_charset((alg == 1 ?
SCRAMBLED_PASSWORD_CHAR_LENGTH :
SCRAMBLED_PASSWORD_CHAR_LENGTH_323),
default_charset());
+ return FALSE;
}
const char *func_name() const { return ((deflt || alg == 1) ?
"password" : "old_password"); }
@@ -572,11 +575,12 @@ class Item_func_des_encrypt :public Item_str_binary_checksum_func
Item_func_des_encrypt(THD *thd, Item *a, Item *b)
:Item_str_binary_checksum_func(thd, a, b) {}
String *val_str(String *);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
maybe_null=1;
/* 9 = MAX ((8- (arg_len % 8)) + 1) */
max_length = args[0]->max_length + 9;
+ return FALSE;
}
const char *func_name() const { return "des_encrypt"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -592,13 +596,14 @@ class Item_func_des_decrypt :public Item_str_binary_checksum_func
Item_func_des_decrypt(THD *thd, Item *a, Item *b)
:Item_str_binary_checksum_func(thd, a, b) {}
String *val_str(String *);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
maybe_null=1;
/* 9 = MAX ((8- (arg_len % 8)) + 1) */
max_length= args[0]->max_length;
if (max_length >= 9U)
max_length-= 9U;
+ return FALSE;
}
const char *func_name() const { return "des_decrypt"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -631,7 +636,7 @@ class Item_func_encrypt :public Item_str_binary_checksum_func
constructor_helper();
}
String *val_str(String *);
- void fix_length_and_dec() { maybe_null=1; max_length = 13; }
+ bool fix_length_and_dec() { maybe_null=1; max_length = 13; return FALSE; }
const char *func_name() const { return "encrypt"; }
bool check_vcol_func_processor(void *arg)
{
@@ -655,7 +660,7 @@ class Item_func_encode :public Item_str_binary_checksum_func
Item_func_encode(THD *thd, Item *a, Item *seed_arg):
Item_str_binary_checksum_func(thd, a, seed_arg) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "encode"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_encode>(thd, mem_root, this); }
@@ -705,10 +710,11 @@ class Item_func_database :public Item_func_sysconst
public:
Item_func_database(THD *thd): Item_func_sysconst(thd) {}
String *val_str(String *);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
max_length= MAX_FIELD_NAME * system_charset_info->mbmaxlen;
maybe_null=1;
+ return FALSE;
}
const char *func_name() const { return "database"; }
const char *fully_qualified_func_name() const { return "database()"; }
@@ -733,10 +739,11 @@ class Item_func_user :public Item_func_sysconst
return (null_value ? 0 : &str_value);
}
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
max_length= (uint32) (username_char_length +
HOSTNAME_LENGTH + 1) * SYSTEM_CHARSET_MBMAXLEN;
+ return FALSE;
}
const char *func_name() const { return "user"; }
const char *fully_qualified_func_name() const { return "user()"; }
@@ -776,8 +783,11 @@ class Item_func_current_role :public Item_func_sysconst
Item_func_current_role(THD *thd, Name_resolution_context *context_arg):
Item_func_sysconst(thd), context(context_arg) {}
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec()
- { max_length= (uint32) username_char_length * SYSTEM_CHARSET_MBMAXLEN; }
+ bool fix_length_and_dec()
+ {
+ max_length= (uint32) username_char_length * SYSTEM_CHARSET_MBMAXLEN;
+ return FALSE;
+ }
int save_in_field(Field *field, bool no_conversions)
{ return save_str_value_in_field(field, &str_value); }
const char *func_name() const { return "current_role"; }
@@ -805,7 +815,7 @@ class Item_func_soundex :public Item_str_func
public:
Item_func_soundex(THD *thd, Item *a): Item_str_func(thd, a) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "soundex"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_soundex>(thd, mem_root, this); }
@@ -819,7 +829,7 @@ class Item_func_elt :public Item_str_func
double val_real();
longlong val_int();
String *val_str(String *str);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "elt"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_elt>(thd, mem_root, this); }
@@ -833,7 +843,7 @@ class Item_func_make_set :public Item_str_func
public:
Item_func_make_set(THD *thd, List<Item> &list): Item_str_func(thd, list) {}
String *val_str(String *str);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "make_set"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_make_set>(thd, mem_root, this); }
@@ -851,7 +861,7 @@ class Item_func_format :public Item_str_ascii_func
MY_LOCALE *get_locale(Item *item);
String *val_str_ascii(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "format"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_format>(thd, mem_root, this); }
@@ -867,9 +877,10 @@ class Item_func_char :public Item_str_func
Item_str_func(thd, list)
{ collation.set(cs); }
String *val_str(String *);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
max_length= arg_count * 4;
+ return FALSE;
}
const char *func_name() const { return "char"; }
void print(String *str, enum_query_type query_type);
@@ -885,7 +896,7 @@ class Item_func_repeat :public Item_str_func
Item_func_repeat(THD *thd, Item *arg1, Item *arg2):
Item_str_func(thd, arg1, arg2) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "repeat"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_repeat>(thd, mem_root, this); }
@@ -897,7 +908,7 @@ class Item_func_space :public Item_str_func
public:
Item_func_space(THD *thd, Item *arg1): Item_str_func(thd, arg1) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "space"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_space>(thd, mem_root, this); }
@@ -910,7 +921,7 @@ class Item_func_binlog_gtid_pos :public Item_str_func
Item_func_binlog_gtid_pos(THD *thd, Item *arg1, Item *arg2):
Item_str_func(thd, arg1, arg2) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "binlog_gtid_pos"; }
bool check_vcol_func_processor(void *arg)
{
@@ -928,7 +939,7 @@ class Item_func_rpad :public Item_str_func
Item_func_rpad(THD *thd, Item *arg1, Item *arg2, Item *arg3):
Item_str_func(thd, arg1, arg2, arg3) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "rpad"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_rpad>(thd, mem_root, this); }
@@ -942,7 +953,7 @@ class Item_func_lpad :public Item_str_func
Item_func_lpad(THD *thd, Item *arg1, Item *arg2, Item *arg3):
Item_str_func(thd, arg1, arg2, arg3) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "lpad"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_lpad>(thd, mem_root, this); }
@@ -956,11 +967,12 @@ class Item_func_conv :public Item_str_func
Item_str_func(thd, a, b, c) {}
const char *func_name() const { return "conv"; }
String *val_str(String *);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
collation.set(default_charset());
max_length=64;
maybe_null= 1;
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_conv>(thd, mem_root, this); }
@@ -975,11 +987,12 @@ class Item_func_hex :public Item_str_ascii_checksum_func
Item_str_ascii_checksum_func(thd, a) {}
const char *func_name() const { return "hex"; }
String *val_str_ascii(String *);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
collation.set(default_charset());
decimals=0;
fix_char_length(args[0]->max_length * 2);
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_hex>(thd, mem_root, this); }
@@ -996,11 +1009,12 @@ class Item_func_unhex :public Item_str_func
}
const char *func_name() const { return "unhex"; }
String *val_str(String *);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
collation.set(&my_charset_bin);
decimals=0;
max_length=(1+args[0]->max_length)/2;
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_unhex>(thd, mem_root, this); }
@@ -1019,11 +1033,12 @@ class Item_func_like_range :public Item_str_func
Item_str_func(thd, a, b), is_min(is_min_arg)
{ maybe_null= 1; }
String *val_str(String *);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
collation.set(args[0]->collation);
decimals=0;
max_length= MAX_BLOB_WIDTH;
+ return FALSE;
}
};
@@ -1064,10 +1079,11 @@ class Item_func_binary :public Item_str_func
tmp->set_charset(&my_charset_bin);
return tmp;
}
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
collation.set(&my_charset_bin);
max_length=args[0]->max_length;
+ return FALSE;
}
void print(String *str, enum_query_type query_type);
const char *func_name() const { return "cast_as_binary"; }
@@ -1084,11 +1100,12 @@ class Item_load_file :public Item_str_func
Item_load_file(THD *thd, Item *a): Item_str_func(thd, a) {}
String *val_str(String *);
const char *func_name() const { return "load_file"; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
collation.set(&my_charset_bin, DERIVATION_COERCIBLE);
maybe_null=1;
max_length=MAX_BLOB_WIDTH;
+ return FALSE;
}
bool check_vcol_func_processor(void *arg)
{
@@ -1109,7 +1126,7 @@ class Item_func_export_set: public Item_str_func
Item_func_export_set(THD *thd, Item *a, Item *b, Item* c, Item* d, Item* e):
Item_str_func(thd, a, b, c, d, e) {}
String *val_str(String *str);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "export_set"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_export_set>(thd, mem_root, this); }
@@ -1123,12 +1140,13 @@ class Item_func_quote :public Item_str_func
Item_func_quote(THD *thd, Item *a): Item_str_func(thd, a) {}
const char *func_name() const { return "quote"; }
String *val_str(String *);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
collation.set(args[0]->collation);
ulonglong max_result_length= (ulonglong) args[0]->max_length * 2 +
2 * collation.collation->mbmaxlen;
max_length= (uint32) MY_MIN(max_result_length, MAX_BLOB_WIDTH);
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_quote>(thd, mem_root, this); }
@@ -1211,7 +1229,7 @@ class Item_func_conv_charset :public Item_str_func
return 1;
return res;
}
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "convert"; }
void print(String *str, enum_query_type query_type);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -1224,7 +1242,7 @@ class Item_func_set_collation :public Item_str_func
Item_func_set_collation(THD *thd, Item *a, Item *b):
Item_str_func(thd, a, b) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool eq(const Item *item, bool binary_cmp) const;
const char *func_name() const { return "collate"; }
enum precedence precedence() const { return COLLATE_PRECEDENCE; }
@@ -1245,11 +1263,12 @@ class Item_func_expr_str_metadata :public Item_str_func
{
public:
Item_func_expr_str_metadata(THD *thd, Item *a): Item_str_func(thd, a) { }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
collation.set(system_charset_info);
max_length= 64 * collation.collation->mbmaxlen; // should be enough
maybe_null= 0;
+ return FALSE;
};
table_map not_null_tables() const { return 0; }
Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
@@ -1299,7 +1318,7 @@ class Item_func_weight_string :public Item_str_func
}
const char *func_name() const { return "weight_string"; }
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool eq(const Item *item, bool binary_cmp) const
{
if (!Item_str_func::eq(item, binary_cmp))
@@ -1323,7 +1342,7 @@ class Item_func_crc32 :public Item_int_func
Item_func_crc32(THD *thd, Item *a): Item_int_func(thd, a)
{ unsigned_flag= 1; }
const char *func_name() const { return "crc32"; }
- void fix_length_and_dec() { max_length=10; }
+ bool fix_length_and_dec() { max_length=10; return FALSE; }
longlong val_int();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_crc32>(thd, mem_root, this); }
@@ -1335,7 +1354,7 @@ class Item_func_uncompressed_length : public Item_int_func
public:
Item_func_uncompressed_length(THD *thd, Item *a): Item_int_func(thd, a) {}
const char *func_name() const{return "uncompressed_length";}
- void fix_length_and_dec() { max_length=10; maybe_null= true; }
+ bool fix_length_and_dec() { max_length=10; maybe_null= true; return FALSE; }
longlong val_int();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_uncompressed_length>(thd, mem_root, this); }
@@ -1353,7 +1372,11 @@ class Item_func_compress: public Item_str_binary_checksum_func
public:
Item_func_compress(THD *thd, Item *a)
:Item_str_binary_checksum_func(thd, a) {}
- void fix_length_and_dec(){max_length= (args[0]->max_length*120)/100+12;}
+ bool fix_length_and_dec()
+ {
+ max_length= (args[0]->max_length * 120) / 100 + 12;
+ return FALSE;
+ }
const char *func_name() const{return "compress";}
String *val_str(String *) ZLIB_DEPENDED_FUNCTION
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -1366,7 +1389,11 @@ class Item_func_uncompress: public Item_str_binary_checksum_func
public:
Item_func_uncompress(THD *thd, Item *a)
:Item_str_binary_checksum_func(thd, a) {}
- void fix_length_and_dec(){ maybe_null= 1; max_length= MAX_BLOB_WIDTH; }
+ bool fix_length_and_dec()
+ {
+ maybe_null= 1; max_length= MAX_BLOB_WIDTH;
+ return FALSE;
+ }
const char *func_name() const{return "uncompress";}
String *val_str(String *) ZLIB_DEPENDED_FUNCTION
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -1378,11 +1405,12 @@ class Item_func_uuid: public Item_str_func
{
public:
Item_func_uuid(THD *thd): Item_str_func(thd) {}
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
collation.set(system_charset_info,
DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
fix_char_length(MY_UUID_STRING_LENGTH);
+ return FALSE;
}
bool const_item() const { return false; }
table_map used_tables() const { return RAND_TABLE_BIT; }
@@ -1410,7 +1438,7 @@ class Item_func_dyncol_create: public Item_str_func
public:
Item_func_dyncol_create(THD *thd, List<Item> &args, DYNCALL_CREATE_DEF *dfs);
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const{ return "column_create"; }
String *val_str(String *);
void print(String *str, enum_query_type query_type);
@@ -1440,11 +1468,12 @@ class Item_func_dyncol_json: public Item_str_func
{collation.set(DYNCOL_UTF);}
const char *func_name() const{ return "column_json"; }
String *val_str(String *);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
max_length= MAX_BLOB_WIDTH;
maybe_null= 1;
decimals= 0;
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_dyncol_json>(thd, mem_root, this); }
@@ -1459,8 +1488,8 @@ class Item_dyncol_get: public Item_str_func
public:
Item_dyncol_get(THD *thd, Item *str, Item *num): Item_str_func(thd, str, num)
{}
- void fix_length_and_dec()
- { maybe_null= 1;; max_length= MAX_BLOB_WIDTH; }
+ bool fix_length_and_dec()
+ { maybe_null= 1;; max_length= MAX_BLOB_WIDTH; return FALSE; }
/* Mark that collation can change between calls */
bool dynamic_result() { return 1; }
@@ -1498,7 +1527,8 @@ class Item_func_dyncol_list: public Item_str_func
public:
Item_func_dyncol_list(THD *thd, Item *str): Item_str_func(thd, str)
{collation.set(DYNCOL_UTF);}
- void fix_length_and_dec() { maybe_null= 1; max_length= MAX_BLOB_WIDTH; };
+ bool fix_length_and_dec()
+ { maybe_null= 1; max_length= MAX_BLOB_WIDTH; return FALSE; };
const char *func_name() const{ return "column_list"; }
String *val_str(String *);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 4214980c36c..ca49e06a9e7 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -307,7 +307,8 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
goto end;
}
- fix_length_and_dec();
+ if (fix_length_and_dec())
+ goto end;
}
else
goto end;
@@ -904,9 +905,10 @@ Item::Type Item_subselect::type() const
}
-void Item_subselect::fix_length_and_dec()
+bool Item_subselect::fix_length_and_dec()
{
engine->fix_length_and_dec(0);
+ return FALSE;
}
@@ -1194,7 +1196,7 @@ enum_field_types Item_singlerow_subselect::field_type() const
return engine->field_type();
}
-void Item_singlerow_subselect::fix_length_and_dec()
+bool Item_singlerow_subselect::fix_length_and_dec()
{
if ((max_columns= engine->cols()) == 1)
{
@@ -1204,7 +1206,7 @@ void Item_singlerow_subselect::fix_length_and_dec()
{
if (!(row= (Item_cache**) current_thd->alloc(sizeof(Item_cache*) *
max_columns)))
- return;
+ return TRUE;
engine->fix_length_and_dec(row);
value= *row;
}
@@ -1221,6 +1223,7 @@ void Item_singlerow_subselect::fix_length_and_dec()
for (uint i= 0; i < max_columns; i++)
row[i]->maybe_null= TRUE;
}
+ return FALSE;
}
@@ -1505,7 +1508,7 @@ void Item_exists_subselect::init_length_and_dec()
}
-void Item_exists_subselect::fix_length_and_dec()
+bool Item_exists_subselect::fix_length_and_dec()
{
DBUG_ENTER("Item_exists_subselect::fix_length_and_dec");
init_length_and_dec();
@@ -1516,11 +1519,11 @@ void Item_exists_subselect::fix_length_and_dec()
thd->change_item_tree(&unit->global_parameters()->select_limit,
new (thd->mem_root) Item_int(thd, (int32) 1));
DBUG_PRINT("info", ("Set limit to 1"));
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
-void Item_in_subselect::fix_length_and_dec()
+bool Item_in_subselect::fix_length_and_dec()
{
DBUG_ENTER("Item_in_subselect::fix_length_and_dec");
init_length_and_dec();
@@ -1528,7 +1531,7 @@ void Item_in_subselect::fix_length_and_dec()
Unlike Item_exists_subselect, LIMIT 1 is set later for
Item_in_subselect, depending on the chosen strategy.
*/
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 7e99e2c3075..f44a5c4d0ce 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -196,7 +196,7 @@ class Item_subselect :public Item_result_field,
const_item_cache= 0;
forced_const= TRUE;
}
- virtual void fix_length_and_dec();
+ virtual bool fix_length_and_dec();
table_map used_tables() const;
table_map not_null_tables() const { return 0; }
bool const_item() const;
@@ -306,7 +306,7 @@ class Item_singlerow_subselect :public Item_subselect
enum Item_result result_type() const;
enum Item_result cmp_type() const;
enum_field_types field_type() const;
- void fix_length_and_dec();
+ bool fix_length_and_dec();
uint cols();
Item* element_index(uint i) { return reinterpret_cast<Item*>(row[i]); }
@@ -403,7 +403,7 @@ class Item_exists_subselect :public Item_subselect
my_decimal *val_decimal(my_decimal *);
bool val_bool();
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
void print(String *str, enum_query_type query_type);
bool select_transformer(JOIN *join);
void top_level_item() { abort_on_null=1; }
@@ -626,7 +626,7 @@ class Item_in_subselect :public Item_exists_subselect
void print(String *str, enum_query_type query_type);
enum precedence precedence() const { return CMP_PRECEDENCE; }
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
bool const_item() const
{
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 94569aa66c9..9da0d9acce5 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -1131,9 +1131,8 @@ Item_sum_num::fix_fields(THD *thd, Item **ref)
result_field=0;
max_length=float_length(decimals);
null_value=1;
- fix_length_and_dec();
-
- if (check_sum_func(thd, ref))
+ if (fix_length_and_dec() ||
+ check_sum_func(thd, ref))
return TRUE;
memcpy (orig_args, args, sizeof (Item *) * arg_count);
@@ -1187,9 +1186,8 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
maybe_null= 1;
result_field=0;
null_value=1;
- fix_length_and_dec();
-
- if (check_sum_func(thd, ref))
+ if (fix_length_and_dec() ||
+ check_sum_func(thd, ref))
return TRUE;
orig_args[0]= args[0];
@@ -1327,7 +1325,7 @@ void Item_sum_sum::clear()
}
-void Item_sum_sum::fix_length_and_dec()
+bool Item_sum_sum::fix_length_and_dec()
{
DBUG_ENTER("Item_sum_sum::fix_length_and_dec");
maybe_null=null_value=1;
@@ -1362,7 +1360,7 @@ void Item_sum_sum::fix_length_and_dec()
"--ILLEGAL!!!--"),
max_length,
(int)decimals));
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
@@ -1662,9 +1660,10 @@ void Item_sum_count::cleanup()
/*
Avgerage
*/
-void Item_sum_avg::fix_length_and_dec()
+bool Item_sum_avg::fix_length_and_dec()
{
- Item_sum_sum::fix_length_and_dec();
+ if (Item_sum_sum::fix_length_and_dec())
+ return TRUE;
maybe_null=null_value=1;
prec_increment= current_thd->variables.div_precincrement;
if (Item_sum_avg::result_type() == DECIMAL_RESULT)
@@ -1684,6 +1683,7 @@ void Item_sum_avg::fix_length_and_dec()
FLOATING_POINT_DECIMALS);
max_length= MY_MIN(args[0]->max_length + prec_increment, float_length(decimals));
}
+ return FALSE;
}
@@ -1882,7 +1882,7 @@ Item_sum_variance::Item_sum_variance(THD *thd, Item_sum_variance *item):
}
-void Item_sum_variance::fix_length_and_dec()
+bool Item_sum_variance::fix_length_and_dec()
{
DBUG_ENTER("Item_sum_variance::fix_length_and_dec");
maybe_null= null_value= 1;
@@ -1917,7 +1917,7 @@ void Item_sum_variance::fix_length_and_dec()
DBUG_ASSERT(0);
}
DBUG_PRINT("info", ("Type: REAL_RESULT (%d, %d)", max_length, (int)decimals));
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
@@ -2987,13 +2987,13 @@ my_decimal *Item_sum_udf_int::val_decimal(my_decimal *dec)
/** Default max_length is max argument length. */
-void Item_sum_udf_str::fix_length_and_dec()
+bool Item_sum_udf_str::fix_length_and_dec()
{
DBUG_ENTER("Item_sum_udf_str::fix_length_and_dec");
max_length=0;
for (uint i = 0; i < arg_count; i++)
set_if_bigger(max_length,args[i]->max_length);
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
diff --git a/sql/item_sum.h b/sql/item_sum.h
index 5c446e5779d..5c8ff520259 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -457,7 +457,8 @@ class Item_sum :public Item_func_or_sum
*/
virtual void update_field()=0;
virtual bool keep_field_type(void) const { return 0; }
- virtual void fix_length_and_dec() { maybe_null=1; null_value=1; }
+ virtual bool fix_length_and_dec()
+ { maybe_null=1; null_value=1; return FALSE; }
virtual Item *result_item(THD *thd, Field *field);
void update_used_tables ();
@@ -752,8 +753,8 @@ class Item_sum_int :public Item_sum_num
my_decimal *val_decimal(my_decimal *);
enum Item_result result_type () const { return INT_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
- void fix_length_and_dec()
- { decimals=0; max_length=21; maybe_null=null_value=0; }
+ bool fix_length_and_dec()
+ { decimals=0; max_length=21; maybe_null=null_value=0; return FALSE; }
};
@@ -764,7 +765,7 @@ class Item_sum_sum :public Item_sum_num,
double sum;
my_decimal dec_buffs[2];
uint curr_dec_buff;
- void fix_length_and_dec();
+ bool fix_length_and_dec();
public:
Item_sum_sum(THD *thd, Item *item_par, bool distinct):
@@ -888,7 +889,7 @@ class Item_sum_avg :public Item_sum_sum
:Item_sum_sum(thd, item), count(item->count),
prec_increment(item->prec_increment) {}
- void fix_length_and_dec();
+ bool fix_length_and_dec();
enum Sumfunctype sum_func () const
{
return has_with_distinct() ? AVG_DISTINCT_FUNC : AVG_FUNC;
@@ -948,7 +949,7 @@ But, this falls prey to catastrophic cancellation. Instead, use the recurrence
class Item_sum_variance : public Item_sum_num
{
- void fix_length_and_dec();
+ bool fix_length_and_dec();
public:
double recurrence_m, recurrence_s; /* Used in recurrence relation. */
@@ -1110,8 +1111,11 @@ class Item_sum_bit :public Item_sum_int
longlong val_int();
void reset_field();
void update_field();
- void fix_length_and_dec()
- { decimals= 0; max_length=21; unsigned_flag= 1; maybe_null= null_value= 0; }
+ bool fix_length_and_dec()
+ {
+ decimals= 0; max_length=21; unsigned_flag= 1; maybe_null= null_value= 0;
+ return FALSE;
+ }
void cleanup()
{
bits= reset_bits;
@@ -1401,7 +1405,7 @@ class Item_sum_udf_float :public Item_udf_sum
enum Item_result result_type () const { return REAL_RESULT; }
enum Item_result cmp_type () const { return REAL_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
- void fix_length_and_dec() { fix_num_length_and_dec(); }
+ bool fix_length_and_dec() { fix_num_length_and_dec(); return FALSE; }
Item *copy_or_same(THD* thd);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_sum_udf_float>(thd, mem_root, this); }
@@ -1424,7 +1428,7 @@ class Item_sum_udf_int :public Item_udf_sum
my_decimal *val_decimal(my_decimal *);
enum Item_result result_type () const { return INT_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
- void fix_length_and_dec() { decimals=0; max_length=21; }
+ bool fix_length_and_dec() { decimals=0; max_length=21; return FALSE; }
Item *copy_or_same(THD* thd);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_sum_udf_int>(thd, mem_root, this); }
@@ -1466,7 +1470,7 @@ class Item_sum_udf_str :public Item_udf_sum
my_decimal *val_decimal(my_decimal *dec);
enum Item_result result_type () const { return STRING_RESULT; }
enum_field_types field_type() const { return string_field_type(); }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
Item *copy_or_same(THD* thd);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_sum_udf_str>(thd, mem_root, this); }
@@ -1488,7 +1492,7 @@ class Item_sum_udf_decimal :public Item_udf_sum
my_decimal *val_decimal(my_decimal *);
enum Item_result result_type () const { return DECIMAL_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; }
- void fix_length_and_dec() { fix_num_length_and_dec(); }
+ bool fix_length_and_dec() { fix_num_length_and_dec(); return FALSE; }
Item *copy_or_same(THD* thd);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_sum_udf_decimal>(thd, mem_root, this); }
@@ -1563,7 +1567,7 @@ class Item_sum_udf_str :public Item_sum_num
double val_real() { DBUG_ASSERT(fixed == 1); null_value=1; return 0.0; }
longlong val_int() { DBUG_ASSERT(fixed == 1); null_value=1; return 0; }
enum Item_result result_type () const { return STRING_RESULT; }
- void fix_length_and_dec() { maybe_null=1; max_length=0; }
+ bool fix_length_and_dec() { maybe_null=1; max_length=0; return FALSE; }
enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
void clear() {}
bool add() { return 0; }
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 87c6489189c..bb75ad7c28c 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -953,7 +953,7 @@ longlong Item_func_month::val_int()
}
-void Item_func_monthname::fix_length_and_dec()
+bool Item_func_monthname::fix_length_and_dec()
{
THD* thd= current_thd;
CHARSET_INFO *cs= thd->variables.collation_connection;
@@ -961,7 +961,8 @@ void Item_func_monthname::fix_length_and_dec()
collation.set(cs, DERIVATION_COERCIBLE, locale->repertoire());
decimals=0;
max_length= locale->max_month_name_length * collation.collation->mbmaxlen;
- maybe_null=1;
+ maybe_null=1;
+ return FALSE;
}
@@ -1101,7 +1102,7 @@ longlong Item_func_weekday::val_int()
odbc_type) + MY_TEST(odbc_type);
}
-void Item_func_dayname::fix_length_and_dec()
+bool Item_func_dayname::fix_length_and_dec()
{
THD* thd= current_thd;
CHARSET_INFO *cs= thd->variables.collation_connection;
@@ -1109,7 +1110,8 @@ void Item_func_dayname::fix_length_and_dec()
collation.set(cs, DERIVATION_COERCIBLE, locale->repertoire());
decimals=0;
max_length= locale->max_day_name_length * collation.collation->mbmaxlen;
- maybe_null=1;
+ maybe_null=1;
+ return FALSE;
}
@@ -1476,7 +1478,7 @@ bool get_interval_value(Item *args,interval_type int_type, INTERVAL *interval)
}
-void Item_temporal_func::fix_length_and_dec()
+bool Item_temporal_func::fix_length_and_dec()
{
uint char_length= mysql_temporal_int_part_length(field_type());
/*
@@ -1502,6 +1504,7 @@ void Item_temporal_func::fix_length_and_dec()
DERIVATION_COERCIBLE : DERIVATION_NUMERIC,
MY_REPERTOIRE_ASCII);
fix_char_length(char_length);
+ return FALSE;
}
String *Item_temporal_func::val_str(String *str)
@@ -1873,7 +1876,7 @@ bool Item_func_sec_to_time::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
return 0;
}
-void Item_func_date_format::fix_length_and_dec()
+bool Item_func_date_format::fix_length_and_dec()
{
THD* thd= current_thd;
locale= thd->variables.lc_time_names;
@@ -1904,6 +1907,7 @@ void Item_func_date_format::fix_length_and_dec()
set_if_smaller(max_length,MAX_BLOB_WIDTH);
}
maybe_null=1; // If wrong date
+ return FALSE;
}
@@ -2050,13 +2054,13 @@ String *Item_func_date_format::val_str(String *str)
}
-void Item_func_from_unixtime::fix_length_and_dec()
-{
+bool Item_func_from_unixtime::fix_length_and_dec()
+{
THD *thd= current_thd;
thd->time_zone_used= 1;
tz= thd->variables.time_zone;
decimals= args[0]->decimals;
- Item_temporal_func::fix_length_and_dec();
+ return Item_temporal_func::fix_length_and_dec();
}
@@ -2083,10 +2087,10 @@ bool Item_func_from_unixtime::get_date(MYSQL_TIME *ltime,
}
-void Item_func_convert_tz::fix_length_and_dec()
+bool Item_func_convert_tz::fix_length_and_dec()
{
decimals= args[0]->temporal_precision(MYSQL_TYPE_DATETIME);
- Item_temporal_func::fix_length_and_dec();
+ return Item_temporal_func::fix_length_and_dec();
}
@@ -2135,7 +2139,7 @@ void Item_func_convert_tz::cleanup()
}
-void Item_date_add_interval::fix_length_and_dec()
+bool Item_date_add_interval::fix_length_and_dec()
{
enum_field_types arg0_field_type;
@@ -2190,7 +2194,7 @@ void Item_date_add_interval::fix_length_and_dec()
}
else
decimals= MY_MAX(args[0]->temporal_precision(MYSQL_TYPE_DATETIME), interval_dec);
- Item_temporal_func::fix_length_and_dec();
+ return Item_temporal_func::fix_length_and_dec();
}
@@ -2261,7 +2265,7 @@ void Item_extract::print(String *str, enum_query_type query_type)
str->append(')');
}
-void Item_extract::fix_length_and_dec()
+bool Item_extract::fix_length_and_dec()
{
maybe_null=1; // If wrong date
switch (int_type) {
@@ -2287,6 +2291,7 @@ void Item_extract::fix_length_and_dec()
case INTERVAL_SECOND_MICROSECOND: set_time_length(8); break; // ssffffff
case INTERVAL_LAST: DBUG_ASSERT(0); break; /* purecov: deadcode */
}
+ return FALSE;
}
@@ -2548,7 +2553,7 @@ String *Item_char_typecast::val_str(String *str)
}
-void Item_char_typecast::fix_length_and_dec()
+bool Item_char_typecast::fix_length_and_dec()
{
uint32 char_length;
/*
@@ -2594,6 +2599,7 @@ void Item_char_typecast::fix_length_and_dec()
(cast_cs == &my_charset_bin ? 1 :
args[0]->collation.collation->mbmaxlen));
max_length= char_length * cast_cs->mbmaxlen;
+ return FALSE;
}
@@ -2682,7 +2688,7 @@ bool Item_func_makedate::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
}
-void Item_func_add_time::fix_length_and_dec()
+bool Item_func_add_time::fix_length_and_dec()
{
enum_field_types arg0_field_type;
decimals= MY_MAX(args[0]->decimals, args[1]->decimals);
@@ -2714,7 +2720,7 @@ void Item_func_add_time::fix_length_and_dec()
decimals= MY_MAX(args[0]->temporal_precision(MYSQL_TYPE_TIME),
args[1]->temporal_precision(MYSQL_TYPE_TIME));
}
- Item_temporal_func::fix_length_and_dec();
+ return Item_temporal_func::fix_length_and_dec();
}
/**
@@ -3203,10 +3209,10 @@ get_date_time_result_type(const char *format, uint length)
}
-void Item_func_str_to_date::fix_length_and_dec()
+bool Item_func_str_to_date::fix_length_and_dec()
{
if (agg_arg_charsets(collation, args, 2, MY_COLL_ALLOW_CONV, 1))
- return;
+ return TRUE;
if (collation.collation->mbminlen > 1)
{
#if MYSQL_VERSION_ID > 50500
@@ -3249,7 +3255,7 @@ void Item_func_str_to_date::fix_length_and_dec()
}
}
cached_timestamp_type= mysql_type_to_time_type(field_type());
- Item_temporal_func::fix_length_and_dec();
+ return Item_temporal_func::fix_length_and_dec();
}
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 354a54a5c1a..c983e1a6f8a 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -49,9 +49,10 @@ class Item_func_period_add :public Item_int_func
Item_func_period_add(THD *thd, Item *a, Item *b): Item_int_func(thd, a, b) {}
longlong val_int();
const char *func_name() const { return "period_add"; }
- void fix_length_and_dec()
- {
+ bool fix_length_and_dec()
+ {
max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_period_add>(thd, mem_root, this); }
@@ -64,10 +65,11 @@ class Item_func_period_diff :public Item_int_func
Item_func_period_diff(THD *thd, Item *a, Item *b): Item_int_func(thd, a, b) {}
longlong val_int();
const char *func_name() const { return "period_diff"; }
- void fix_length_and_dec()
- {
+ bool fix_length_and_dec()
+ {
decimals=0;
max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_period_diff>(thd, mem_root, this); }
@@ -80,11 +82,12 @@ class Item_func_to_days :public Item_int_func
Item_func_to_days(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "to_days"; }
- void fix_length_and_dec()
- {
+ bool fix_length_and_dec()
+ {
decimals=0;
max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
- maybe_null=1;
+ maybe_null=1;
+ return FALSE;
}
enum_monotonicity_info get_monotonicity_info() const;
longlong val_int_endpoint(bool left_endp, bool *incl_endp);
@@ -105,11 +108,12 @@ class Item_func_to_seconds :public Item_int_func
Item_func_to_seconds(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "to_seconds"; }
- void fix_length_and_dec()
- {
+ bool fix_length_and_dec()
+ {
decimals=0;
max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null= 1;
+ return FALSE;
}
enum_monotonicity_info get_monotonicity_info() const;
longlong val_int_endpoint(bool left_endp, bool *incl_endp);
@@ -131,11 +135,12 @@ class Item_func_dayofmonth :public Item_int_func
Item_func_dayofmonth(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "dayofmonth"; }
- void fix_length_and_dec()
- {
+ bool fix_length_and_dec()
+ {
decimals=0;
max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
- maybe_null=1;
+ maybe_null=1;
+ return FALSE;
}
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
@@ -167,11 +172,12 @@ class Item_func_month :public Item_func
const char *func_name() const { return "month"; }
enum Item_result result_type () const { return INT_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
- void fix_length_and_dec()
- {
+ bool fix_length_and_dec()
+ {
decimals= 0;
fix_char_length(2);
maybe_null=1;
+ return FALSE;
}
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
@@ -191,7 +197,7 @@ class Item_func_monthname :public Item_str_func
Item_func_monthname(THD *thd, Item *a): Item_str_func(thd, a) {}
const char *func_name() const { return "monthname"; }
String *val_str(String *str);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool check_partition_func_processor(void *int_arg) {return TRUE;}
bool check_valid_arguments_processor(void *int_arg)
{
@@ -212,11 +218,12 @@ class Item_func_dayofyear :public Item_int_func
Item_func_dayofyear(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "dayofyear"; }
- void fix_length_and_dec()
- {
+ bool fix_length_and_dec()
+ {
decimals= 0;
fix_char_length(3);
maybe_null=1;
+ return FALSE;
}
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
@@ -235,11 +242,12 @@ class Item_func_hour :public Item_int_func
Item_func_hour(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "hour"; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
decimals=0;
max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null=1;
+ return FALSE;
}
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
@@ -258,11 +266,12 @@ class Item_func_minute :public Item_int_func
Item_func_minute(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "minute"; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
decimals=0;
max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null=1;
+ return FALSE;
}
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
@@ -281,11 +290,12 @@ class Item_func_quarter :public Item_int_func
Item_func_quarter(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "quarter"; }
- void fix_length_and_dec()
- {
+ bool fix_length_and_dec()
+ {
decimals=0;
max_length=1*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null=1;
+ return FALSE;
}
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
@@ -304,11 +314,12 @@ class Item_func_second :public Item_int_func
Item_func_second(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "second"; }
- void fix_length_and_dec()
- {
+ bool fix_length_and_dec()
+ {
decimals=0;
max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null=1;
+ return FALSE;
}
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
@@ -328,11 +339,12 @@ class Item_func_week :public Item_int_func
Item_func_week(THD *thd, Item *a, Item *b): Item_int_func(thd, a, b) {}
longlong val_int();
const char *func_name() const { return "week"; }
- void fix_length_and_dec()
- {
+ bool fix_length_and_dec()
+ {
decimals=0;
max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null=1;
+ return FALSE;
}
bool check_vcol_func_processor(void *arg)
{
@@ -354,11 +366,12 @@ class Item_func_yearweek :public Item_int_func
Item_func_yearweek(THD *thd, Item *a, Item *b): Item_int_func(thd, a, b) {}
longlong val_int();
const char *func_name() const { return "yearweek"; }
- void fix_length_and_dec()
- {
+ bool fix_length_and_dec()
+ {
decimals=0;
max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null=1;
+ return FALSE;
}
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
@@ -379,11 +392,12 @@ class Item_func_year :public Item_int_func
const char *func_name() const { return "year"; }
enum_monotonicity_info get_monotonicity_info() const;
longlong val_int_endpoint(bool left_endp, bool *incl_endp);
- void fix_length_and_dec()
- {
+ bool fix_length_and_dec()
+ {
decimals=0;
max_length=4*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null=1;
+ return FALSE;
}
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
@@ -416,11 +430,12 @@ class Item_func_weekday :public Item_func
}
enum Item_result result_type () const { return INT_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
decimals= 0;
fix_char_length(1);
maybe_null=1;
+ return FALSE;
}
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
@@ -441,7 +456,7 @@ class Item_func_dayname :public Item_func_weekday
String *val_str(String *str);
enum Item_result result_type () const { return STRING_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool check_partition_func_processor(void *int_arg) {return TRUE;}
bool check_vcol_func_processor(void *arg)
{
@@ -457,7 +472,7 @@ class Item_func_seconds_hybrid: public Item_func_numhybrid
public:
Item_func_seconds_hybrid(THD *thd): Item_func_numhybrid(thd) {}
Item_func_seconds_hybrid(THD *thd, Item *a): Item_func_numhybrid(thd, a) {}
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
if (arg_count)
decimals= args[0]->temporal_precision(arg0_expected_type());
@@ -465,6 +480,7 @@ class Item_func_seconds_hybrid: public Item_func_numhybrid
max_length=17 + (decimals ? decimals + 1 : 0);
maybe_null= true;
set_handler_by_result_type(decimals ? DECIMAL_RESULT : INT_RESULT);
+ return FALSE;
}
double real_op() { DBUG_ASSERT(0); return 0; }
String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
@@ -556,7 +572,7 @@ class Item_temporal_func: public Item_func
save_date_in_field(field);
}
#endif
- void fix_length_and_dec();
+ bool fix_length_and_dec();
};
@@ -834,7 +850,7 @@ class Item_func_date_format :public Item_str_func
String *val_str(String *str);
const char *func_name() const
{ return is_time_format ? "time_format" : "date_format"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
uint format_length(const String *format);
bool eq(const Item *item, bool binary_cmp) const;
bool check_vcol_func_processor(void *arg)
@@ -854,7 +870,7 @@ class Item_func_from_unixtime :public Item_datetimefunc
public:
Item_func_from_unixtime(THD *thd, Item *a): Item_datetimefunc(thd, a) {}
const char *func_name() const { return "from_unixtime"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_from_unixtime>(thd, mem_root, this); }
@@ -889,7 +905,7 @@ class Item_func_convert_tz :public Item_datetimefunc
Item_func_convert_tz(THD *thd, Item *a, Item *b, Item *c):
Item_datetimefunc(thd, a, b, c), from_tz_cached(0), to_tz_cached(0) {}
const char *func_name() const { return "convert_tz"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
void cleanup();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -902,10 +918,10 @@ class Item_func_sec_to_time :public Item_timefunc
public:
Item_func_sec_to_time(THD *thd, Item *item): Item_timefunc(thd, item) {}
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
decimals= MY_MIN(args[0]->decimals, TIME_SECOND_PART_DIGITS);
- Item_timefunc::fix_length_and_dec();
+ return Item_timefunc::fix_length_and_dec();
}
const char *func_name() const { return "sec_to_time"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -923,7 +939,7 @@ class Item_date_add_interval :public Item_temporal_hybrid_func
Item_temporal_hybrid_func(thd, a, b),int_type(type_arg),
date_sub_interval(neg_arg) {}
const char *func_name() const { return "date_add_interval"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
bool eq(const Item *item, bool binary_cmp) const;
void print(String *str, enum_query_type query_type);
@@ -991,7 +1007,7 @@ class Item_extract :public Item_int_func
longlong val_int();
enum Functype functype() const { return EXTRACT_FUNC; }
const char *func_name() const { return "extract"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool eq(const Item *item, bool binary_cmp) const;
void print(String *str, enum_query_type query_type);
bool check_partition_func_processor(void *int_arg) {return FALSE;}
@@ -1063,7 +1079,7 @@ class Item_char_typecast :public Item_str_func
bool eq(const Item *item, bool binary_cmp) const;
const char *func_name() const { return "cast_as_char"; }
String *val_str(String *a);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
void print(String *str, enum_query_type query_type);
bool need_parentheses_in_default() { return true; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -1077,11 +1093,11 @@ class Item_temporal_typecast: public Item_temporal_func
Item_temporal_typecast(THD *thd, Item *a): Item_temporal_func(thd, a) {}
virtual const char *cast_type() const = 0;
void print(String *str, enum_query_type query_type);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
if (decimals == NOT_FIXED_DEC)
decimals= args[0]->temporal_precision(field_type());
- Item_temporal_func::fix_length_and_dec();
+ return Item_temporal_func::fix_length_and_dec();
}
};
@@ -1148,7 +1164,7 @@ class Item_func_add_time :public Item_temporal_hybrid_func
Item_func_add_time(THD *thd, Item *a, Item *b, bool type_arg, bool neg_arg):
Item_temporal_hybrid_func(thd, a, b), is_date(type_arg)
{ sign= neg_arg ? -1 : 1; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
void print(String *str, enum_query_type query_type);
const char *func_name() const { return "add_time"; }
@@ -1161,11 +1177,11 @@ class Item_func_timediff :public Item_timefunc
public:
Item_func_timediff(THD *thd, Item *a, Item *b): Item_timefunc(thd, a, b) {}
const char *func_name() const { return "timediff"; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
decimals= MY_MAX(args[0]->temporal_precision(MYSQL_TYPE_TIME),
args[1]->temporal_precision(MYSQL_TYPE_TIME));
- Item_timefunc::fix_length_and_dec();
+ return Item_timefunc::fix_length_and_dec();
}
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -1178,10 +1194,10 @@ class Item_func_maketime :public Item_timefunc
Item_func_maketime(THD *thd, Item *a, Item *b, Item *c):
Item_timefunc(thd, a, b, c)
{}
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
decimals= MY_MIN(args[2]->decimals, TIME_SECOND_PART_DIGITS);
- Item_timefunc::fix_length_and_dec();
+ return Item_timefunc::fix_length_and_dec();
}
const char *func_name() const { return "maketime"; }
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
@@ -1196,10 +1212,11 @@ class Item_func_microsecond :public Item_int_func
Item_func_microsecond(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "microsecond"; }
- void fix_length_and_dec()
- {
+ bool fix_length_and_dec()
+ {
decimals=0;
maybe_null=1;
+ return FALSE;
}
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
@@ -1220,10 +1237,11 @@ class Item_func_timestamp_diff :public Item_int_func
Item_int_func(thd, a, b), int_type(type_arg) {}
const char *func_name() const { return "timestampdiff"; }
longlong val_int();
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
decimals=0;
maybe_null=1;
+ return FALSE;
}
virtual void print(String *str, enum_query_type query_type);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -1245,11 +1263,12 @@ class Item_func_get_format :public Item_str_ascii_func
{}
String *val_str_ascii(String *str);
const char *func_name() const { return "get_format"; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
maybe_null= 1;
decimals=0;
fix_length_and_charset(17, default_charset());
+ return FALSE;
}
virtual void print(String *str, enum_query_type query_type);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -1271,7 +1290,7 @@ class Item_func_str_to_date :public Item_temporal_hybrid_func
{}
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
const char *func_name() const { return "str_to_date"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_str_to_date>(thd, mem_root, this); }
};
diff --git a/sql/item_windowfunc.cc b/sql/item_windowfunc.cc
index 5fbfb2651af..532a351dec1 100644
--- a/sql/item_windowfunc.cc
+++ b/sql/item_windowfunc.cc
@@ -106,7 +106,8 @@ Item_window_func::fix_fields(THD *thd, Item **ref)
with_window_func= true;
with_sum_func= false;
- fix_length_and_dec();
+ if (fix_length_and_dec())
+ return TRUE;
max_length= window_func()->max_length;
maybe_null= window_func()->maybe_null;
@@ -268,7 +269,8 @@ bool Item_sum_hybrid_simple::fix_fields(THD *thd, Item **ref)
maybe_null= 1;
result_field=0;
null_value=1;
- fix_length_and_dec();
+ if (fix_length_and_dec())
+ return TRUE;
if (check_sum_func(thd, ref))
return TRUE;
diff --git a/sql/item_windowfunc.h b/sql/item_windowfunc.h
index a1ef6854288..e5afb9e1555 100644
--- a/sql/item_windowfunc.h
+++ b/sql/item_windowfunc.h
@@ -516,10 +516,11 @@ class Item_sum_percent_rank: public Item_sum_window_with_row_count
enum Item_result result_type () const { return REAL_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
decimals = 10; // TODO-cvicentiu find out how many decimals the standard
// requires.
+ return FALSE;
}
void setup_window_func(THD *thd, Window_spec *window_spec);
@@ -602,10 +603,11 @@ class Item_sum_cume_dist: public Item_sum_window_with_row_count
enum Item_result result_type () const { return REAL_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
decimals = 10; // TODO-cvicentiu find out how many decimals the standard
// requires.
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -950,9 +952,10 @@ class Item_window_func : public Item_func_or_sum
void split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array,
List<Item> &fields, uint flags);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
decimals = window_func()->decimals;
+ return FALSE;
}
const char* func_name() const { return "WF"; }
diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc
index af62a94afd0..738047fea9b 100644
--- a/sql/item_xmlfunc.cc
+++ b/sql/item_xmlfunc.cc
@@ -222,13 +222,14 @@ class Item_nodeset_func :public Item_str_func
return str;
}
enum Item_result result_type () const { return STRING_RESULT; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
max_length= MAX_BLOB_WIDTH;
collation.collation= pxml->charset();
// To avoid premature evaluation, mark all nodeset functions as non-const.
used_tables_cache= RAND_TABLE_BIT;
const_item_cache= false;
+ return FALSE;
}
const char *func_name() const { return "nodeset"; }
bool check_vcol_func_processor(void *arg)
@@ -456,7 +457,7 @@ class Item_nodeset_context_cache :public Item_nodeset_func
Item_nodeset_func(thd, pxml), string_cache(str_arg) { }
String *val_nodeset(String *res)
{ return string_cache; }
- void fix_length_and_dec() { max_length= MAX_BLOB_WIDTH; }
+ bool fix_length_and_dec() { max_length= MAX_BLOB_WIDTH; return FALSE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_nodeset_context_cache>(thd, mem_root, this); }
};
@@ -470,7 +471,7 @@ class Item_func_xpath_position :public Item_int_func
Item_func_xpath_position(THD *thd, Item *a, String *p):
Item_int_func(thd, a), pxml(p) {}
const char *func_name() const { return "xpath_position"; }
- void fix_length_and_dec() { max_length=10; }
+ bool fix_length_and_dec() { max_length=10; return FALSE; }
longlong val_int()
{
String *flt= args[0]->val_nodeset(&tmp_value);
@@ -491,7 +492,7 @@ class Item_func_xpath_count :public Item_int_func
Item_func_xpath_count(THD *thd, Item *a, String *p):
Item_int_func(thd, a), pxml(p) {}
const char *func_name() const { return "xpath_count"; }
- void fix_length_and_dec() { max_length=10; }
+ bool fix_length_and_dec() { max_length=10; return FALSE; }
longlong val_int()
{
uint predicate_supplied_context_size;
@@ -2709,10 +2710,10 @@ my_xpath_parse(MY_XPATH *xpath, const char *str, const char *strend)
}
-void Item_xml_str_func::fix_length_and_dec()
+bool Item_xml_str_func::fix_length_and_dec()
{
max_length= MAX_BLOB_WIDTH;
- agg_arg_charsets_for_comparison(collation, args, arg_count);
+ return agg_arg_charsets_for_comparison(collation, args, arg_count);
}
diff --git a/sql/item_xmlfunc.h b/sql/item_xmlfunc.h
index d281e076ec8..c46365ee5f0 100644
--- a/sql/item_xmlfunc.h
+++ b/sql/item_xmlfunc.h
@@ -82,7 +82,7 @@ class Item_xml_str_func: public Item_str_func
maybe_null= TRUE;
}
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool const_item() const
{
return const_item_cache && (!nodeset_func || nodeset_func->const_item());
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 30ef26f67e2..3fecddc6661 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -13508,7 +13508,8 @@ COND *Item_func_eq::build_equal_items(THD *thd,
List_iterator_fast<Item_equal> it(cond_equal.current_level);
while ((item_equal= it++))
{
- item_equal->fix_length_and_dec();
+ if (item_equal->fix_length_and_dec())
+ return NULL;
item_equal->update_used_tables();
set_if_bigger(thd->lex->current_select->max_equal_elems,
item_equal->n_field_items());
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 9e7973b745c..f3cb85f01d3 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -4894,7 +4894,13 @@ int create_table_impl(THD *thd,
file= mysql_create_frm_image(thd, orig_db, orig_table_name, create_info,
alter_info, create_table_mode, key_info,
key_count, frm);
- if (!file)
+ /*
+ We have to check thd->is_error() here because it can be set by
+ Item::val* for example, and before it will be cought accidentally by
+ Item_func::fix_fields() of the next call. Now we removed the check
+ from Item_func::fix_fields()
+ */
+ if (!file || thd->is_error())
goto err;
if (rea_create_table(thd, frm, path, db, table_name, create_info,
file, frm_only))
@@ -7377,7 +7383,8 @@ static bool mysql_inplace_alter_table(THD *thd,
*/
if (mysql_rename_table(db_type, alter_ctx->new_db, alter_ctx->tmp_name,
alter_ctx->db, alter_ctx->alias,
- FN_FROM_IS_TMP | NO_HA_TABLE))
+ FN_FROM_IS_TMP | NO_HA_TABLE) ||
+ thd->is_error())
{
// Since changes were done in-place, we can't revert them.
(void) quick_rm_table(thd, db_type,
1
0

[Commits] fa0b71b0e19: MDEV-10259 mysqld crash with certain statement length and...
by sachin 08 May '18
by sachin 08 May '18
08 May '18
revision-id: fa0b71b0e190403ae65e82a58c3af6c086242c96 (mariadb-10.1.32-83-gfa0b71b0e19)
parent(s): de0e5fe17c9e59fc7e16691b00eb32162a2a1409
author: Sachin Setiya
committer: Sachin Setiya
timestamp: 2018-05-08 17:25:35 +0530
message:
MDEV-10259 mysqld crash with certain statement length and...
order with Galera and encrypt-tmp-files=1
Problem:- If trans_cache (IO_CACHE) uses encrypted tmp file
then on next DML server will crash.
Case:-
Lets take a case , we have a table t1 , We try to do 2 inserts in t1
1. A really long insert so that trans_cache has to use temp_file
2. Just a small insert
Analysis:- Actually server crashes from inside of galera
library.
/lib64/libc.so.6(abort+0x175)[0x7fb5ba779dc5]
/usr/lib64/galera/libgalera_smm.so(_ZN6galera3FSMINS_9TrxHandle5State...
mysys/stacktrace.c:247(my_print_stacktrace)[0x7fb5a714940e]
sql/signal_handler.cc:160(handle_fatal_signal)[0x7fb5a715c1bd]
sql/wsrep_hton.cc:257(wsrep_rollback)[0x7fb5bcce923a]
sql/wsrep_hton.cc:268(wsrep_rollback)[0x7fb5bcce9368]
sql/handler.cc:1658(ha_rollback_trans(THD*, bool))[0x7fb5bcd4f41a]
sql/handler.cc:1483(ha_commit_trans(THD*, bool))[0x7fb5bcd4f804]
but actual issue is not in galera but in mariadb, because for 2nd
insert we should never call rollback. We are calling rollback because
log_and_order fails it fails because write_cache fails , It fails
because after reinit_io_cache(trans_cache) , my_b_bytes_in_cache says 0
so we look into tmp_file for data , which is obviously wrong since temp
was used for previous insert and it no longer exist.
wsrep_write_cache_inc() reads the IO_CACHE in a loop, filling it with
my_b_fill() until it returns "0 bytes read". Later
MYSQL_BIN_LOG::write_cache() does the same. wsrep_write_cache_inc()
assumes that reading a zero bytes past EOF leaves the old data in the
cache
Solution:- There is two issue in my_b_encr_read
1st we should never equal read_end to info->buffer. I mean this
does not make sense read_end should always point to end of buffer.
2nd For most of the case(apart from async IO_CACHE) info->pos_in_file
should be equal to info->buffer position wrt to temp file , since
in this case we are not changing info->buffer it should remain
unchanged.
---
.../suite/galera/r/galera_encrypt_tmp_files.result | 35 +++++++++++
.../suite/galera/t/galera_encrypt_tmp_files.cnf | 8 +++
.../suite/galera/t/galera_encrypt_tmp_files.test | 57 ++++++++++++++++++
sql/mf_iocache_encr.cc | 4 +-
unittest/sql/mf_iocache-t.cc | 67 +++++++++++++++++++++-
5 files changed, 168 insertions(+), 3 deletions(-)
diff --git a/mysql-test/suite/galera/r/galera_encrypt_tmp_files.result b/mysql-test/suite/galera/r/galera_encrypt_tmp_files.result
new file mode 100644
index 00000000000..63f6c281af1
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_encrypt_tmp_files.result
@@ -0,0 +1,35 @@
+SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment';
+VARIABLE_VALUE = 'Synced'
+1
+SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+VARIABLE_VALUE = 2
+1
+CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) Engine=InnoDB;
+INSERT INTO t1 VALUES (1);
+SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment';
+VARIABLE_VALUE = 'Synced'
+1
+SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+VARIABLE_VALUE = 2
+1
+SELECT COUNT(*) = 1 FROM t1;
+COUNT(*) = 1
+1
+DROP TABLE t1;
+CREATE TABLE `t1` (
+`col1` int(11) NOT NULL,
+`col2` varchar(64) NOT NULL DEFAULT '',
+`col3` varchar(32) NOT NULL DEFAULT '0',
+`col4` varchar(64) NOT NULL DEFAULT '',
+`col5` tinyint(4) NOT NULL DEFAULT '0',
+`col6` int(11) NOT NULL DEFAULT '0',
+`col7` varchar(64) NOT NULL DEFAULT '',
+`col8` tinyint(4) NOT NULL DEFAULT '0',
+`col9` tinyint(4) NOT NULL DEFAULT '0',
+`col10` text NOT NULL,
+`col11` varchar(255) NOT NULL DEFAULT '',
+`col12` tinyint(4) NOT NULL DEFAULT '1'
+) ;
+create table t2 (test int);
+insert into t2 values (1);
+drop table t1,t2;
diff --git a/mysql-test/suite/galera/t/galera_encrypt_tmp_files.cnf b/mysql-test/suite/galera/t/galera_encrypt_tmp_files.cnf
new file mode 100644
index 00000000000..0f7f80b7d0b
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_encrypt_tmp_files.cnf
@@ -0,0 +1,8 @@
+!include ../galera_2nodes.cnf
+[mysqld]
+
+encrypt-tmp-files = 1
+plugin-load-add= @ENV.FILE_KEY_MANAGEMENT_SO
+file-key-management
+loose-file-key-management-filename= @ENV.MYSQL_TEST_DIR/std_data/keys.txt
+log-bin
diff --git a/mysql-test/suite/galera/t/galera_encrypt_tmp_files.test b/mysql-test/suite/galera/t/galera_encrypt_tmp_files.test
new file mode 100644
index 00000000000..c42c3dbd98a
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_encrypt_tmp_files.test
@@ -0,0 +1,57 @@
+# This file tests that mariadb cluster should not crash when encrypt_tmp_file
+# is enabled
+
+--source include/galera_cluster.inc
+--source include/have_innodb.inc
+
+SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment';
+SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+
+CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) Engine=InnoDB;
+INSERT INTO t1 VALUES (1);
+
+--connection node_2
+SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment';
+SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+
+SELECT COUNT(*) = 1 FROM t1;
+
+DROP TABLE t1;
+
+--connection node_1
+
+CREATE TABLE `t1` (
+ `col1` int(11) NOT NULL,
+ `col2` varchar(64) NOT NULL DEFAULT '',
+ `col3` varchar(32) NOT NULL DEFAULT '0',
+ `col4` varchar(64) NOT NULL DEFAULT '',
+ `col5` tinyint(4) NOT NULL DEFAULT '0',
+ `col6` int(11) NOT NULL DEFAULT '0',
+ `col7` varchar(64) NOT NULL DEFAULT '',
+ `col8` tinyint(4) NOT NULL DEFAULT '0',
+ `col9` tinyint(4) NOT NULL DEFAULT '0',
+ `col10` text NOT NULL,
+ `col11` varchar(255) NOT NULL DEFAULT '',
+ `col12` tinyint(4) NOT NULL DEFAULT '1'
+) ;
+
+#Although we just need $counter >= 907 for IO_CACHE to use
+#encrypted temp file. Just on safe side I am using $counter
+# = 1100
+--disable_query_log
+--let $counter=1100
+--let $query= (1,'test','test','test',0,0,'-1',0,0,'','',-1)
+while($counter)
+{
+ --let $query= $query ,(1,'test','test','test',0,0,'-1',0,0,'','',-1)
+ --dec $counter
+}
+--let $query= INSERT INTO t1 values $query ;
+--eval $query
+--enable_query_log
+#INSERT INTO `t1` VALUE
+
+create table t2 (test int);
+insert into t2 values (1);
+
+drop table t1,t2;
diff --git a/sql/mf_iocache_encr.cc b/sql/mf_iocache_encr.cc
index 149e6feb605..f26a437a25a 100644
--- a/sql/mf_iocache_encr.cc
+++ b/sql/mf_iocache_encr.cc
@@ -49,8 +49,8 @@ static int my_b_encr_read(IO_CACHE *info, uchar *Buffer, size_t Count)
if (pos_in_file == info->end_of_file)
{
- info->read_pos= info->read_end= info->buffer;
- info->pos_in_file= pos_in_file;
+ /* reading past EOF should not empty the cache */
+ info->read_pos= info->read_end;
info->error= 0;
DBUG_RETURN(MY_TEST(Count));
}
diff --git a/unittest/sql/mf_iocache-t.cc b/unittest/sql/mf_iocache-t.cc
index 31f98562521..d5e2ffb095e 100644
--- a/unittest/sql/mf_iocache-t.cc
+++ b/unittest/sql/mf_iocache-t.cc
@@ -187,10 +187,71 @@ void mdev9044()
close_cached_file(&info);
}
+/* 2 Reads in cache makes second read to fail (only if first read uses temp file) */
+void mdev10259()
+{
+ int res;
+ uchar buf[CACHE_SIZE + 200];
+ memset(buf, FILL, sizeof(buf));
+
+ diag("MDEV-10259- mysqld crash with certain statement length and order with"
+ " Galera and encrypt-tmp-files=1");
+
+ init_io_cache_encryption();
+
+ res= open_cached_file(&info, 0, 0, CACHE_SIZE, 0);
+ ok(res == 0, "open_cached_file" INFO_TAIL);
+
+ res= my_b_write(&info, buf, sizeof(buf));
+ ok(res == 0 && info.pos_in_file == CACHE_SIZE, "large write" INFO_TAIL);
+
+ res= my_b_flush_io_cache(&info, 1);
+ ok(res == 0, "flush" INFO_TAIL);
+
+ res= reinit_io_cache(&info, READ_CACHE, 0, 0, 0);
+ ok(res == 0, "reinit READ_CACHE" INFO_TAIL);
+
+ res= my_b_fill(&info);
+ ok(res == CACHE_SIZE, "fill" INFO_TAIL);
+
+ res= my_b_fill(&info);
+ ok(res == 200, "fill" INFO_TAIL);
+
+ res= my_b_fill(&info);
+ ok(res == 0, "fill" INFO_TAIL);
+
+ res= my_b_fill(&info);
+ ok(res == 0, "fill" INFO_TAIL);
+
+ res= reinit_io_cache(&info, READ_CACHE, 0, 0, 0);
+ ok(res == 0, "reinit WRITE_CACHE" INFO_TAIL);
+
+ res= my_b_fill(&info);
+ ok(res == CACHE_SIZE, "fill" INFO_TAIL);
+
+ res= my_b_fill(&info);
+ ok(res == 200, "fill" INFO_TAIL);
+
+ res= my_b_fill(&info);
+ ok(res == 0, "fill" INFO_TAIL);
+
+ res= my_b_fill(&info);
+ ok(res == 0, "fill" INFO_TAIL);
+
+ res= reinit_io_cache(&info, READ_CACHE, 0, 0, 0);
+ ok(res == 0, "reinit WRITE_CACHE" INFO_TAIL);
+
+ res= my_b_read(&info, buf, sizeof(buf)) || data_bad(buf, sizeof(buf));
+ ok(res == 0 && info.pos_in_file == CACHE_SIZE, "large read" INFO_TAIL);
+
+ close_cached_file(&info);
+
+}
+
int main(int argc __attribute__((unused)),char *argv[])
{
MY_INIT(argv[0]);
- plan(29);
+ plan(44);
/* temp files with and without encryption */
encrypt_tmp_files= 1;
@@ -202,6 +263,10 @@ int main(int argc __attribute__((unused)),char *argv[])
/* regression tests */
mdev9044();
+ encrypt_tmp_files= 1;
+ mdev10259();
+ encrypt_tmp_files= 0;
+
my_end(0);
return exit_status();
}
1
0

[Commits] 9781cfa29c1: MDEV-10259 mysqld crash with certain statement length and...
by sachin 08 May '18
by sachin 08 May '18
08 May '18
revision-id: 9781cfa29c1314663ef1d0063dcd50cb6772039a (mariadb-10.1.32-83-g9781cfa29c1)
parent(s): de0e5fe17c9e59fc7e16691b00eb32162a2a1409
author: Sachin Setiya
committer: Sachin Setiya
timestamp: 2018-05-08 17:15:18 +0530
message:
MDEV-10259 mysqld crash with certain statement length and...
order with Galera and encrypt-tmp-files=1
Problem:- If trans_cache (IO_CACHE) uses encrypted tmp file
then on next DML server will crash.
Case:-
Lets take a case , we have a table t1 , We try to do 2 inserts in t1
1. A really long insert so that trans_cache has to use temp_file
2. Just a small insert
Analysis:- Actually server crashes from inside of galera
library.
/lib64/libc.so.6(abort+0x175)[0x7fb5ba779dc5]
/usr/lib64/galera/libgalera_smm.so(_ZN6galera3FSMINS_9TrxHandle5State...
mysys/stacktrace.c:247(my_print_stacktrace)[0x7fb5a714940e]
sql/signal_handler.cc:160(handle_fatal_signal)[0x7fb5a715c1bd]
sql/wsrep_hton.cc:257(wsrep_rollback)[0x7fb5bcce923a]
sql/wsrep_hton.cc:268(wsrep_rollback)[0x7fb5bcce9368]
sql/handler.cc:1658(ha_rollback_trans(THD*, bool))[0x7fb5bcd4f41a]
sql/handler.cc:1483(ha_commit_trans(THD*, bool))[0x7fb5bcd4f804]
but actual issue is not in galera but in mariadb, because for 2nd
insert we should never call rollback. We are calling rollback because
log_and_order fails it fails because write_cache fails , It fails
because after reinit_io_cache(trans_cache) , my_b_bytes_in_cache says 0
so we look into tmp_file for data , which is obviously wrong since temp
was used for previous insert and it no longer exist.
wsrep_write_cache_inc() reads the IO_CACHE in a loop, filling it with
my_b_fill() until it returns "0 bytes read". Later
MYSQL_BIN_LOG::write_cache() does the same. wsrep_write_cache_inc()
assumes that reading a zero bytes past EOF leaves the old data in the
cache
Solution:- There is two issue in my_b_encr_read
1st we should never equal read_end to info->buffer. I mean this
does not make sense read_end should always point to end of buffer.
2nd For most of the case(apart from async IO_CACHE) info->pos_in_file
should be equal to info->buffer position wrt to temp file , since
in this case we are not changing info->buffer it should remain
unchanged.
---
.../suite/galera/r/galera_encrypt_tmp_files.result | 35 ++++++++++++
.../suite/galera/t/galera_encrypt_tmp_files.cnf | 8 +++
.../suite/galera/t/galera_encrypt_tmp_files.test | 57 +++++++++++++++++++
sql/mf_iocache_encr.cc | 4 +-
unittest/sql/mf_iocache-t.cc | 65 ++++++++++++++++++++++
5 files changed, 167 insertions(+), 2 deletions(-)
diff --git a/mysql-test/suite/galera/r/galera_encrypt_tmp_files.result b/mysql-test/suite/galera/r/galera_encrypt_tmp_files.result
new file mode 100644
index 00000000000..63f6c281af1
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_encrypt_tmp_files.result
@@ -0,0 +1,35 @@
+SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment';
+VARIABLE_VALUE = 'Synced'
+1
+SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+VARIABLE_VALUE = 2
+1
+CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) Engine=InnoDB;
+INSERT INTO t1 VALUES (1);
+SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment';
+VARIABLE_VALUE = 'Synced'
+1
+SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+VARIABLE_VALUE = 2
+1
+SELECT COUNT(*) = 1 FROM t1;
+COUNT(*) = 1
+1
+DROP TABLE t1;
+CREATE TABLE `t1` (
+`col1` int(11) NOT NULL,
+`col2` varchar(64) NOT NULL DEFAULT '',
+`col3` varchar(32) NOT NULL DEFAULT '0',
+`col4` varchar(64) NOT NULL DEFAULT '',
+`col5` tinyint(4) NOT NULL DEFAULT '0',
+`col6` int(11) NOT NULL DEFAULT '0',
+`col7` varchar(64) NOT NULL DEFAULT '',
+`col8` tinyint(4) NOT NULL DEFAULT '0',
+`col9` tinyint(4) NOT NULL DEFAULT '0',
+`col10` text NOT NULL,
+`col11` varchar(255) NOT NULL DEFAULT '',
+`col12` tinyint(4) NOT NULL DEFAULT '1'
+) ;
+create table t2 (test int);
+insert into t2 values (1);
+drop table t1,t2;
diff --git a/mysql-test/suite/galera/t/galera_encrypt_tmp_files.cnf b/mysql-test/suite/galera/t/galera_encrypt_tmp_files.cnf
new file mode 100644
index 00000000000..0f7f80b7d0b
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_encrypt_tmp_files.cnf
@@ -0,0 +1,8 @@
+!include ../galera_2nodes.cnf
+[mysqld]
+
+encrypt-tmp-files = 1
+plugin-load-add= @ENV.FILE_KEY_MANAGEMENT_SO
+file-key-management
+loose-file-key-management-filename= @ENV.MYSQL_TEST_DIR/std_data/keys.txt
+log-bin
diff --git a/mysql-test/suite/galera/t/galera_encrypt_tmp_files.test b/mysql-test/suite/galera/t/galera_encrypt_tmp_files.test
new file mode 100644
index 00000000000..c42c3dbd98a
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_encrypt_tmp_files.test
@@ -0,0 +1,57 @@
+# This file tests that mariadb cluster should not crash when encrypt_tmp_file
+# is enabled
+
+--source include/galera_cluster.inc
+--source include/have_innodb.inc
+
+SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment';
+SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+
+CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) Engine=InnoDB;
+INSERT INTO t1 VALUES (1);
+
+--connection node_2
+SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment';
+SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+
+SELECT COUNT(*) = 1 FROM t1;
+
+DROP TABLE t1;
+
+--connection node_1
+
+CREATE TABLE `t1` (
+ `col1` int(11) NOT NULL,
+ `col2` varchar(64) NOT NULL DEFAULT '',
+ `col3` varchar(32) NOT NULL DEFAULT '0',
+ `col4` varchar(64) NOT NULL DEFAULT '',
+ `col5` tinyint(4) NOT NULL DEFAULT '0',
+ `col6` int(11) NOT NULL DEFAULT '0',
+ `col7` varchar(64) NOT NULL DEFAULT '',
+ `col8` tinyint(4) NOT NULL DEFAULT '0',
+ `col9` tinyint(4) NOT NULL DEFAULT '0',
+ `col10` text NOT NULL,
+ `col11` varchar(255) NOT NULL DEFAULT '',
+ `col12` tinyint(4) NOT NULL DEFAULT '1'
+) ;
+
+#Although we just need $counter >= 907 for IO_CACHE to use
+#encrypted temp file. Just on safe side I am using $counter
+# = 1100
+--disable_query_log
+--let $counter=1100
+--let $query= (1,'test','test','test',0,0,'-1',0,0,'','',-1)
+while($counter)
+{
+ --let $query= $query ,(1,'test','test','test',0,0,'-1',0,0,'','',-1)
+ --dec $counter
+}
+--let $query= INSERT INTO t1 values $query ;
+--eval $query
+--enable_query_log
+#INSERT INTO `t1` VALUE
+
+create table t2 (test int);
+insert into t2 values (1);
+
+drop table t1,t2;
diff --git a/sql/mf_iocache_encr.cc b/sql/mf_iocache_encr.cc
index 149e6feb605..f26a437a25a 100644
--- a/sql/mf_iocache_encr.cc
+++ b/sql/mf_iocache_encr.cc
@@ -49,8 +49,8 @@ static int my_b_encr_read(IO_CACHE *info, uchar *Buffer, size_t Count)
if (pos_in_file == info->end_of_file)
{
- info->read_pos= info->read_end= info->buffer;
- info->pos_in_file= pos_in_file;
+ /* reading past EOF should not empty the cache */
+ info->read_pos= info->read_end;
info->error= 0;
DBUG_RETURN(MY_TEST(Count));
}
diff --git a/unittest/sql/mf_iocache-t.cc b/unittest/sql/mf_iocache-t.cc
index 31f98562521..6cfd4ca3551 100644
--- a/unittest/sql/mf_iocache-t.cc
+++ b/unittest/sql/mf_iocache-t.cc
@@ -187,6 +187,67 @@ void mdev9044()
close_cached_file(&info);
}
+/* 2 Reads in cache makes second read to fail (only if first read uses temp file) */
+void mdev10259()
+{
+ int res;
+ uchar buf[CACHE_SIZE + 200];
+ memset(buf, FILL, sizeof(buf));
+
+ diag("MDEV-10259- mysqld crash with certain statement length and order with"
+ " Galera and encrypt-tmp-files=1");
+
+ init_io_cache_encryption();
+
+ res= open_cached_file(&info, 0, 0, CACHE_SIZE, 0);
+ ok(res == 0, "open_cached_file" INFO_TAIL);
+
+ res= my_b_write(&info, buf, sizeof(buf));
+ ok(res == 0 && info.pos_in_file == CACHE_SIZE, "large write" INFO_TAIL);
+
+ res= my_b_flush_io_cache(&info, 1);
+ ok(res == 0, "flush" INFO_TAIL);
+
+ res= reinit_io_cache(&info, READ_CACHE, 0, 0, 0);
+ ok(res == 0, "reinit READ_CACHE" INFO_TAIL);
+
+ res= my_b_fill(&info);
+ ok(res == CACHE_SIZE, "fill" INFO_TAIL);
+
+ res= my_b_fill(&info);
+ ok(res == 200, "fill" INFO_TAIL);
+
+ res= my_b_fill(&info);
+ ok(res == 0, "fill" INFO_TAIL);
+
+ res= my_b_fill(&info);
+ ok(res == 0, "fill" INFO_TAIL);
+
+ res= reinit_io_cache(&info, READ_CACHE, 0, 0, 0);
+ ok(res == 0, "reinit WRITE_CACHE" INFO_TAIL);
+
+ res= my_b_fill(&info);
+ ok(res == CACHE_SIZE, "fill" INFO_TAIL);
+
+ res= my_b_fill(&info);
+ ok(res == 200, "fill" INFO_TAIL);
+
+ res= my_b_fill(&info);
+ ok(res == 0, "fill" INFO_TAIL);
+
+ res= my_b_fill(&info);
+ ok(res == 0, "fill" INFO_TAIL);
+
+ res= reinit_io_cache(&info, READ_CACHE, 0, 0, 0);
+ ok(res == 0, "reinit WRITE_CACHE" INFO_TAIL);
+
+ res= my_b_read(&info, buf, sizeof(buf)) || data_bad(buf, sizeof(buf));
+ ok(res == 0 && info.pos_in_file == CACHE_SIZE, "large read" INFO_TAIL);
+
+ close_cached_file(&info);
+
+}
+
int main(int argc __attribute__((unused)),char *argv[])
{
MY_INIT(argv[0]);
@@ -202,6 +263,10 @@ int main(int argc __attribute__((unused)),char *argv[])
/* regression tests */
mdev9044();
+ encrypt_tmp_files= 1;
+ mdev10259();
+ encrypt_tmp_files= 0;
+
my_end(0);
return exit_status();
}
1
0

[Commits] eb3e9cd: MDEV-15813 ASAN use-after-poison in hp_hashnr upon HANDLER READ on a versioned HEAP table.
by holyfoot@askmonty.org 08 May '18
by holyfoot@askmonty.org 08 May '18
08 May '18
revision-id: eb3e9cdbe86b5a68c3ec8a9f26165259e4ca7eec (mariadb-10.3.6-125-geb3e9cd)
parent(s): bd09c5ca866e273b6cebbd9a15c51c82bfa3ac9b
committer: Alexey Botchkov
timestamp: 2018-05-08 14:19:55 +0400
message:
MDEV-15813 ASAN use-after-poison in hp_hashnr upon HANDLER READ on a versioned HEAP table.
Returns an error if we try to use a key in a query it declared unable to
handle.
---
mysql-test/suite/heap/heap_hash.result | 19 +++++++++++++++++++
mysql-test/suite/heap/heap_hash.test | 18 ++++++++++++++++++
sql/share/errmsg-utf8.txt | 2 ++
sql/sql_handler.cc | 29 +++++++++++++++++++++++++----
sql/sql_handler.h | 3 ++-
sql/sql_prepare.cc | 1 +
6 files changed, 67 insertions(+), 5 deletions(-)
diff --git a/mysql-test/suite/heap/heap_hash.result b/mysql-test/suite/heap/heap_hash.result
index 55d4358..cba39c1 100644
--- a/mysql-test/suite/heap/heap_hash.result
+++ b/mysql-test/suite/heap/heap_hash.result
@@ -467,3 +467,22 @@ c1
bar2
DROP TABLE t1;
End of 5.5 tests
+#
+# MDEV-15813 ASAN use-after-poison in hp_hashnr upon
+# HANDLER READ on a versioned HEAP table
+#
+CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, CONSTRAINT PRIMARY KEY (a, b), UNIQUE ba(b, a) USING HASH) ENGINE=HEAP;
+INSERT INTO t1 VALUES (1, 10), (2, 20), (3,30), (4,40);
+HANDLER t1 OPEN AS m;
+HANDLER m READ `PRIMARY`= (3,30);
+a b
+3 30
+HANDLER m READ `PRIMARY`> (3,30);
+ERROR HY000: HASH index `PRIMARY` does not support this operation
+HANDLER m READ `ba`= (30,3);
+a b
+3 30
+HANDLER m READ `ba`= (30);
+ERROR HY000: HASH index `ba` does not support this operation
+HANDLER m CLOSE;
+DROP TABLE t1;
diff --git a/mysql-test/suite/heap/heap_hash.test b/mysql-test/suite/heap/heap_hash.test
index 3fe95e1..5a08c6d 100644
--- a/mysql-test/suite/heap/heap_hash.test
+++ b/mysql-test/suite/heap/heap_hash.test
@@ -347,3 +347,21 @@ SELECT * FROM t1 WHERE c1='bar2';
DROP TABLE t1;
--echo End of 5.5 tests
+
+--echo #
+--echo # MDEV-15813 ASAN use-after-poison in hp_hashnr upon
+--echo # HANDLER READ on a versioned HEAP table
+--echo #
+
+CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, CONSTRAINT PRIMARY KEY (a, b), UNIQUE ba(b, a) USING HASH) ENGINE=HEAP;
+INSERT INTO t1 VALUES (1, 10), (2, 20), (3,30), (4,40);
+HANDLER t1 OPEN AS m;
+HANDLER m READ `PRIMARY`= (3,30);
+--error ER_KEY_DOESNT_SUPPORT
+HANDLER m READ `PRIMARY`> (3,30);
+HANDLER m READ `ba`= (30,3);
+--error ER_KEY_DOESNT_SUPPORT
+HANDLER m READ `ba`= (30);
+HANDLER m CLOSE;
+DROP TABLE t1;
+
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index c55ac4f..7446a60 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -7915,3 +7915,5 @@ ER_UPDATED_COLUMN_ONLY_ONCE
eng "The column %`s.%`s cannot be changed more than once in a single UPDATE statement"
ER_EMPTY_ROW_IN_TVC
eng "Row with no elements is not allowed in table value constructor in this context"
+ER_KEY_DOESNT_SUPPORT
+ eng "%s index %`s does not support this operation"
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
index 09883d8..12e4b5a 100644
--- a/sql/sql_handler.cc
+++ b/sql/sql_handler.cc
@@ -618,7 +618,7 @@ static SQL_HANDLER *mysql_ha_find_handler(THD *thd, const LEX_CSTRING *name)
static bool
mysql_ha_fix_cond_and_key(SQL_HANDLER *handler,
enum enum_ha_read_modes mode, const char *keyname,
- List<Item> *key_expr,
+ List<Item> *key_expr, enum ha_rkey_function ha_rkey_mode,
Item *cond, bool in_prepare)
{
THD *thd= handler->thd;
@@ -661,12 +661,30 @@ mysql_ha_fix_cond_and_key(SQL_HANDLER *handler,
key_part_map keypart_map;
uint key_len;
+ if (ha_rkey_mode != HA_READ_KEY_EXACT &&
+ (table->file->index_flags(handler->keyno, 0, TRUE) &
+ (HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE)) == 0)
+ {
+ my_error(ER_KEY_DOESNT_SUPPORT, MYF(0),
+ table->file->index_type(handler->keyno), keyinfo->name);
+ return 1;
+ }
+
if (key_expr->elements > keyinfo->user_defined_key_parts)
{
my_error(ER_TOO_MANY_KEY_PARTS, MYF(0),
keyinfo->user_defined_key_parts);
return 1;
}
+ else if (key_expr->elements < keyinfo->user_defined_key_parts &&
+ (table->file->index_flags(handler->keyno, 0, TRUE) &
+ HA_ONLY_WHOLE_INDEX))
+ {
+ my_error(ER_KEY_DOESNT_SUPPORT, MYF(0),
+ table->file->index_type(handler->keyno), keyinfo->name);
+ return 1;
+ }
+
for (keypart_map= key_len=0 ; (item=it_ke++) ; key_part++)
{
my_bitmap_map *old_map;
@@ -841,7 +859,8 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
goto err0; // mysql_lock_tables() printed error message already
}
- if (mysql_ha_fix_cond_and_key(handler, mode, keyname, key_expr, cond, 0))
+ if (mysql_ha_fix_cond_and_key(handler, mode, keyname, key_expr,
+ ha_rkey_mode, cond, 0))
goto err;
mode= handler->mode;
keyno= handler->keyno;
@@ -1002,14 +1021,16 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
SQL_HANDLER *mysql_ha_read_prepare(THD *thd, TABLE_LIST *tables,
enum enum_ha_read_modes mode,
const char *keyname,
- List<Item> *key_expr, Item *cond)
+ List<Item> *key_expr, enum ha_rkey_function ha_rkey_mode,
+ Item *cond)
{
SQL_HANDLER *handler;
DBUG_ENTER("mysql_ha_read_prepare");
if (!(handler= mysql_ha_find_handler(thd, &tables->alias)))
DBUG_RETURN(0);
tables->table= handler->table; // This is used by fix_fields
- if (mysql_ha_fix_cond_and_key(handler, mode, keyname, key_expr, cond, 1))
+ if (mysql_ha_fix_cond_and_key(handler, mode, keyname, key_expr,
+ ha_rkey_mode, cond, 1))
DBUG_RETURN(0);
DBUG_RETURN(handler);
}
diff --git a/sql/sql_handler.h b/sql/sql_handler.h
index ffefec9..4c16f7e 100644
--- a/sql/sql_handler.h
+++ b/sql/sql_handler.h
@@ -80,5 +80,6 @@ void mysql_ha_rm_temporary_tables(THD *thd);
SQL_HANDLER *mysql_ha_read_prepare(THD *thd, TABLE_LIST *tables,
enum enum_ha_read_modes mode,
const char *keyname,
- List<Item> *key_expr, Item *cond);
+ List<Item> *key_expr, enum ha_rkey_function ha_rkey_mode,
+ Item *cond);
#endif
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index f763613..d6d30f7 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -2204,6 +2204,7 @@ static int mysql_test_handler_read(Prepared_statement *stmt,
if (!(ha_table= mysql_ha_read_prepare(thd, tables, lex->ha_read_mode,
lex->ident.str,
lex->insert_list,
+ lex->ha_rkey_mode,
lex->select_lex.where)))
DBUG_RETURN(1);
1
0